]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Updated files.
authorscipio <scipio>
Mon, 6 Nov 2006 11:56:45 +0000 (11:56 +0000)
committerscipio <scipio>
Mon, 6 Nov 2006 11:56:45 +0000 (11:56 +0000)
319 files changed:
README
apps/BaseStationCC2420/BaseStationC.nc [new file with mode: 0644]
apps/BaseStationCC2420/BaseStationP.nc [new file with mode: 0644]
apps/BaseStationCC2420/CC2420ControlP.nc [new file with mode: 0644]
apps/BaseStationCC2420/Makefile [new file with mode: 0644]
apps/BaseStationCC2420/README.txt [new file with mode: 0644]
apps/MViz/.cvsignore [new file with mode: 0644]
apps/MViz/MViz.h [new file with mode: 0644]
apps/MViz/MVizAppC.nc [new file with mode: 0644]
apps/MViz/MVizC.nc [new file with mode: 0644]
apps/MViz/MVizSensorC.nc [new file with mode: 0644]
apps/MViz/Makefile [new file with mode: 0644]
apps/MViz/README.txt [new file with mode: 0644]
apps/MViz/mote.gif [new file with mode: 0644]
apps/tests/TestAM/README.txt [new file with mode: 0644]
apps/tests/TestArbiter/TestFcfsArbiter/TestFcfsArbiterAppC.nc [new file with mode: 0644]
apps/tests/TestArbiter/TestFcfsArbiter/TestFcfsArbiterC.nc [new file with mode: 0644]
apps/tests/TestArbiter/TestRoundRobinArbiter/TestRoundRobinArbiterAppC.nc [new file with mode: 0644]
apps/tests/TestArbiter/TestRoundRobinArbiter/TestRoundRobinArbiterC.nc [new file with mode: 0644]
apps/tests/TestDissemination/README [new file with mode: 0644]
apps/tests/TestLPL/Makefile [new file with mode: 0644]
apps/tests/TestLPL/README.txt [new file with mode: 0644]
apps/tests/TestLPL/TestLplAppC.nc [new file with mode: 0644]
apps/tests/TestLPL/TestLplC.nc [new file with mode: 0644]
apps/tests/TestPrintf/Makefile [new file with mode: 0644]
apps/tests/TestPrintf/PrintfClient.java [new file with mode: 0644]
apps/tests/TestPrintf/TestPrintfAppC.nc [new file with mode: 0644]
apps/tests/TestPrintf/TestPrintfC.nc [new file with mode: 0644]
apps/tests/TestSharedResource/Makefile [new file with mode: 0644]
apps/tests/TestSharedResource/README.txt [new file with mode: 0644]
apps/tests/TestSharedResource/ResourceOperations.nc [new file with mode: 0644]
apps/tests/TestSharedResource/ResourceP.nc [new file with mode: 0644]
apps/tests/TestSharedResource/SharedResourceC.nc [new file with mode: 0644]
apps/tests/TestSharedResource/SharedResourceImplP.nc [new file with mode: 0644]
apps/tests/TestSharedResource/SharedResourceP.nc [new file with mode: 0644]
apps/tests/TestSharedResource/TestSharedResourceAppC.nc [new file with mode: 0644]
apps/tests/TestSharedResource/TestSharedResourceC.nc [new file with mode: 0644]
apps/tests/TestTrickleTimer/TestTrickle.h [new file with mode: 0644]
apps/tests/eyesIFX/RadioCountToFlash/Makefile [new file with mode: 0644]
apps/tests/eyesIFX/RadioCountToFlash/README.txt [new file with mode: 0644]
apps/tests/eyesIFX/RadioCountToFlash/RadioCountToFlash.h [new file with mode: 0644]
apps/tests/eyesIFX/RadioCountToFlash/RadioCountToFlashAppC.nc [new file with mode: 0644]
apps/tests/eyesIFX/RadioCountToFlash/RadioCountToFlashC.nc [new file with mode: 0644]
apps/tests/eyesIFX/RadioCountToFlash/volumes-at45db.xml [new file with mode: 0644]
apps/tests/storage/Block/volumes-pxa27xp30.xml [new file with mode: 0644]
apps/tests/storage/CircularLog/volumes-pxa27xp30.xml [new file with mode: 0644]
apps/tests/storage/Config/volumes-pxa27xp30.xml [new file with mode: 0644]
apps/tests/storage/Log/volumes-pxa27xp30.xml [new file with mode: 0644]
apps/tutorials/BlinkConfig/BlinkConfigAppC.nc
apps/tutorials/BlinkConfig/BlinkConfigC.nc
apps/tutorials/BlinkConfig/README.txt
doc/html/porting.html [new file with mode: 0644]
doc/html/tutorial/img/arbiter_pm_graph.png [new file with mode: 0644]
doc/html/tutorial/img/mviz.png [new file with mode: 0644]
doc/html/tutorial/img/shared_resource_graph.png [new file with mode: 0644]
doc/html/tutorial/lesson10.html [new file with mode: 0644]
doc/html/tutorial/lesson12.html [new file with mode: 0644]
doc/html/tutorial/lesson13.html [new file with mode: 0644]
doc/html/tutorial/lesson7.html [new file with mode: 0644]
doc/html/tutorial/lesson9.html [new file with mode: 0644]
doc/pdf/tinyos-programming.pdf [new file with mode: 0644]
doc/txt/porting.txt [new file with mode: 0644]
overall-todo.txt [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DDocument.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DLayer.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DLink.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DLinkModel.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DLinkModelListener.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DMote.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DMoteModel.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DMoteModelListener.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DNavigate.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DShape.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DShapeModel.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DShapeModelListener.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/DataModel.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/Makefile [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/MessageInput.java [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/images/tmote_sky.gif [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/images/tmote_sky.jpg [new file with mode: 0644]
support/sdk/java/net/tinyos/mviz/images/tmote_sky.png [new file with mode: 0644]
support/sdk/java/tinyos.jar
tools/tinyos/misc/tos-mviz [new file with mode: 0755]
tools/tinyos/misc/tos-mviz.1 [new file with mode: 0644]
tools/tinyos/misc/tos-storage-pxa27xp30 [new file with mode: 0755]
tools/tinyos/misc/tos-storage-pxa27xp30.1 [new file with mode: 0644]
tools/tinyos/misc/tos-storage-pxa27xp30.in [new file with mode: 0755]
tos/chips/atm128/Atm128Uart0C.nc [new file with mode: 0644]
tos/chips/atm128/Atm128UartP.nc [new file with mode: 0644]
tos/chips/atm128/HplAtm128Uart.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/ByteRadio.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000ActiveMessageC.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000ActiveMessageP.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000Const.h [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000Control.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000ControlP.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000CsmaP.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000CsmaRadioC.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000LowPowerListening.h [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000LowPowerListeningC.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000LowPowerListeningP.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000Msg.h [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000RssiP.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000SendReceiveP.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000Squelch.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CC1000SquelchP.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/CsmaControl.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/HplCC1000.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/HplCC1000Spi.nc [new file with mode: 0644]
tos/chips/cc1000_lpl/LowPowerListening.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/AlarmMultiplexC.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420.h [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420ActiveMessageC.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420ActiveMessageP.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420Cca.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420Config.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420ControlC.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420ControlP.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420CsmaC.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420CsmaP.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420DutyCycle.h [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420DutyCycle.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420DutyCycleC.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420DutyCycleP.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420Fifo.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420LowPowerListening.h [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420LowPowerListeningC.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420LowPowerListeningP.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420LplDummyP.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420Packet.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420PacketC.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420Power.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420Ram.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420Receive.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420ReceiveC.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420ReceiveP.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420Register.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420SpiC.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420SpiImplP.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420SpiP.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420Strobe.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420Transmit.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420TransmitC.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/CC2420TransmitP.nc [new file with mode: 0644]
tos/chips/cc2420_lpl/IEEE802154.h [new file with mode: 0644]
tos/chips/cc2420_lpl/LowPowerListening.nc [new file with mode: 0644]
tos/chips/ds2745/DS2745.h [new file with mode: 0644]
tos/chips/ds2745/HplDS2745.nc [new file with mode: 0644]
tos/chips/ds2745/HplDS2745LogicP.nc [new file with mode: 0644]
tos/chips/msp430/adc12/AdcP.nc [new file with mode: 0644]
tos/chips/msp430/adc12/Msp430Adc12ClientAutoDMAC.nc [new file with mode: 0644]
tos/chips/msp430/adc12/Msp430Adc12ClientAutoDMA_RVGC.nc [new file with mode: 0644]
tos/chips/msp430/adc12/Msp430Adc12ClientAutoRVGC.nc [new file with mode: 0644]
tos/chips/msp430/adc12/Msp430Adc12DMAP.nc [new file with mode: 0644]
tos/chips/msp430/adc12/Msp430Adc12ImplP.nc [new file with mode: 0644]
tos/chips/msp430/adc12/Msp430RefVoltArbiterImplP.nc [new file with mode: 0644]
tos/chips/msp430/adc12/README.txt [new file with mode: 0644]
tos/chips/msp430/timer/Alarm32khz16C.nc [new file with mode: 0644]
tos/chips/msp430/timer/Alarm32khz32C.nc [new file with mode: 0644]
tos/chips/msp430/timer/AlarmMilli16C.nc [new file with mode: 0644]
tos/chips/msp430/timer/AlarmMilli32C.nc [new file with mode: 0644]
tos/chips/msp430/timer/Counter32khz16C.nc [new file with mode: 0644]
tos/chips/msp430/timer/Counter32khz32C.nc [new file with mode: 0644]
tos/chips/msp430/timer/CounterMilli16C.nc [new file with mode: 0644]
tos/chips/msp430/timer/CounterMilli32C.nc [new file with mode: 0644]
tos/chips/msp430/usart/HplMsp430I2C.nc [new file with mode: 0644]
tos/chips/msp430/usart/HplMsp430I2C0C.nc [new file with mode: 0644]
tos/chips/msp430/usart/HplMsp430I2C0P.nc [new file with mode: 0644]
tos/chips/msp430/usart/HplMsp430I2CInterrupts.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430I2C0P.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430I2CC.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430I2CConfigure.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430I2CP.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430Spi1C.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430SpiConfigure.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430SpiDma1P.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430SpiNoDma1P.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430Uart0C.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430Uart0P.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430Uart1P.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430UartConfigure.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430UartControl.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430Usart1C.nc [new file with mode: 0644]
tos/chips/msp430/usart/Msp430UsartShare1P.nc [new file with mode: 0644]
tos/chips/pxa27x/dma/DMA.h [new file with mode: 0644]
tos/chips/pxa27x/dma/HalPXA27xDMAChannel.nc [new file with mode: 0644]
tos/chips/pxa27x/dma/HalPXA27xDMAChannelC.nc [new file with mode: 0644]
tos/chips/pxa27x/dma/HalPXA27xDMAChannelM.nc [new file with mode: 0644]
tos/chips/pxa27x/dma/HplPXA27xDMAInfoC.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/Flash.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/FlashC.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/HalP30C.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/HalP30P.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/HplP30.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/HplP30P.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/P30.h [new file with mode: 0644]
tos/chips/pxa27x/p30/P30BlockC.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/P30BlockP.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/P30ConfigC.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/P30ConfigP.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/P30LogC.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/P30LogCircularP.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/P30LogP.nc [new file with mode: 0644]
tos/chips/pxa27x/p30/Storage_chip.h [new file with mode: 0644]
tos/chips/pxa27x/ssp/HalPXA27xPSPDMAC.nc [new file with mode: 0644]
tos/chips/pxa27x/ssp/HalPXA27xPSPPioC.nc [new file with mode: 0644]
tos/chips/pxa27x/ssp/HalPXA27xSSPDMAC.nc [new file with mode: 0644]
tos/chips/pxa27x/ssp/HalPXA27xSSPPioC.nc [new file with mode: 0644]
tos/chips/pxa27x/ssp/HalPXA27xSpiDMAC.nc [new file with mode: 0644]
tos/chips/pxa27x/ssp/HalPXA27xuWireDMAC.nc [new file with mode: 0644]
tos/chips/pxa27x/ssp/HalPXA27xuWirePioC.nc [new file with mode: 0644]
tos/chips/pxa27x/timer/HalPXA27xSleep.nc [new file with mode: 0644]
tos/chips/pxa27x/timer/HalPXA27xSleepC.nc [new file with mode: 0644]
tos/chips/pxa27x/timer/HalPXA27xSleepM.nc [new file with mode: 0644]
tos/chips/pxa27x/timer/HalPXA27xWatchdog.nc [new file with mode: 0644]
tos/chips/pxa27x/timer/HalPXA27xWatchdogC.nc [new file with mode: 0644]
tos/chips/pxa27x/timer/HalPXA27xWatchdogM.nc [new file with mode: 0644]
tos/chips/pxa27x/timer/HplPXA27xPower.nc [new file with mode: 0644]
tos/chips/pxa27x/timer/HplPXA27xPowerM.nc [new file with mode: 0644]
tos/chips/pxa27x/timer/HplPXA27xRTC.nc [new file with mode: 0644]
tos/chips/pxa27x/timer/HplPXA27xRTCM.nc [new file with mode: 0644]
tos/chips/pxa27x/uart/HalPXA27xSerialCntl.nc [new file with mode: 0644]
tos/chips/pxa27x/uart/HalPXA27xSerialPacket.nc [new file with mode: 0644]
tos/chips/pxa27x/uart/HplPXA27xBTUARTC.nc [new file with mode: 0644]
tos/chips/pxa27x/uart/HplPXA27xFFUARTC.nc [new file with mode: 0644]
tos/chips/pxa27x/uart/HplPXA27xUARTP.nc [new file with mode: 0644]
tos/chips/pxa27x/uart/PXA27X_UARTREG.h [new file with mode: 0644]
tos/chips/pxa27x/uart/pxa27x_serial.h [new file with mode: 0644]
tos/chips/tda5250/HplTda5250DataC.nc [new file with mode: 0644]
tos/chips/tda5250/HplTda5250DataControl.nc [new file with mode: 0644]
tos/interfaces/AdcConfigure.nc [new file with mode: 0644]
tos/interfaces/ResourceQueue.nc [new file with mode: 0644]
tos/interfaces/ResourceRequested.nc [new file with mode: 0644]
tos/interfaces/UartByte.nc [new file with mode: 0644]
tos/interfaces/UartStream.nc [new file with mode: 0644]
tos/lib/byte_radio/PacketAck.h [new file with mode: 0644]
tos/lib/net/CollectionDebug.nc [new file with mode: 0644]
tos/lib/net/CollectionDebugMsg.h [new file with mode: 0644]
tos/lib/net/CollectionId.nc [new file with mode: 0644]
tos/lib/net/CollectionIdP.nc [new file with mode: 0644]
tos/lib/net/CollectionPacket.nc [new file with mode: 0644]
tos/lib/net/NeighborTableEviction.nc [new file with mode: 0644]
tos/lib/net/README [new file with mode: 0644]
tos/lib/net/RootControl.nc [new file with mode: 0644]
tos/lib/net/UARTDebugSenderP.nc [new file with mode: 0644]
tos/lib/net/UnicastNameFreeRouting.nc [new file with mode: 0644]
tos/lib/net/ctp/.cvsignore [new file with mode: 0644]
tos/lib/net/ctp/Collection.h [new file with mode: 0644]
tos/lib/net/ctp/CollectionC.nc [new file with mode: 0644]
tos/lib/net/ctp/CollectionSenderC.nc [new file with mode: 0644]
tos/lib/net/ctp/CollectionSenderP.nc [new file with mode: 0644]
tos/lib/net/ctp/Ctp.h [new file with mode: 0644]
tos/lib/net/ctp/CtpCongestion.nc [new file with mode: 0644]
tos/lib/net/ctp/CtpDebug.nc [new file with mode: 0644]
tos/lib/net/ctp/CtpDebugMsg.h [new file with mode: 0644]
tos/lib/net/ctp/CtpForwardingEngine.h [new file with mode: 0644]
tos/lib/net/ctp/CtpForwardingEngineP.nc [new file with mode: 0644]
tos/lib/net/ctp/CtpInfo.nc [new file with mode: 0644]
tos/lib/net/ctp/CtpP.nc [new file with mode: 0644]
tos/lib/net/ctp/CtpPacket.nc [new file with mode: 0644]
tos/lib/net/ctp/CtpRoutingEngineP.nc [new file with mode: 0644]
tos/lib/net/ctp/CtpRoutingPacket.nc [new file with mode: 0644]
tos/lib/net/ctp/CtpSenderC.nc [new file with mode: 0644]
tos/lib/net/ctp/CtpSenderP.nc [new file with mode: 0644]
tos/lib/net/ctp/LruCtpMsgCacheC.nc [new file with mode: 0644]
tos/lib/net/ctp/LruCtpMsgCacheP.nc [new file with mode: 0644]
tos/lib/net/ctp/TreeRouting.h [new file with mode: 0644]
tos/lib/net/le/LinkEstimator.h [new file with mode: 0644]
tos/lib/net/le/LinkEstimator.nc [new file with mode: 0644]
tos/lib/net/le/LinkEstimatorC.nc [new file with mode: 0644]
tos/lib/net/le/LinkEstimatorDummyP.nc [new file with mode: 0644]
tos/lib/net/le/LinkEstimatorP.nc [new file with mode: 0644]
tos/lib/net/le/LinkSrcPacket.nc [new file with mode: 0644]
tos/lib/printf/PrintfC.nc [new file with mode: 0644]
tos/lib/printf/PrintfFlush.nc [new file with mode: 0644]
tos/lib/printf/PrintfP.nc [new file with mode: 0644]
tos/lib/printf/printf.h [new file with mode: 0644]
tos/platforms/eyesIFX/ActiveMessageFilterC.nc [new file with mode: 0644]
tos/platforms/eyesIFX/byte_radio/Uart4b6bPhyC.nc [new file with mode: 0644]
tos/platforms/eyesIFX/byte_radio/Uart4b6bPhyP.nc [new file with mode: 0644]
tos/platforms/eyesIFX/byte_radio/UartManchPhyC.nc [new file with mode: 0644]
tos/platforms/eyesIFX/byte_radio/UartManchPhyP.nc [new file with mode: 0644]
tos/platforms/eyesIFX/byte_radio/code4b6b.h [new file with mode: 0644]
tos/platforms/eyesIFX/chips/msp430/Msp430Timer32khzMapC.nc [new file with mode: 0644]
tos/platforms/eyesIFX/chips/msp430/Msp430Uart0C.nc [new file with mode: 0644]
tos/platforms/eyesIFX/chips/msp430/Msp430Usart0C.nc [new file with mode: 0644]
tos/platforms/eyesIFX/chips/msp430/Msp430UsartShare0P.nc [new file with mode: 0644]
tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataIOC.nc [new file with mode: 0644]
tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataIOP.nc [new file with mode: 0644]
tos/platforms/eyesIFX/chips/tda5250/Tda5250ASKNFSKFakePinP.nc [new file with mode: 0644]
tos/platforms/eyesIFX/chips/tda5250/tda5250BusResourceSettings.h [new file with mode: 0644]
tos/platforms/eyesIFX/eyesIFXv2/chips/at45db/HplAt45dbC.nc [new file with mode: 0644]
tos/platforms/eyesIFX/eyesIFXv2/chips/at45db/HplAt45dbP.nc [new file with mode: 0644]
tos/platforms/eyesIFX/eyesIFXv2/chips/at45db/HplAt45db_chip.h [new file with mode: 0644]
tos/platforms/eyesIFX/sensors/RssiSensorVccP.nc [new file with mode: 0644]
tos/platforms/intelmote2/BlockStorageC.nc [new file with mode: 0644]
tos/platforms/intelmote2/ConfigStorageC.nc [new file with mode: 0644]
tos/platforms/intelmote2/LogStorageC.nc [new file with mode: 0644]
tos/platforms/intelmote2/chips/ds2745/DS2745InternalC.nc [new file with mode: 0644]
tos/platforms/intelmote2/chips/ds2745/DS2745InternalP.nc [new file with mode: 0644]
tos/platforms/tinynode/DemoSensorNowC.nc [new file with mode: 0644]
tos/platforms/tinynode/DemoSensorStreamC.nc [new file with mode: 0644]
tos/platforms/tinynode/VoltageStreamC.nc [new file with mode: 0644]
tos/platforms/tinynode/chips/at45db/HplAt45dbC.nc [new file with mode: 0644]
tos/platforms/tinynode/chips/at45db/HplAt45dbP.nc [new file with mode: 0644]
tos/platforms/tinynode/chips/at45db/HplAt45db_chip.h [new file with mode: 0644]
tos/system/ArbiterP.nc [new file with mode: 0644]
tos/system/FcfsResourceQueueC.nc [new file with mode: 0644]
tos/system/RoundRobinResourceQueueC.nc [new file with mode: 0644]
tos/system/SimpleArbiterP.nc [new file with mode: 0644]
tos/system/SimpleFcfsArbiterC.nc [new file with mode: 0644]
tos/system/SimpleRoundRobinArbiterC.nc [new file with mode: 0644]
tos/system/SineSensorC.nc [new file with mode: 0644]
tos/system/State.nc [new file with mode: 0644]
tos/system/StateC.nc [new file with mode: 0644]
tos/system/StateImplC.nc [new file with mode: 0644]
tos/system/StateImplP.nc [new file with mode: 0644]
tos/types/Resource.h [new file with mode: 0644]
tos/types/State.h [new file with mode: 0644]

diff --git a/README b/README
index c50cc0e8074998977d9daa25981f5a817d6c99e6..03dbb4bc7df6c491f6bc44995e98d17f39d37235 100644 (file)
--- a/README
+++ b/README
@@ -1,44 +1,46 @@
-This contains the TinyOS 2.0 source code as of\r
-\r
-$Date$\r
-\r
-This tree includes the TinyOS 2.0 documentation in tinyos-2.x/doc; \r
-you can also find the documentation online at:\r
-http://www.tinyos.net/tinyos-2.x/doc/\r
-\r
-The basic directory structure is as follows:\r
-\r
-apps: Sample TinyOS applications.\r
-  tests: Sample TinyOS applications which test a part of the system.\r
-\r
-doc: Documentation\r
-  index.html: Index file to all documentation\r
-  txt: Text files (TEPs)\r
-  html: HTML files (TEPs, installation)\r
-  html/tutorial: Tutorials\r
-\r
-support: Non-nesC code for using TinyOS nodes\r
-  make: TinyOS make system\r
-  sdk: Standard developers kit: serial communication, etc.\r
-    c: C SDK (fully supported, but not exhaustively tested yet)\r
-    java: Java SDK (fully supported, heavily tested and used)\r
-    python: Python SDK (limited, not fully supported)\r
-\r
-tools: TinyOS-specific tools and scripts\r
-  platforms: Platform-specific tools\r
-  release: Scripts and configurations for packaging release RPMs\r
-  tinyos: TinyOS scripts\r
-    java: Native support for TinyOS JNI libraries (serial and env)\r
-    misc: Assorted utility scripts, begininning with tos-\r
-    ncc: The scripts that invoke the nesC compiler: ncc, mig, ncg\r
-    \r
-tos: TinyOS source code (nesC, C)\r
-  chips: Chip-specific code\r
-  interfaces: Core system interfaces\r
-  lib: Extensions and larger common subsystems\r
-  platforms: Platform-specific code\r
-  sensorboards: Sensorboard drivers\r
-  system: Core system components\r
-  types: Core system data types (header files)\r
-\r
-\r
+This contains the TinyOS 2.0 source code as of
+
+$Date$
+
+This tree includes the TinyOS 2.0 documentation in tinyos-2.x/doc; 
+you can also find the documentation online at:
+http://www.tinyos.net/tinyos-2.x/doc/
+
+The basic directory structure is as follows:
+
+apps: Sample TinyOS applications.
+  tests: Sample TinyOS applications which test a part of the system.
+
+doc: Documentation
+  index.html: Index file to all documentation
+  txt: Text files (TEPs)
+  html: HTML files (TEPs, installation)
+  html/tutorial: Tutorials
+
+support: Non-nesC code for using TinyOS nodes
+  make: TinyOS make system
+  sdk: Standard developers kit: serial communication, etc.
+    c: C SDK (fully supported, but not exhaustively tested yet)
+    java: Java SDK (fully supported, heavily tested and used)
+    python: Python SDK (limited, not fully supported)
+
+tools: TinyOS-specific tools and scripts
+  platforms: Platform-specific tools
+  release: Scripts and configurations for packaging release RPMs
+  tinyos: TinyOS scripts
+    java: Native support for TinyOS JNI libraries (serial and env)
+    misc: Assorted utility scripts, begininning with tos-
+    ncc: The scripts that invoke the nesC compiler: ncc, mig, ncg
+    
+tos: TinyOS source code (nesC, C)
+  chips: Chip-specific code
+  interfaces: Core system interfaces
+  lib: Extensions and larger common subsystems
+  platforms: Platform-specific code
+  sensorboards: Sensorboard drivers
+  system: Core system components
+  types: Core system data types (header files)
+
+You can find documentation for the 2.0.0 release online at:
+http://www.tinyos.net/tinyos-2.x/doc/
+
diff --git a/apps/BaseStationCC2420/BaseStationC.nc b/apps/BaseStationCC2420/BaseStationC.nc
new file mode 100644 (file)
index 0000000..016a8b1
--- /dev/null
@@ -0,0 +1,89 @@
+// $Id$
+
+/*                                                                     tab:4
+ * "Copyright (c) 2000-2003 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2003 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+/**
+ * The TinyOS 2.x base station that forwards packets between the UART
+ * and radio.It replaces the GenericBase of TinyOS 1.0 and the
+ * TOSBase of TinyOS 1.1.
+ *
+ * <p>On the serial link, BaseStation sends and receives simple active
+ * messages (not particular radio packets): on the radio link, it
+ * sends radio active messages, whose format depends on the network
+ * stack being used. BaseStation will copy its compiled-in group ID to
+ * messages moving from the serial link to the radio, and will filter
+ * out incoming radio messages that do not contain that group ID.</p>
+ *
+ * <p>BaseStation includes queues in both directions, with a guarantee
+ * that once a message enters a queue, it will eventually leave on the
+ * other interface. The queues allow the BaseStation to handle load
+ * spikes.</p>
+ *
+ * <p>BaseStation acknowledges a message arriving over the serial link
+ * only if that message was successfully enqueued for delivery to the
+ * radio link.</p>
+ *
+ * <p>The LEDS are programmed to toggle as follows:</p>
+ * <ul>
+ * <li><b>RED Toggle:</b>: Message bridged from serial to radio</li>
+ * <li><b>GREEN Toggle:</b> Message bridged from radio to serial</li>
+ * <li><b>YELLOW/BLUE Toggle:</b> Dropped message due to queue overflow in either direction</li>
+ * </ul>
+ *
+ * @author Phil Buonadonna
+ * @author Gilman Tolle
+ * @author David Gay
+ * @author Philip Levis
+ * @date August 10 2005
+ */
+
+configuration BaseStationC {
+}
+implementation {
+  components MainC, BaseStationP, LedsC;
+  components ActiveMessageC as Radio, SerialActiveMessageC as Serial;
+  
+  MainC.Boot <- BaseStationP;
+
+  BaseStationP.RadioControl -> Radio;
+  BaseStationP.SerialControl -> Serial;
+  
+  BaseStationP.UartSend -> Serial;
+  BaseStationP.UartReceive -> Serial;
+  BaseStationP.UartPacket -> Serial;
+  BaseStationP.UartAMPacket -> Serial;
+  
+  BaseStationP.RadioSend -> Radio;
+  BaseStationP.RadioReceive -> Radio.Receive;
+  BaseStationP.RadioPacket -> Radio;
+  BaseStationP.RadioAMPacket -> Radio;
+  
+  BaseStationP.Leds -> LedsC;
+}
diff --git a/apps/BaseStationCC2420/BaseStationP.nc b/apps/BaseStationCC2420/BaseStationP.nc
new file mode 100644 (file)
index 0000000..dd4255a
--- /dev/null
@@ -0,0 +1,278 @@
+// $Id$
+
+/*                                                                     tab:4
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  
+ * All rights reserved.
+` *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2005 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+/*
+ * @author Phil Buonadonna
+ * @author Gilman Tolle
+ * @author David Gay
+ * Revision:   $Id$
+ */
+  
+/* 
+ * BaseStationP bridges packets between a serial channel and the radio.
+ * Messages moving from serial to radio will be tagged with the group
+ * ID compiled into the TOSBase, and messages moving from radio to
+ * serial will be filtered by that same group id.
+ */
+
+#include "AM.h"
+#include "Serial.h"
+
+module BaseStationP {
+  uses {
+    interface Boot;
+    interface SplitControl as SerialControl;
+    interface SplitControl as RadioControl;
+
+    interface AMSend as UartSend[am_id_t id];
+    interface Receive as UartReceive[am_id_t id];
+    interface Packet as UartPacket;
+    interface AMPacket as UartAMPacket;
+    
+    interface AMSend as RadioSend[am_id_t id];
+    interface Receive as RadioReceive[am_id_t id];
+    interface Packet as RadioPacket;
+    interface AMPacket as RadioAMPacket;
+
+    interface Leds;
+  }
+}
+
+implementation
+{
+  enum {
+    UART_QUEUE_LEN = 12,
+    RADIO_QUEUE_LEN = 12,
+  };
+
+  message_t  uartQueueBufs[UART_QUEUE_LEN];
+  message_t  *uartQueue[UART_QUEUE_LEN];
+  uint8_t    uartIn, uartOut;
+  bool       uartBusy, uartFull;
+
+  message_t  radioQueueBufs[RADIO_QUEUE_LEN];
+  message_t  *radioQueue[RADIO_QUEUE_LEN];
+  uint8_t    radioIn, radioOut;
+  bool       radioBusy, radioFull;
+
+  task void uartSendTask();
+  task void radioSendTask();
+
+  void dropBlink() {
+    call Leds.led2Toggle();
+  }
+
+  void failBlink() {
+    call Leds.led2Toggle();
+  }
+
+  event void Boot.booted() {
+    uint8_t i;
+
+    for (i = 0; i < UART_QUEUE_LEN; i++)
+      uartQueue[i] = &uartQueueBufs[i];
+    uartIn = uartOut = 0;
+    uartBusy = FALSE;
+    uartFull = TRUE;
+
+    for (i = 0; i < RADIO_QUEUE_LEN; i++)
+      radioQueue[i] = &radioQueueBufs[i];
+    radioIn = radioOut = 0;
+    radioBusy = FALSE;
+    radioFull = TRUE;
+
+    call RadioControl.start();
+    call SerialControl.start();
+  }
+
+  event void RadioControl.startDone(error_t error) {
+    if (error == SUCCESS) {
+      radioFull = FALSE;
+    }
+  }
+
+  event void SerialControl.startDone(error_t error) {
+    if (error == SUCCESS) {
+      uartFull = FALSE;
+    }
+  }
+
+  event void SerialControl.stopDone(error_t error) {}
+  event void RadioControl.stopDone(error_t error) {}
+
+  uint8_t count = 0;
+  event message_t *RadioReceive.receive[am_id_t id](message_t *msg,
+                                                   void *payload,
+                                                   uint8_t len) {
+    message_t *ret = msg;
+
+    atomic {
+      if (!uartFull)
+       {
+         ret = uartQueue[uartIn];
+         uartQueue[uartIn] = msg;
+
+         uartIn = (uartIn + 1) % UART_QUEUE_LEN;
+       
+         if (uartIn == uartOut)
+           uartFull = TRUE;
+
+         if (!uartBusy)
+           {
+             post uartSendTask();
+             uartBusy = TRUE;
+           }
+       }
+      else
+       dropBlink();
+    }
+    
+    return ret;
+  }
+
+  uint8_t tmpLen;
+  
+  task void uartSendTask() {
+    uint8_t len;
+    am_id_t id;
+    am_addr_t addr;
+    message_t* msg;
+    atomic
+      if (uartIn == uartOut && !uartFull)
+       {
+         uartBusy = FALSE;
+         return;
+       }
+
+    msg = uartQueue[uartOut];
+    tmpLen = len = call RadioPacket.payloadLength(msg);
+    id = call RadioAMPacket.type(msg);
+    addr = call RadioAMPacket.destination(msg);
+
+    if (call UartSend.send[id](addr, uartQueue[uartOut], len) == SUCCESS)
+      call Leds.led1Toggle();
+    else
+      {
+       failBlink();
+       post uartSendTask();
+      }
+  }
+
+  event void UartSend.sendDone[am_id_t id](message_t* msg, error_t error) {
+    if (error != SUCCESS)
+      failBlink();
+    else
+      atomic
+       if (msg == uartQueue[uartOut])
+         {
+           if (++uartOut >= UART_QUEUE_LEN)
+             uartOut = 0;
+           if (uartFull)
+             uartFull = FALSE;
+         }
+    post uartSendTask();
+  }
+
+  event message_t *UartReceive.receive[am_id_t id](message_t *msg,
+                                                  void *payload,
+                                                  uint8_t len) {
+    message_t *ret = msg;
+    bool reflectToken = FALSE;
+
+    atomic
+      if (!radioFull)
+       {
+         reflectToken = TRUE;
+         ret = radioQueue[radioIn];
+         radioQueue[radioIn] = msg;
+         if (++radioIn >= RADIO_QUEUE_LEN)
+           radioIn = 0;
+         if (radioIn == radioOut)
+           radioFull = TRUE;
+
+         if (!radioBusy)
+           {
+             post radioSendTask();
+             radioBusy = TRUE;
+           }
+       }
+      else
+       dropBlink();
+
+    if (reflectToken) {
+      //call UartTokenReceive.ReflectToken(Token);
+    }
+    
+    return ret;
+  }
+
+  task void radioSendTask() {
+    uint8_t len;
+    am_id_t id;
+    am_addr_t addr;
+    message_t* msg;
+    
+    atomic
+      if (radioIn == radioOut && !radioFull)
+       {
+         radioBusy = FALSE;
+         return;
+       }
+
+    msg = radioQueue[radioOut];
+    len = call UartPacket.payloadLength(msg);
+    addr = call UartAMPacket.destination(msg);
+    id = call UartAMPacket.type(msg);
+    if (call RadioSend.send[id](addr, msg, len) == SUCCESS)
+      call Leds.led0Toggle();
+    else
+      {
+       failBlink();
+       post radioSendTask();
+      }
+  }
+
+  event void RadioSend.sendDone[am_id_t id](message_t* msg, error_t error) {
+    if (error != SUCCESS)
+      failBlink();
+    else
+      atomic
+       if (msg == radioQueue[radioOut])
+         {
+           if (++radioOut >= RADIO_QUEUE_LEN)
+             radioOut = 0;
+           if (radioFull)
+             radioFull = FALSE;
+         }
+    
+    post radioSendTask();
+  }
+}  
diff --git a/apps/BaseStationCC2420/CC2420ControlP.nc b/apps/BaseStationCC2420/CC2420ControlP.nc
new file mode 100644 (file)
index 0000000..fc0c0ce
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#include "Timer.h"
+
+module CC2420ControlP {
+
+  provides interface Init;
+  provides interface Resource;
+  provides interface CC2420Config;
+  provides interface CC2420Power;
+
+  uses interface Alarm<T32khz,uint32_t> as StartupTimer;
+  uses interface GeneralIO as CSN;
+  uses interface GeneralIO as RSTN;
+  uses interface GeneralIO as VREN;
+  uses interface GpioInterrupt as InterruptCCA;
+
+  uses interface Resource as SpiResource;
+  uses interface CC2420Ram as PANID;
+  uses interface CC2420Register as FSCTRL;
+  uses interface CC2420Register as IOCFG0;
+  uses interface CC2420Register as IOCFG1;
+  uses interface CC2420Register as MDMCTRL0;
+  uses interface CC2420Register as MDMCTRL1;
+  uses interface CC2420Strobe as SRXON;
+  uses interface CC2420Strobe as SRFOFF;
+  uses interface CC2420Strobe as SXOSCOFF;
+  uses interface CC2420Strobe as SXOSCON;
+  uses interface AMPacket;
+
+  uses interface Resource as SyncResource;
+
+  uses interface Leds;
+
+}
+
+implementation {
+
+  typedef enum {
+    S_VREG_STOPPED,
+    S_VREG_STARTING,
+    S_VREG_STARTED,
+    S_XOSC_STARTING,
+    S_XOSC_STARTED,
+  } cc2420_control_state_t;
+
+  uint8_t channel = CC2420_DEF_CHANNEL;
+  uint8_t txPower = CC2420_DEF_RFPOWER;
+  uint16_t pan = TOS_AM_GROUP;
+  uint16_t shortAddress;
+  bool syncBusy;
+  task void syncDoneTask();
+
+  norace cc2420_control_state_t state = S_VREG_STOPPED;
+
+  command error_t Init.init() {
+    call CSN.makeOutput();
+    call RSTN.makeOutput();
+    call VREN.makeOutput();
+    shortAddress = call AMPacket.address();
+    return SUCCESS;
+  }
+
+  async command error_t Resource.immediateRequest() {
+    error_t error = call SpiResource.immediateRequest();
+    if ( error == SUCCESS )
+      call CSN.clr();
+    return error;
+  }
+
+  async command error_t Resource.request() {
+    return call SpiResource.request();
+  }
+
+  async command uint8_t Resource.isOwner() {
+    return call SpiResource.isOwner();
+  }
+
+  async command error_t Resource.release() {
+    atomic {
+      call CSN.set();
+      return call SpiResource.release();
+    }
+  }
+
+  event void SpiResource.granted() {
+    call CSN.clr();
+    signal Resource.granted();
+  }
+
+  async command error_t CC2420Power.startVReg() {
+    atomic {
+      if ( state != S_VREG_STOPPED )
+       return FAIL;
+      state = S_VREG_STARTING;
+    }
+    call VREN.set();
+    call StartupTimer.start( CC2420_TIME_VREN );
+    return SUCCESS;
+  }
+
+  async event void StartupTimer.fired() {
+    if ( state == S_VREG_STARTING ) {
+      state = S_VREG_STARTED;
+      call RSTN.clr();
+      call RSTN.set();
+      signal CC2420Power.startVRegDone();
+    }
+  }
+
+  async command error_t CC2420Power.stopVReg() {
+    state = S_VREG_STOPPED;
+    call RSTN.clr();
+    call VREN.clr();
+    call RSTN.set();
+    return SUCCESS;
+  }
+
+  async command error_t CC2420Power.startOscillator() {
+    atomic {
+      if ( state != S_VREG_STARTED )
+       return FAIL;
+       
+      state = S_XOSC_STARTING;
+      call IOCFG1.write( CC2420_SFDMUX_XOSC16M_STABLE << 
+                        CC2420_IOCFG1_CCAMUX );
+      call InterruptCCA.enableRisingEdge();
+      call SXOSCON.strobe();
+      call IOCFG0.write( ( 1 << CC2420_IOCFG0_FIFOP_POLARITY ) |
+                        ( 127 << CC2420_IOCFG0_FIFOP_THR ) );
+      call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |
+                        ( ( (channel - 11)*5+357 ) 
+                          << CC2420_FSCTRL_FREQ ) );
+      call MDMCTRL0.write( ( 1 << CC2420_MDMCTRL0_RESERVED_FRAME_MODE ) |
+                          ( 2 << CC2420_MDMCTRL0_CCA_HYST ) |
+                          ( 3 << CC2420_MDMCTRL0_CCA_MOD ) |
+                          ( 1 << CC2420_MDMCTRL0_AUTOCRC ) |
+                          ( 2 << CC2420_MDMCTRL0_PREAMBLE_LENGTH ) );
+    }
+    return SUCCESS;
+  }
+
+  async event void InterruptCCA.fired() {
+    nxle_uint16_t id[ 2 ];
+    state = S_XOSC_STARTED;
+    id[ 0 ] = pan;
+    id[ 1 ] = shortAddress;
+    call InterruptCCA.disable();
+    call IOCFG1.write( 0 );
+    call PANID.write( 0, (uint8_t*)&id, 4 );
+    call CSN.set();
+    call CSN.clr();
+    signal CC2420Power.startOscillatorDone();
+  }
+
+  async command error_t CC2420Power.stopOscillator() {
+    atomic {
+      if ( state != S_XOSC_STARTED )
+       return FAIL;
+      state = S_VREG_STARTED;
+      call SXOSCOFF.strobe();
+    }
+    return SUCCESS;
+  }
+
+  async command error_t CC2420Power.rxOn() {
+    atomic {
+      if ( state != S_XOSC_STARTED )
+       return FAIL;
+      call SRXON.strobe();
+    }
+    return SUCCESS;
+  }
+
+  async command error_t CC2420Power.rfOff() {
+    atomic {  
+      if ( state != S_XOSC_STARTED )
+       return FAIL;
+      call SRFOFF.strobe();
+    }
+    return SUCCESS;
+  }
+
+  command uint8_t CC2420Config.getChannel() {
+    atomic return channel;
+  }
+
+  command void CC2420Config.setChannel( uint8_t chan ) {
+    atomic channel = chan;
+  }
+
+  command uint16_t CC2420Config.getShortAddr() {
+    atomic return shortAddress;
+  }
+
+  command void CC2420Config.setShortAddr( uint16_t addr ) {
+    atomic shortAddress = addr;
+  }
+
+  command uint16_t CC2420Config.getPanAddr() {
+    return pan;
+  }
+
+  command void CC2420Config.setPanAddr( uint16_t p ) {
+    atomic pan = p;
+  }
+
+  command error_t CC2420Config.sync() {
+    atomic {
+      if ( syncBusy )
+        return FAIL;
+      syncBusy = TRUE;
+      if ( state == S_XOSC_STARTED )
+        call SyncResource.request();
+      else
+        post syncDoneTask();
+    }
+    return SUCCESS;
+  }
+
+  event void SyncResource.granted() {
+
+    nxle_uint16_t id[ 2 ];
+    uint8_t chan;
+
+    atomic {
+      chan = channel;
+      id[ 0 ] = pan;
+      id[ 1 ] = shortAddress;
+    }
+
+    call CSN.clr();
+    call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |
+                      ( ( (chan - 11)*5+357 ) << CC2420_FSCTRL_FREQ ) );
+    call PANID.write( 0, (uint8_t*)id, sizeof( id ) );
+    call CSN.set();
+    call SyncResource.release();
+    
+    post syncDoneTask();
+    
+  }
+
+  task void syncDoneTask() {
+    atomic syncBusy = FALSE;
+    signal CC2420Config.syncDone( SUCCESS );
+  }
+
+  default event void CC2420Config.syncDone( error_t error ) {}
+
+}
diff --git a/apps/BaseStationCC2420/Makefile b/apps/BaseStationCC2420/Makefile
new file mode 100644 (file)
index 0000000..3e098f4
--- /dev/null
@@ -0,0 +1,3 @@
+COMPONENT=BaseStationC
+include $(MAKERULES)
+
diff --git a/apps/BaseStationCC2420/README.txt b/apps/BaseStationCC2420/README.txt
new file mode 100644 (file)
index 0000000..3961a14
--- /dev/null
@@ -0,0 +1,40 @@
+README for BaseStationCC2420
+Author/Contact: tinyos-help@millennium.berkeley.edu
+
+Description:
+
+BaseStation is an application that acts as a simple Active Message
+bridge between the serial and radio links. It replaces the GenericBase
+of TinyOS 1.0 and the TOSBase of TinyOS 1.1. This base station
+is for CC2420-based platforms (e.g., micaz, telos).
+
+On the serial link, BaseStation sends and receives simple active
+messages (not particular radio packets): on the radio link, it sends
+radio active messages, whose format depends on the network stack being
+used. BaseStation will copy its compiled-in group ID to messages
+moving from the serial link to the radio, and will filter out incoming
+radio messages that do not contain that group ID.
+
+BaseStation includes queues in both directions, with a guarantee that
+once a message enters a queue, it will eventually leave on the other
+interface. The queues allow the BaseStation to handle load spikes more
+gracefully.
+
+BaseStation acknowledges a message arriving over the serial link only if
+that message was successfully enqueued for delivery to the radio link.
+
+The LEDS are programmed to toggle as follows:
+
+RED Toggle         - Message bridged from serial to radio
+GREEN Toggle       - Message bridged from radio to serial
+YELLOW/BLUE Toggle - Dropped message due to queue overflow 
+                     in either direction
+
+Tools:
+
+tools/java/net/tinyos/sf/SerialForwarder.  
+
+See doc/serialcomm/index.html for more information using these tools.
+
+
+
diff --git a/apps/MViz/.cvsignore b/apps/MViz/.cvsignore
new file mode 100644 (file)
index 0000000..040264a
--- /dev/null
@@ -0,0 +1 @@
+build .*.swp
diff --git a/apps/MViz/MViz.h b/apps/MViz/MViz.h
new file mode 100644 (file)
index 0000000..82b60d2
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2006 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+/**
+ * @author David Gay
+ * @author Kyle Jamieson
+ * @author Phil Levis
+ */
+
+#ifndef MVIZ_H
+#define MVIZ_H
+
+#include "AM.h"
+
+enum {
+  /* Default sampling period. */
+  DEFAULT_INTERVAL = 1024,
+  AM_MVIZ_MSG = 0x93
+};
+
+typedef nx_struct mviz_msg {
+  nx_uint16_t version; /* Version of the interval. */
+  nx_uint16_t interval; /* Samping period. */
+  nx_uint16_t origin; /* Mote id of sending mote. */
+  nx_uint16_t count; /* The readings are samples count * NREADINGS onwards */
+  nx_uint16_t reading;
+  nx_uint16_t etx;
+  nx_uint16_t link_route_value;
+  nx_am_addr_t link_route_addr;
+} mviz_msg_t;
+
+#endif
diff --git a/apps/MViz/MVizAppC.nc b/apps/MViz/MVizAppC.nc
new file mode 100644 (file)
index 0000000..56847e2
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+/**
+ * MViz demo application using the collection layer. 
+ * See README.txt file in this directory and TEP 119: Collection.
+ *
+ * @author David Gay
+ * @author Kyle Jamieson
+ * @author Philip Levis
+ */
+
+#include <MViz.h>
+
+configuration MVizAppC { }
+implementation {
+  components MainC, MVizC, LedsC, new TimerMilliC(), 
+    new MVizSensorC() as Sensor, RandomC;
+
+  //MainC.SoftwareInit -> Sensor;
+  
+  MVizC.Boot -> MainC;
+  MVizC.Timer -> TimerMilliC;
+  MVizC.Read -> Sensor;
+  MVizC.Leds -> LedsC;
+  MVizC.Random -> RandomC;
+  //
+  // Communication components.  These are documented in TEP 113:
+  // Serial Communication, and TEP 119: Collection.
+  //
+  components CollectionC as Collector,  // Collection layer
+    ActiveMessageC,                         // AM layer
+    new CollectionSenderC(AM_MVIZ_MSG), // Sends multihop RF
+    SerialActiveMessageC,                   // Serial messaging
+    new SerialAMSenderC(AM_MVIZ_MSG);   // Sends to the serial port
+
+  components CtpP as Ctp;
+  
+  MVizC.RadioControl -> ActiveMessageC;
+  MVizC.SerialControl -> SerialActiveMessageC;
+  MVizC.RoutingControl -> Collector;
+
+  MVizC.Send -> CollectionSenderC;
+  MVizC.SerialSend -> SerialAMSenderC.AMSend;
+  MVizC.Snoop -> Collector.Snoop[AM_MVIZ_MSG];
+  MVizC.Receive -> Collector.Receive[AM_MVIZ_MSG];
+  MVizC.RootControl -> Collector;
+  MVizC.CtpInfo -> Ctp;
+  MVizC.LinkEstimator -> Ctp;
+
+}
diff --git a/apps/MViz/MVizC.nc b/apps/MViz/MVizC.nc
new file mode 100644 (file)
index 0000000..6719d8f
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2006 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+/**
+ * MViz demo application using the collection layer. 
+ * See README.txt file in this directory and TEP 119: Collection.
+ *
+ * @author David Gay
+ * @author Kyle Jamieson
+ * @author Philip Levis
+ */
+
+#include "MViz.h"
+
+module MVizC {
+  uses {
+    // Interfaces for initialization:
+    interface Boot;
+    interface SplitControl as RadioControl;
+    interface SplitControl as SerialControl;
+    interface StdControl as RoutingControl;
+    
+    // Interfaces for communication, multihop and serial:
+    interface Send;
+    interface Receive as Snoop;
+    interface Receive;
+    interface AMSend as SerialSend;
+    interface CollectionPacket;
+    interface RootControl;
+
+    // Miscalleny:
+    interface Timer<TMilli>;
+    interface Read<uint16_t>;
+    interface Leds;
+    interface CtpInfo;
+    interface LinkEstimator;
+    interface Random;
+  }
+}
+
+implementation {
+  task void uartSendTask();
+  static void startTimer();
+  static void fatal_problem();
+  static void report_problem();
+  static void report_sent();
+  static void report_received();
+
+  uint8_t uartlen;
+  message_t sendbuf;
+  message_t uartbuf;
+  bool sendbusy=FALSE, uartbusy=FALSE;
+
+  /* Current local state - interval, version and accumulated readings */
+  mviz_msg_t local;
+
+  uint8_t reading; /* 0 to NREADINGS */
+
+  /* When we head an Oscilloscope message, we check it's sample count. If
+     it's ahead of ours, we "jump" forwards (set our count to the received
+     count). However, we must then suppress our next count increment. This
+     is a very simple form of "time" synchronization (for an abstract
+     notion of time). */
+  bool suppress_count_change;
+
+  // 
+  // On bootup, initialize radio and serial communications, and our
+  // own state variables.
+  //
+  event void Boot.booted() {
+    local.interval = DEFAULT_INTERVAL;
+    local.origin = TOS_NODE_ID;
+
+    // Beginning our initialization phases:
+    if (call RadioControl.start() != SUCCESS)
+      fatal_problem();
+
+    if (call RoutingControl.start() != SUCCESS)
+      fatal_problem();
+  }
+
+  event void RadioControl.startDone(error_t error) {
+    if (error != SUCCESS)
+      fatal_problem();
+
+    if (sizeof(local) > call Send.maxPayloadLength())
+      fatal_problem();
+
+    if (call SerialControl.start() != SUCCESS)
+      fatal_problem();
+  }
+
+  event void SerialControl.startDone(error_t error) {
+    if (error != SUCCESS)
+      fatal_problem();
+
+    // This is how to set yourself as a root to the collection layer:
+    if (local.origin % 500 == 0)
+      call RootControl.setRoot();
+
+    startTimer();
+  }
+
+  static void startTimer() {
+    call Timer.startPeriodic(local.interval);
+    reading = 0;
+  }
+
+  event void RadioControl.stopDone(error_t error) { }
+  event void SerialControl.stopDone(error_t error) { }
+
+  //
+  // Only the root will receive messages from this interface; its job
+  // is to forward them to the serial uart for processing on the pc
+  // connected to the sensor network.
+  //
+  event message_t*
+  Receive.receive(message_t* msg, void *payload, uint8_t len) {
+    if (uartbusy == FALSE) {
+      mviz_msg_t* in = (mviz_msg_t*)payload;
+      mviz_msg_t* out = (mviz_msg_t*)call SerialSend.getPayload(&uartbuf);
+      if (len != sizeof(mviz_msg_t)) {
+       return msg;
+      }
+      else {
+       memcpy(out, in, sizeof(mviz_msg_t));
+      }
+      uartbusy = TRUE;
+      uartlen = sizeof(mviz_msg_t);
+      post uartSendTask();
+    }
+
+    return msg;
+  }
+
+  task void uartSendTask() {
+    if (call SerialSend.send(0xffff, &uartbuf, uartlen) != SUCCESS) {
+      uartbusy = FALSE;
+    }
+  }
+  //
+  // Overhearing other traffic in the network.
+  //
+  event message_t* 
+  Snoop.receive(message_t* msg, void* payload, uint8_t len) {
+    mviz_msg_t *omsg = payload;
+
+    report_received();
+
+    // If we receive a newer version, update our interval. 
+    if (omsg->version > local.version) {
+      local.version = omsg->version;
+      local.interval = omsg->interval;
+      startTimer();
+    }
+
+    // If we hear from a future count, jump ahead but suppress our own
+    // change.
+    if (omsg->count > local.count) {
+      local.count = omsg->count;
+      suppress_count_change = TRUE;
+    }
+
+    return msg;
+  }
+
+  /* At each sample period:
+     - if local sample buffer is full, send accumulated samples
+     - read next sample
+  */
+  event void Timer.fired() {
+    if (!sendbusy) {
+      mviz_msg_t *o = (mviz_msg_t *)call Send.getPayload(&sendbuf);
+      memcpy(o, &local, sizeof(local));
+      if (call Send.send(&sendbuf, sizeof(local)) == SUCCESS)
+       sendbusy = TRUE;
+      else
+       report_problem();
+    }
+    
+    reading = 0;
+    /* Part 2 of cheap "time sync": increment our count if we didn't
+       jump ahead. */
+    if (!suppress_count_change)
+      local.count++;
+    suppress_count_change = FALSE;
+    call Timer.stop();
+    call Timer.startPeriodic(local.interval);    
+    if (call Read.read() != SUCCESS)
+      fatal_problem();
+  }
+
+  event void Send.sendDone(message_t* msg, error_t error) {
+    if (error == SUCCESS)
+      report_sent();
+    else
+      report_problem();
+
+    sendbusy = FALSE;
+  }
+
+  event void Read.readDone(error_t result, uint16_t data) {
+    uint16_t val;
+    if (result != SUCCESS) {
+      data = 0xffff;
+      report_problem();
+    }
+    local.reading = data;
+    call CtpInfo.getEtx(&val);
+    local.link_route_value = val;
+    call CtpInfo.getParent(&val);
+    local.link_route_addr = val;
+    local.link_route_value = call LinkEstimator.getLinkQuality(local.link_route_addr);
+  }
+  event void LinkEstimator.evicted(am_addr_t addr){}
+  
+  event void SerialSend.sendDone(message_t *msg, error_t error) {
+    uartbusy = FALSE;
+  }
+
+  // Use LEDs to report various status issues.
+  static void fatal_problem() { 
+    call Leds.led0On(); 
+    call Leds.led1On();
+    call Leds.led2On();
+    call Timer.stop();
+  }
+
+  static void report_problem() { call Leds.led0Toggle(); }
+  static void report_sent() { call Leds.led1Toggle(); }
+  static void report_received() { call Leds.led2Toggle(); }
+}
diff --git a/apps/MViz/MVizSensorC.nc b/apps/MViz/MVizSensorC.nc
new file mode 100644 (file)
index 0000000..10e96c3
--- /dev/null
@@ -0,0 +1,16 @@
+/**
+ * The default sensor for MViz is a simple sine wave.
+ *
+ * @author Philip Levis
+ */
+
+generic configuration MVizSensorC()
+{
+  provides interface Read<uint16_t>;
+}
+implementation
+{
+  components new SineSensorC() as DemoChannel;
+
+  Read = DemoChannel;
+}
diff --git a/apps/MViz/Makefile b/apps/MViz/Makefile
new file mode 100644 (file)
index 0000000..9756b23
--- /dev/null
@@ -0,0 +1,11 @@
+COMPONENT=MVizAppC
+CFLAGS += -I$(TOSDIR)/lib/net/ -I$(TOSDIR)/lib/net/ctp -I$(TOSDIR)/lib/net/le -I.
+BUILD_EXTRA_DEPS = MVizMsg.class
+
+MVizMsg.java: MViz.h
+       mig -target=null -java-classname=MVizMsg java MViz.h mviz_msg -o $@
+
+MVizMsg.class: MVizMsg.java
+       javac MVizMsg.java
+
+include $(MAKERULES)
diff --git a/apps/MViz/README.txt b/apps/MViz/README.txt
new file mode 100644 (file)
index 0000000..a9df879
--- /dev/null
@@ -0,0 +1,41 @@
+README for MViz
+Author/Contact: tinyos-help@millennium.berkeley.edu
+
+Description:
+
+MViz is a sample application for the MViz network visualization tool. The MViz
+application is a multihop collection network. Nodes whose (ID % 500) == 0 are
+collection roots. The application samples a platform's DemoSensorC and routes
+those values to the collection roots. The roots send the packets to the serial
+port, which the MViz java application then visualizes.
+
+To run this application, install the TinyOS application on several nodes, one
+of whom is a root. Then run the tos-mviz script with MVizMsg as a parameter:
+
+tos-mviz [-comm source] MVizMsg
+
+This will cause the MViz java tool to parse the fields of MVizMsg and make
+them displayable. As nodes send readings to the base station, they will be
+displayed in the GUI. 
+
+By default, the TinyOS program uses an artificial demonstration sensor that
+just generates a sine wave (MVizSensorC). To change the sensor that
+the MViz application uses, change the wiring in MVizAppC to your sensor
+of choice.
+
+Tools:
+
+The Java application lives in support/sdk/java/net/tinyos/mviz. It is
+invoked by the tos-mviz script, which is part of a TinyOS tools  distribution.
+The top-level Java class is net.tinyos.mviz.DDocument. To display a mote image,
+the tool looks for a mote.gif in either the local directory (default) or a 
+directory specified with the -dir parameter.
+
+Known bugs/limitations:
+
+Under Ubuntu Linux, the MViz Java visualization can be painfully slow.
+
+Notes:
+
+MViz configures a mote whose TOS_NODE_ID modulo 500 is zero to be a
+collection root. 
diff --git a/apps/MViz/mote.gif b/apps/MViz/mote.gif
new file mode 100644 (file)
index 0000000..bfb252d
Binary files /dev/null and b/apps/MViz/mote.gif differ
diff --git a/apps/tests/TestAM/README.txt b/apps/tests/TestAM/README.txt
new file mode 100644 (file)
index 0000000..c3248eb
--- /dev/null
@@ -0,0 +1,19 @@
+README for TestAM
+Author/Contact: tinyos-help@millennium.berkeley.edu
+
+Description:
+
+TestAM sends active message broadcasts at 1Hz and blinks LED 0 whenever 
+it has sucessfully sent a broadcast. Whenever it receives one of these 
+broadcasts from another node, it blinks LED 1.  It uses the radio HIL 
+component ActiveMessageC, and its packets are AM type 240.  This application 
+is useful for testing AM communication and the ActiveMessageC component.
+
+Tools:
+
+None.
+
+Known bugs/limitations:
+
+None.
+
diff --git a/apps/tests/TestArbiter/TestFcfsArbiter/TestFcfsArbiterAppC.nc b/apps/tests/TestArbiter/TestFcfsArbiter/TestFcfsArbiterAppC.nc
new file mode 100644 (file)
index 0000000..aa89764
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2004, Technische Universitat Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/**
+ * Please refer to TEP 108 for more information about the components
+ * this application is used to test.<br><br>
+ *
+ * This application is used to test the functionality of the
+ * FcfsArbiter component developed using the Resource
+ * interface.  Three Resource users are created and all three request
+ * control of the resource before any one of them is granted it.
+ * Once the first user is granted control of the resource, a timer
+ * is set to allow this user to have control of it for a specific
+ * amount of time.  Once this timer expires, the resource is released
+ * and then immediately requested again.  Upon releasing the resource
+ * control will be granted to the next user that has
+ * requested it in FCFS order.  Initial requests are made
+ * by the three resource users in the following order<br>
+ * <li> Resource 0
+ * <li> Resource 2
+ * <li> Resource 1
+ * <br>
+ * It is expected then that using a first-come-first-serve policy, control of the
+ * resource will be granted in the order of 0,2,1 and the Leds
+ * corresponding to each resource will flash whenever this occurs.<br>
+ * <li> Led 0 -> Resource 0
+ * <li> Led 1 -> Resource 1
+ * <li> Led 2 -> Resource 2
+ * <br>
+ *
+ * @author Kevin Klues <klues@tkn.tu-berlin.de>
+ * @version  $Revision$
+ * @date $Date$
+ */
+#define TEST_ARBITER_RESOURCE   "Test.Arbiter.Resource"
+configuration TestFcfsArbiterAppC{
+}
+implementation {
+  components MainC, TestFcfsArbiterC as App,LedsC,
+     new TimerMilliC() as Timer0,
+     new TimerMilliC() as Timer1,
+     new TimerMilliC() as Timer2,
+     new FcfsArbiterC(TEST_ARBITER_RESOURCE) as Arbiter;
+
+  enum {
+    RESOURCE0_ID = unique(TEST_ARBITER_RESOURCE),
+    RESOURCE1_ID = unique(TEST_ARBITER_RESOURCE),
+    RESOURCE2_ID = unique(TEST_ARBITER_RESOURCE),
+  };
+
+  App -> MainC.Boot;
+  App.Resource0 -> Arbiter.Resource[RESOURCE0_ID];
+  App.Resource1 -> Arbiter.Resource[RESOURCE1_ID];
+  App.Resource2 -> Arbiter.Resource[RESOURCE2_ID];
+  App.Timer0 -> Timer0;
+  App.Timer1 -> Timer1;
+  App.Timer2 -> Timer2;
+  
+  App.Leds -> LedsC;
+}
+
diff --git a/apps/tests/TestArbiter/TestFcfsArbiter/TestFcfsArbiterC.nc b/apps/tests/TestArbiter/TestFcfsArbiter/TestFcfsArbiterC.nc
new file mode 100644 (file)
index 0000000..8a09308
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2004, Technische Universitat Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "Timer.h"
+/**
+ * Please refer to TEP 108 for more information about the components
+ * this application is used to test
+ *
+ * This application is used to test the functionality of the
+ * FcfsArbiter component developed using the Resource
+ * interface.  Three Resource users are created and all three request
+ * control of the resource before any one of them is granted it.
+ * Once the first user is granted control of the resource, a timer
+ * is set to allow this user to have control of it for a specific
+ * amount of time.  Once this timer expires, the resource is released
+ * and then immediately requested again.  Upon releasing the resource
+ * control will be granted to the next user that has
+ * requested it in FCFS order.  Initial requests are made
+ * by the three resource users in the following order<br>
+ * <li> Resource 0
+ * <li> Resource 2
+ * <li> Resource 1
+ * <br>
+ * It is expected then that using a first-come-first-serve policy, control of the
+ * resource will be granted in the order of 0,2,1 and the Leds
+ * corresponding to each resource will flash whenever this occurs.<br>
+ * <li> Led 0 -> Resource 0
+ * <li> Led 1 -> Resource 1
+ * <li> Led 2 -> Resource 2
+ * <br>
+ *
+ * @author Kevin Klues <klues@tkn.tu-berlin.de>
+ * @version  $Revision$
+ * @date $Date$
+ */
+
+module TestFcfsArbiterC {
+  uses {
+    interface Boot;  
+    interface Leds;
+    interface Resource as Resource0;
+    interface Resource as Resource1;
+    interface Resource as Resource2;
+    interface Timer<TMilli> as Timer0;
+    interface Timer<TMilli> as Timer1;
+    interface Timer<TMilli> as Timer2;
+  }
+}
+implementation {
+
+  #define HOLD_PERIOD 250
+  
+  //All resources try to gain access
+  event void Boot.booted() {
+    call Resource0.request();
+    call Resource2.request();
+    call Resource1.request();
+  }
+  
+  //If granted the resource, turn on an LED  
+  event void Resource0.granted() {
+    call Timer0.startOneShot(HOLD_PERIOD);
+    call Leds.led0Toggle();      
+  }  
+  event void Resource1.granted() {
+    call Timer1.startOneShot(HOLD_PERIOD);
+    call Leds.led1Toggle();     
+  }  
+  event void Resource2.granted() {
+    call Timer2.startOneShot(HOLD_PERIOD);
+    call Leds.led2Toggle();  
+  }  
+  
+  //After the hold period release the resource
+  event void Timer0.fired() {
+    call Resource0.release();
+    call Resource0.request();
+  }
+  event void Timer1.fired() {
+    call Resource1.release();
+    call Resource1.request();
+  }
+  event void Timer2.fired() {
+    call Resource2.release();
+    call Resource2.request();
+  }
+}
+
diff --git a/apps/tests/TestArbiter/TestRoundRobinArbiter/TestRoundRobinArbiterAppC.nc b/apps/tests/TestArbiter/TestRoundRobinArbiter/TestRoundRobinArbiterAppC.nc
new file mode 100644 (file)
index 0000000..593fea7
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2004, Technische Universitat Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/**
+ * Please refer to TEP 108 for more information about the components
+ * this application is used to test.<br><br>
+ *
+ * This application is used to test the functionality of the
+ * RoundRobinArbiter component developed using the Resource
+ * interface.  Three Resource users are created and all three request
+ * control of the resource before any one of them is granted it.
+ * Once the first user is granted control of the resource, a timer
+ * is set to allow this user to have control of it for a specific
+ * amount of time.  Once this timer expires, the resource is released
+ * and then immediately requested again.  Upon releasing the resource
+ * control will be granted to the next user that has
+ * requested it in Round Robin order.  Initial requests are made
+ * by the three resource users in the following order<br>
+ * <li> Resource 0
+ * <li> Resource 2
+ * <li> Resource 1
+ * <br>
+ * It is expected then that using a round robin policy, control of the
+ * resource will be granted in the order of 0,1,2, and the Leds
+ * corresponding to each resource will flash whenever this occurs.<br>
+ * <li> Led 0 -> Resource 0
+ * <li> Led 1 -> Resource 1
+ * <li> Led 2 -> Resource 2
+ * <br>
+ *
+ * @author Kevin Klues <klues@tkn.tu-berlin.de>
+ * @version  $Revision$
+ * @date $Date$
+ */
+#define TEST_ARBITER_RESOURCE   "Test.Arbiter.Resource"
+configuration TestRoundRobinArbiterAppC{
+}
+implementation {
+  components MainC, TestRoundRobinArbiterC as App,LedsC,
+  new TimerMilliC() as Timer0,
+  new TimerMilliC() as Timer1,
+  new TimerMilliC() as Timer2,
+  new RoundRobinArbiterC(TEST_ARBITER_RESOURCE) as Arbiter;
+
+     enum {
+       RESOURCE0_ID = unique(TEST_ARBITER_RESOURCE),
+       RESOURCE1_ID = unique(TEST_ARBITER_RESOURCE),
+       RESOURCE2_ID = unique(TEST_ARBITER_RESOURCE),
+     };
+
+  App -> MainC.Boot;
+  
+  App.Resource0 -> Arbiter.Resource[RESOURCE0_ID];
+  App.Resource1 -> Arbiter.Resource[RESOURCE1_ID];
+  App.Resource2 -> Arbiter.Resource[RESOURCE2_ID];
+  App.Timer0 -> Timer0;
+  App.Timer1 -> Timer1;
+  App.Timer2 -> Timer2;
+  
+  App.Leds -> LedsC;
+}
+
diff --git a/apps/tests/TestArbiter/TestRoundRobinArbiter/TestRoundRobinArbiterC.nc b/apps/tests/TestArbiter/TestRoundRobinArbiter/TestRoundRobinArbiterC.nc
new file mode 100644 (file)
index 0000000..de62114
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2004, Technische Universitat Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "Timer.h"
+/**
+ * Please refer to TEP 108 for more information about the components
+ * this application is used to test
+ *
+ * This application is used to test the functionality of the
+ * RoundRobinArbiter component developed using the Resource
+ * interface.  Three Resource users are created and all three request
+ * control of the resource before any one of them is granted it.
+ * Once the first user is granted control of the resource, a timer
+ * is set to allow this user to have control of it for a specific
+ * amount of time.  Once this timer expires, the resource is released
+ * and then immediately requested again.  Upon releasing the resource
+ * control will be granted to the next user that has
+ * requested it in Round Robin order.  Initial requests are made
+ * by the three resource users in the following order<br>
+ * <li> Resource 0
+ * <li> Resource 2
+ * <li> Resource 1
+ * <br>
+ * It is expected then that using a round robin policy, control of the
+ * resource will be granted in the order of 0,1,2, and the Leds
+ * corresponding to each resource will flash whenever this occurs.<br>
+ * <li> Led 0 -> Resource 0
+ * <li> Led 1 -> Resource 1
+ * <li> Led 2 -> Resource 2
+ * <br>
+ *
+ * @author Kevin Klues <klues@tkn.tu-berlin.de>
+ * @version  $Revision$
+ * @date $Date$
+ */
+
+module TestRoundRobinArbiterC {
+  uses {
+    interface Boot;  
+    interface Leds;
+    interface Resource as Resource0;
+    interface Resource as Resource1;
+    interface Resource as Resource2;
+    interface Timer<TMilli> as Timer0;
+    interface Timer<TMilli> as Timer1;
+    interface Timer<TMilli> as Timer2;
+  }
+}
+implementation {
+
+  #define HOLD_PERIOD 250
+  
+  //All resources try to gain access
+  event void Boot.booted() {
+    call Resource0.request();
+    call Resource2.request();
+    call Resource1.request();
+  }
+  
+  //If granted the resource, turn on an LED  
+  event void Resource0.granted() {
+    call Timer0.startOneShot(HOLD_PERIOD);
+    call Leds.led0Toggle();      
+  }  
+  event void Resource1.granted() {
+    call Timer1.startOneShot(HOLD_PERIOD);
+    call Leds.led1Toggle();     
+  }  
+  event void Resource2.granted() {
+    call Timer2.startOneShot(HOLD_PERIOD);
+    call Leds.led2Toggle();  
+  }  
+  
+  //After the hold period release the resource
+  event void Timer0.fired() {
+    call Resource0.release();
+    call Resource0.request();
+  }
+  event void Timer1.fired() {
+    call Resource1.release();
+    call Resource1.request();
+  }
+  event void Timer2.fired() {
+    call Resource2.release();
+    call Resource2.request();
+  }
+}
+
diff --git a/apps/tests/TestDissemination/README b/apps/tests/TestDissemination/README
new file mode 100644 (file)
index 0000000..554bfa1
--- /dev/null
@@ -0,0 +1,24 @@
+README for TestDisseminationAppC
+
+This application will disseminate 2 constant data objects to all nodes
+every 20 seconds. Nodes whose TOS_NODE_ID mod 4 equals 1 will act as
+disseminators, and all others will act as receivers. 
+
+Every 20 seconds:
+* The disseminator toggles its led0 and led1.
+  Sim debugging msg: Timer fired.
+
+* The disseminator sends a new 32-bit value and a new 16-bit value.
+
+* When a receiver receives the correct 32-bit value, it toggles led0.
+  Sim debugging msg: Received new correct 32-bit value
+
+* When a receiver receives the correct 16-bit value, it toggles led1.
+  Sim debugging msg: Received new correct 16-bit value
+
+Thus, in a successful test, you should see all nodes toggling both
+led0 and led1 roughly in unison.
+
+
+
+
diff --git a/apps/tests/TestLPL/Makefile b/apps/tests/TestLPL/Makefile
new file mode 100644 (file)
index 0000000..1c57962
--- /dev/null
@@ -0,0 +1,4 @@
+COMPONENT=TestLplAppC
+
+include $(MAKERULES)
+
diff --git a/apps/tests/TestLPL/README.txt b/apps/tests/TestLPL/README.txt
new file mode 100644 (file)
index 0000000..02e0081
--- /dev/null
@@ -0,0 +1,54 @@
+README for TestLPL
+Author/Contact: tinyos-help@millennium.berkeley.edu
+
+Description:
+
+A simple low-power-listening test app, which cycles through different
+low-power-listening settings every ~32s, repeating every ~256s. 
+
+This application currently runs on motes using the CC1000 and CC2420
+radios. To compile for motes with CC2420 radios, you must do:
+  env CFLAGS="-I%T/chips/cc2420_lpl -DLOW_POWER_LISTENING" make <platform>
+
+This application blinks LED 0 every time it sends a message, and toggles
+LED 1 every time it receives a message.
+
+It's low-power-listening settings are as follows (repeating every 256s):
+
+0-32s:     receive: fully on
+           send: every second, to fully on listener
+
+32-64s:    receive: fully on
+          send: every second, to low-power-listeners with 100ms interval
+
+64-96s:    receive: low-power-listening with 250ms interval
+          send: every second, to low-power-listeners with 250ms interval
+
+96-128s:   receive: low-power-listening with 250ms interval
+          send: every second, to fully on listener
+
+128-160s:  receive: low-power-listening with 10ms interval
+          send: every second, to low-power-listeners with 10ms interval
+
+160-192s:  receive: low-power-listening with 2000ms interval
+          send: every 7 seconds, to low-power-listeners with 2000ms interval
+
+192-224s:  receive: low-power-listening with 1% duty cycle
+          send: every 7 seconds, to low-power-listeners with 1% duty cycle
+
+224-256s:  receive: low-power-listening with 0.1% duty cycle
+          send: every 7 seconds, to low-power-listeners with 0.1% duty cycle
+
+Whether two motes running TestLPL can receive each others messages depends
+on their current send and receive low-power-listening settings. If you reset
+two such motes at the same time, they will be able to receive each other's
+messages in the following intervals: 0-96s and 128-256s.
+
+Tools:
+
+None.
+
+Known bugs/limitations:
+
+None.
+
diff --git a/apps/tests/TestLPL/TestLplAppC.nc b/apps/tests/TestLPL/TestLplAppC.nc
new file mode 100644 (file)
index 0000000..1499eb5
--- /dev/null
@@ -0,0 +1,64 @@
+// $Id$
+
+/*                                                                     tab:4
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2005 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+/**
+ * Simple test code for low-power-listening. Sends a sequence of packets,
+ * changing the low-power-listening settings every ~32s. See README.txt
+ * for more details.
+ *
+ *  @author Philip Levis, David Gay
+ *  @date   Oct 27 2006
+ */
+
+configuration TestLplAppC {}
+implementation {
+  components MainC, TestLplC as App, LedsC;
+  components ActiveMessageC;
+  components new TimerMilliC();
+#if defined(PLATFORM_MICA2) || defined(PLATFORM_MICA2DOT)
+  components CC1000CsmaRadioC as LplRadio;
+#elif defined(PLATFORM_MICAZ) || defined(PLATFORM_TELOSB)
+  components CC2420ActiveMessageC as LplRadio;
+#else
+#error "LPL testing not supported on this platform"
+#endif
+    
+  App.Boot -> MainC.Boot;
+
+  App.Receive -> ActiveMessageC.Receive[240];
+  App.AMSend -> ActiveMessageC.AMSend[240];
+  App.SplitControl -> ActiveMessageC;
+  App.Leds -> LedsC;
+  App.MilliTimer -> TimerMilliC;
+  App.LowPowerListening -> LplRadio;
+}
+
+
diff --git a/apps/tests/TestLPL/TestLplC.nc b/apps/tests/TestLPL/TestLplC.nc
new file mode 100644 (file)
index 0000000..0920f13
--- /dev/null
@@ -0,0 +1,144 @@
+// $Id$
+
+/*                                                                     tab:4
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2003 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+#include "Timer.h"
+
+/**
+ * Simple test code for low-power-listening. Sends a sequence of packets,
+ * changing the low-power-listening settings every ~32s. See README.txt
+ * for more details.
+ *
+ *  @author Philip Levis, David Gay
+ *  @date   Oct 27 2006
+ */
+
+module TestLplC {
+  uses {
+    interface Leds;
+    interface Boot;
+    interface Receive;
+    interface AMSend;
+    interface Timer<TMilli> as MilliTimer;
+    interface SplitControl;
+    interface LowPowerListening;
+  }
+}
+implementation 
+{
+  message_t packet;
+  bool locked;
+  uint8_t counter = 0, sendSkip;
+  int16_t sendInterval;
+
+  event void Boot.booted() {
+    call SplitControl.start();
+  }
+
+  void nextLplState()
+  {
+    switch (counter >> 5) {
+    case 0:
+      sendSkip = 0;
+      sendInterval = 0;
+      call LowPowerListening.setLocalSleepInterval(0);
+      break;
+    case 1:
+      sendInterval = 100; /* Send to sleepy listener */
+      break;
+    case 2:
+      sendInterval = -1; /* Send to listener like us */
+      call LowPowerListening.setLocalSleepInterval(250);
+      break;
+    case 3:
+      sendInterval = 0; /* Send to awake listener */
+      break;
+    case 4:
+      sendInterval = -1; /* Send to listener like us */
+      call LowPowerListening.setLocalSleepInterval(10);
+      break;
+    case 5:
+      sendSkip = 7; /* Send every 7s */
+      call LowPowerListening.setLocalSleepInterval(2000);
+      break;
+    case 6:
+      call LowPowerListening.setLocalDutyCycle(100);
+      break;
+    case 7:
+      call LowPowerListening.setLocalDutyCycle(10);
+      break;
+    }
+  }
+  
+  event void MilliTimer.fired()
+  {
+    counter++;
+    if (!(counter & 31))
+      nextLplState();
+
+    if (!locked && ((counter & sendSkip) == sendSkip))
+      {
+       if (sendInterval >= 0)
+         call LowPowerListening.setRxSleepInterval(&packet, sendInterval);
+       if (call AMSend.send(AM_BROADCAST_ADDR, &packet, 0) == SUCCESS)
+         {
+           call Leds.led0On();
+           locked = TRUE;
+         }
+      }
+  }
+
+  event message_t* Receive.receive(message_t* bufPtr, 
+                                  void* payload, uint8_t len)
+  {
+    call Leds.led1Toggle();
+    return bufPtr;
+  }
+
+  event void AMSend.sendDone(message_t* bufPtr, error_t error)
+  {
+    if (&packet == bufPtr)
+      {
+       locked = FALSE;
+       call Leds.led0Off();
+      }
+  }
+
+  event void SplitControl.startDone(error_t err)
+  {
+    call MilliTimer.startPeriodic(1000);
+  }
+
+  event void SplitControl.stopDone(error_t err) { }
+}
+
+
+
+
diff --git a/apps/tests/TestPrintf/Makefile b/apps/tests/TestPrintf/Makefile
new file mode 100644 (file)
index 0000000..9f2960f
--- /dev/null
@@ -0,0 +1,13 @@
+COMPONENT=TestPrintfAppC
+CFLAGS += -I$(TOSDIR)/lib/printf
+
+BUILD_EXTRA_DEPS += PrintfMsg.class PrintfClient.class
+
+%.class: %.java
+       javac $<
+
+PrintfMsg.java: $(TOSDIR)/lib/printf/printf.h
+       mig java -target=$(PLATFORM) $(CFLAGS) -java-classname=PrintfMsg $(TOSDIR)/lib/printf/printf.h PrintfMsg -o $@
+
+include $(MAKERULES)
+
diff --git a/apps/tests/TestPrintf/PrintfClient.java b/apps/tests/TestPrintf/PrintfClient.java
new file mode 100644 (file)
index 0000000..55b38e5
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+
+/**
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+
+import java.io.IOException;
+
+import net.tinyos.message.*;
+import net.tinyos.packet.*;
+import net.tinyos.util.*;
+
+public class PrintfClient implements MessageListener {
+
+  private MoteIF moteIF;
+  
+  public PrintfClient(MoteIF moteIF) {
+    this.moteIF = moteIF;
+    this.moteIF.registerListener(new PrintfMsg(), this);
+  }
+
+  public void messageReceived(int to, Message message) {
+    PrintfMsg msg = (PrintfMsg)message;
+    for(int i=0; i<msg.dataLength(); i++) {
+      char nextChar = (char)(msg.getElement_buffer(i));
+      System.out.print(nextChar);
+    }
+  }
+  
+  private static void usage() {
+    System.err.println("usage: PrintfClient [-comm <source>]");
+  }
+  
+  public static void main(String[] args) throws Exception {
+    String source = "";
+    if (args.length == 2) {
+      if (!args[0].equals("-comm")) {
+              usage();
+              System.exit(1);
+      }
+      source = args[1];
+    }
+    else {
+      usage();
+      System.exit(1);
+    }
+    
+    PhoenixSource phoenix;
+    if (source == null) {
+      phoenix = BuildSource.makePhoenix(PrintStreamMessenger.err);
+    }
+    else {
+      phoenix = BuildSource.makePhoenix(source, PrintStreamMessenger.err);
+    }
+    System.out.print(phoenix);
+    MoteIF mif = new MoteIF(phoenix);
+    PrintfClient client = new PrintfClient(mif);
+  }
+}
diff --git a/apps/tests/TestPrintf/TestPrintfAppC.nc b/apps/tests/TestPrintf/TestPrintfAppC.nc
new file mode 100644 (file)
index 0000000..37c0bb1
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/**
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+#include "printf.h"
+
+configuration TestPrintfAppC{
+}
+implementation {
+  components MainC, TestPrintfC, LedsC;
+  components PrintfC;
+
+  TestPrintfC.Boot -> MainC;
+  TestPrintfC.Leds -> LedsC;
+  TestPrintfC.PrintfControl -> PrintfC;
+  TestPrintfC.PrintfFlush -> PrintfC;
+}
+
diff --git a/apps/tests/TestPrintf/TestPrintfC.nc b/apps/tests/TestPrintf/TestPrintfC.nc
new file mode 100644 (file)
index 0000000..79f3f08
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/**
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+
+module TestPrintfC {
+  uses {
+    interface Boot;  
+    interface Leds;
+    interface SplitControl as PrintfControl;
+    interface PrintfFlush;
+  }
+}
+implementation {
+       
+  #define NUM_TIMES_TO_PRINT   100
+  uint16_t counter=0;
+  uint32_t dummyVar = 345678;
+
+  event void Boot.booted() {
+    call PrintfControl.start();
+  }
+  
+  event void PrintfControl.startDone(error_t error) {
+       printf("Hi my name is Kevin Klues and I am writing to you from my telos mote\n");
+       printf("Here is a uint8: %hd\n", 123);
+       printf("Here is a uint16: %d\n", 12345);
+       printf("Here is a uint32: %ld\n", 1234567890);
+       call PrintfFlush.flush();
+  }
+
+  event void PrintfControl.stopDone(error_t error) {
+       counter = 0;
+       printf("This should not be printed...");
+       call PrintfFlush.flush();
+  }
+  
+  event void PrintfFlush.flushDone(error_t error) {
+       if(counter < NUM_TIMES_TO_PRINT) {
+      printf("I am now iterating: %d\n", counter);
+         call PrintfFlush.flush();
+    }
+    else if(counter == NUM_TIMES_TO_PRINT) {
+      printf("This is a really short string...\n");
+      printf("I am generating this string to have just less than 250 characters since that is the limit of the size I put on my maximum buffer when I instantiated the PrintfC component.\n");
+      printf("Only part of this line should get printed because by writing this sentence, I go over my character limit that the internal Printf buffer can hold.  If I were to flush before trying to write this, or increase my buffer size when I instantiate my PrintfC component to 1000, we would see this line too\n");
+      call PrintfFlush.flush();
+    }
+    else call PrintfControl.stop();
+    counter++;
+  }
+}
+
diff --git a/apps/tests/TestSharedResource/Makefile b/apps/tests/TestSharedResource/Makefile
new file mode 100644 (file)
index 0000000..fe39435
--- /dev/null
@@ -0,0 +1,3 @@
+COMPONENT=TestSharedResourceAppC
+include $(MAKERULES)
+
diff --git a/apps/tests/TestSharedResource/README.txt b/apps/tests/TestSharedResource/README.txt
new file mode 100644 (file)
index 0000000..8464c74
--- /dev/null
@@ -0,0 +1,35 @@
+README for TestFcfsArbiter
+Author/Contact: tinyos-help@millennium.berkeley.edu
+@author Kevin Klues <klues@tkn.tu-berlin.de>
+
+Description:
+
+This application is used to test the use of Shared Resources.  
+Three Resource users are created and all three request
+control of the resource before any one of them is granted it.
+Once the first user is granted control of the resource, it performs
+some operation on it.  Once this operation has completed, a timer
+is set to allow this user to have control of it for a specific
+amount of time.  Once this timer expires, the resource is released
+and then immediately requested again.  Upon releasing the resource
+control will be granted to the next user that has requested it in 
+round robin order.  Initial requests are made by the three resource 
+users in the following order.
+  -- Resource 0
+  -- Resource 2
+  -- Resource 1
+It is expected then that using a round robin policy, control of the
+resource will be granted in the order of 0,1,2 and the Leds
+corresponding to each resource will flash whenever this occurs.
+  -- Led 0 -> Resource 0
+  -- Led 1 -> Resource 1
+  -- Led 2 -> Resource 2
+
+Tools:
+
+None.
+
+Known bugs/limitations:
+
+None.
+
diff --git a/apps/tests/TestSharedResource/ResourceOperations.nc b/apps/tests/TestSharedResource/ResourceOperations.nc
new file mode 100644 (file)
index 0000000..8a7e9c6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/**
+ * An EXAMPLE of an interface for performing operations on a resource.
+ * In this test application it is provided by the dedicated ResourceP component
+ * and passed through all of the proper components before being exposed by the
+ * shared resource at the topmost level.
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+
+interface ResourceOperations {
+       command error_t operation();
+       event void operationDone(error_t error);
+}
diff --git a/apps/tests/TestSharedResource/ResourceP.nc b/apps/tests/TestSharedResource/ResourceP.nc
new file mode 100644 (file)
index 0000000..b1d644a
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/**
+ * This is an example implementation of a dedicated resource.  
+ * It provides the SplitControl interface for power management
+ * of the resource and an EXAMPLE ResourceOperations interface
+ * for performing operations on it.
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+
+module ResourceP {
+  provides {
+    interface SplitControl;
+    interface ResourceOperations;
+  }
+}
+implementation {
+       
+  bool lock;
+       
+  task void startDone() {
+       lock = FALSE;
+       signal SplitControl.startDone(SUCCESS);
+  }
+  
+  task void stopDone() {
+       signal SplitControl.stopDone(SUCCESS);
+  }
+  
+  task void operationDone() {
+       lock = FALSE;
+       signal ResourceOperations.operationDone(SUCCESS);
+  }
+       
+  command error_t SplitControl.start() {
+       post startDone();
+       return  SUCCESS;
+  }
+  
+  command error_t SplitControl.stop() {
+       lock = TRUE;
+       post stopDone();
+       return  SUCCESS;
+  }
+  
+  command error_t ResourceOperations.operation() {
+       if(lock == FALSE) {
+      lock = TRUE;
+         post operationDone();
+         return SUCCESS;
+       }
+       return FAIL;
+  }
+}
+
diff --git a/apps/tests/TestSharedResource/SharedResourceC.nc b/apps/tests/TestSharedResource/SharedResourceC.nc
new file mode 100644 (file)
index 0000000..a6f8468
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/**
+ * SharedResourceC is used to provide a generic configuration around 
+ * the SharedResourceP component so that new instantiations of 
+ * it provide a single set of interfaces that are all properly associated 
+ * with one another rather than requiring the user to deal with the complexity
+ * of doing this themselves.
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+#define TEST_SHARED_RESOURCE   "Test.Shared.Resource"
+generic configuration SharedResourceC() {
+       provides interface Resource;
+       provides interface ResourceRequested;
+       provides interface ResourceOperations;
+    uses interface ResourceConfigure;
+}
+implementation {
+  components SharedResourceP;
+  
+  enum {
+    RESOURCE_ID = unique(TEST_SHARED_RESOURCE)
+  };
+
+  Resource = SharedResourceP.Resource[RESOURCE_ID];
+  ResourceRequested = SharedResourceP.ResourceRequested[RESOURCE_ID];
+  ResourceOperations = SharedResourceP.ResourceOperations[RESOURCE_ID];
+  ResourceConfigure = SharedResourceP.ResourceConfigure[RESOURCE_ID];
+}
+
diff --git a/apps/tests/TestSharedResource/SharedResourceImplP.nc b/apps/tests/TestSharedResource/SharedResourceImplP.nc
new file mode 100644 (file)
index 0000000..ae9d0f0
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/**
+ * The SharedResourceImplP component is used to wrap all of the operations
+ * from a dedicated resource so that access to them is protected when 
+ * it is used as a shared resource.  It uses the ArbiterInfo interface 
+ * provided by an Arbiter to accomplish this.
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+
+module SharedResourceImplP {
+  provides {
+    interface ResourceOperations as SharedResourceOperations[uint8_t id];
+  }
+  uses {
+       interface ArbiterInfo;
+       interface ResourceOperations;
+  }
+}
+implementation {
+  uint8_t current_id = 0xFF;
+  
+  event void ResourceOperations.operationDone(error_t error) {
+       signal SharedResourceOperations.operationDone[current_id](error);
+  }
+  
+  command error_t SharedResourceOperations.operation[uint8_t id]() {
+       if(call ArbiterInfo.userId() == id && call ResourceOperations.operation() == SUCCESS) {
+      current_id = id;
+         return SUCCESS;
+       }
+       return FAIL;
+  }
+  
+  default event void SharedResourceOperations.operationDone[uint8_t id](error_t error) {}
+}
+
diff --git a/apps/tests/TestSharedResource/SharedResourceP.nc b/apps/tests/TestSharedResource/SharedResourceP.nc
new file mode 100644 (file)
index 0000000..a5e7262
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/**
+ * The SharedResourceP component is used to create a shared resource
+ * out of a dedicated one.
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+#define TEST_SHARED_RESOURCE   "Test.Shared.Resource"
+configuration SharedResourceP {
+       provides interface Resource[uint8_t id];
+       provides interface ResourceRequested[uint8_t id];
+       provides interface ResourceOperations[uint8_t id];
+       uses interface ResourceConfigure[uint8_t id];
+}
+implementation {
+  components new RoundRobinArbiterC(TEST_SHARED_RESOURCE) as Arbiter;
+  components new SplitControlPowerManagerC() as PowerManager;
+  components ResourceP;
+  components SharedResourceImplP;
+
+  ResourceOperations = SharedResourceImplP;
+  Resource = Arbiter;
+  ResourceRequested = Arbiter;
+  ResourceConfigure = Arbiter;
+  SharedResourceImplP.ArbiterInfo -> Arbiter;
+  PowerManager.ResourceController -> Arbiter;
+  
+  PowerManager.SplitControl -> ResourceP;
+  SharedResourceImplP.ResourceOperations -> ResourceP;
+}
+
diff --git a/apps/tests/TestSharedResource/TestSharedResourceAppC.nc b/apps/tests/TestSharedResource/TestSharedResourceAppC.nc
new file mode 100644 (file)
index 0000000..bf2975b
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/**
+ *
+ * This application is used to test the use of Shared Resources.  
+ * Three Resource users are created and all three request
+ * control of the resource before any one of them is granted it.
+ * Once the first user is granted control of the resource, it performs
+ * some operation on it.  Once this operation has completed, a timer
+ * is set to allow this user to have control of it for a specific
+ * amount of time.  Once this timer expires, the resource is released
+ * and then immediately requested again.  Upon releasing the resource
+ * control will be granted to the next user that has requested it in 
+ * round robin order.  Initial requests are made by the three resource 
+ * users in the following order.<br>
+ * <li> Resource 0
+ * <li> Resource 2
+ * <li> Resource 1
+ * <br>
+ * It is expected then that using a round robin policy, control of the
+ * resource will be granted in the order of 0,1,2 and the Leds
+ * corresponding to each resource will flash whenever this occurs.<br>
+ * <li> Led 0 -> Resource 0
+ * <li> Led 1 -> Resource 1
+ * <li> Led 2 -> Resource 2
+ * <br>
+ * 
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+configuration TestSharedResourceAppC{
+}
+implementation {
+  components MainC,LedsC, TestSharedResourceC as App,
+  new TimerMilliC() as Timer0,
+  new TimerMilliC() as Timer1,
+  new TimerMilliC() as Timer2;
+  App -> MainC.Boot;
+  App.Leds -> LedsC;
+  App.Timer0 -> Timer0;
+  App.Timer1 -> Timer1;
+  App.Timer2 -> Timer2;
+  
+  components
+  new SharedResourceC() as Resource0,
+  new SharedResourceC() as Resource1, 
+  new SharedResourceC() as Resource2;
+  App.Resource0 -> Resource0;
+  App.Resource1 -> Resource1;
+  App.Resource2 -> Resource2;
+  App.ResourceOperations0 -> Resource0;
+  App.ResourceOperations1 -> Resource1;
+  App.ResourceOperations2 -> Resource2;
+}
diff --git a/apps/tests/TestSharedResource/TestSharedResourceC.nc b/apps/tests/TestSharedResource/TestSharedResourceC.nc
new file mode 100644 (file)
index 0000000..833fe81
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+#include "Timer.h"
+/**
+ *
+ * This application is used to test the use of Shared Resources.  
+ * Three Resource users are created and all three request
+ * control of the resource before any one of them is granted it.
+ * Once the first user is granted control of the resource, it performs
+ * some operation on it.  Once this operation has completed, a timer
+ * is set to allow this user to have control of it for a specific
+ * amount of time.  Once this timer expires, the resource is released
+ * and then immediately requested again.  Upon releasing the resource
+ * control will be granted to the next user that has requested it in 
+ * round robin order.  Initial requests are made by the three resource 
+ * users in the following order.<br>
+ * <li> Resource 0
+ * <li> Resource 2
+ * <li> Resource 1
+ * <br>
+ * It is expected then that using a round robin policy, control of the
+ * resource will be granted in the order of 0,1,2 and the Leds
+ * corresponding to each resource will flash whenever this occurs.<br>
+ * <li> Led 0 -> Resource 0
+ * <li> Led 1 -> Resource 1
+ * <li> Led 2 -> Resource 2
+ * <br>
+ * 
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+
+module TestSharedResourceC {
+  uses {
+    interface Boot;  
+    interface Leds;
+    interface Timer<TMilli> as Timer0;
+    interface Timer<TMilli> as Timer1;
+    interface Timer<TMilli> as Timer2;
+    
+    interface Resource as Resource0;
+    interface ResourceOperations as ResourceOperations0;
+    
+    interface Resource as Resource1;
+    interface ResourceOperations as ResourceOperations1;
+    
+    interface Resource as Resource2;
+    interface ResourceOperations as ResourceOperations2;
+  }
+}
+implementation {
+
+  #define HOLD_PERIOD 250
+  
+  //All resources try to gain access
+  event void Boot.booted() {
+    call Resource0.request();
+    call Resource2.request();
+    call Resource1.request();
+  }
+  
+  //If granted the resource, run some operation  
+  event void Resource0.granted() {
+       call ResourceOperations0.operation();   
+  }  
+  event void Resource1.granted() {
+       call ResourceOperations1.operation();
+  }  
+  event void Resource2.granted() {
+       call ResourceOperations2.operation();
+  }  
+  
+  //When the operation completes, flash the LED and hold the resource for a while
+  event void ResourceOperations0.operationDone(error_t error) {
+       call Timer0.startOneShot(HOLD_PERIOD);  
+    call Leds.led0Toggle();
+  }
+  event void ResourceOperations1.operationDone(error_t error) {
+    call Timer1.startOneShot(HOLD_PERIOD);  
+    call Leds.led1Toggle();
+  }
+  event void ResourceOperations2.operationDone(error_t error) {
+    call Timer2.startOneShot(HOLD_PERIOD);  
+    call Leds.led2Toggle();
+  }
+  
+  //After the hold period release the resource and request it again
+  event void Timer0.fired() {
+    call Resource0.release();
+    call Resource0.request();
+  }
+  event void Timer1.fired() {
+    call Resource1.release();
+    call Resource1.request();
+  }
+  event void Timer2.fired() {
+    call Resource2.release();
+    call Resource2.request();
+  }
+}
+
diff --git a/apps/tests/TestTrickleTimer/TestTrickle.h b/apps/tests/TestTrickleTimer/TestTrickle.h
new file mode 100644 (file)
index 0000000..33f99cb
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TEST_TRICKLE_H
+#define TEST_TRICKLE_H
+
+#define UQ_TEST_TRICKLE "TestTrickle.TrickleTimer"
+
+#endif
diff --git a/apps/tests/eyesIFX/RadioCountToFlash/Makefile b/apps/tests/eyesIFX/RadioCountToFlash/Makefile
new file mode 100644 (file)
index 0000000..14ef685
--- /dev/null
@@ -0,0 +1,15 @@
+COMPONENT=RadioCountToFlashAppC
+BUILD_EXTRA_DEPS = RadioCountMsg.py RadioCountMsg.class
+
+RadioCountMsg.py: RadioCountToFlash.h
+       mig python -target=$(PLATFORM) $(CFLAGS) -python-classname=RadioCountMsg RadioCountToFlash.h RadioCountMsg -o $@
+
+RadioCountMsg.class: RadioCountMsg.java
+       javac RadioCountMsg.java
+
+RadioCountMsg.java: RadioCountToFlash.h
+       mig java -target=$(PLATFORM) $(CFLAGS) -java-classname=RadioCountMsg RadioCountToFlash.h RadioCountMsg -o $@
+
+
+include $(MAKERULES)
+
diff --git a/apps/tests/eyesIFX/RadioCountToFlash/README.txt b/apps/tests/eyesIFX/RadioCountToFlash/README.txt
new file mode 100644 (file)
index 0000000..2bf61d2
--- /dev/null
@@ -0,0 +1,22 @@
+README for RadioCountToFlash
+
+Description:
+
+RadioCountToLeds maintains a 1Hz counter and broadcsts its value repeatedly. A 
+RadioCountToLeds node that hears a counter writes the counter to the flash. 
+After LOG_LENGTH (default = 16) successful receiptions the previously stored counters 
+are read from the flash with a delay of 100ms between each read. The bottom three bits 
+are displayed on the LEDs. This application tests the coexistance between 
+the radio and the flash.
+
+Tools:
+
+RadioCountMsg.java is a Java class representing the message that
+this application sends.  RadioCountMsg.py is a Python class representing
+the message that this application sends.
+
+Known bugs/limitations:
+
+None.
+
+
diff --git a/apps/tests/eyesIFX/RadioCountToFlash/RadioCountToFlash.h b/apps/tests/eyesIFX/RadioCountToFlash/RadioCountToFlash.h
new file mode 100644 (file)
index 0000000..2c8a0ac
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef RADIO_COUNT_TO_FLASH_H
+#define RADIO_COUNT_TO_FLASH_H
+
+typedef nx_struct RadioCountMsg {
+  nx_uint16_t counter;
+} RadioCountMsg;
+
+enum {
+  AM_RADIOCOUNTMSG = 6,
+};
+
+#endif
diff --git a/apps/tests/eyesIFX/RadioCountToFlash/RadioCountToFlashAppC.nc b/apps/tests/eyesIFX/RadioCountToFlash/RadioCountToFlashAppC.nc
new file mode 100644 (file)
index 0000000..67ce4a6
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2005 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+/**
+ * This application tests the coexistence of radio and flash.
+ * (based on RadioCountToLeds)
+ *
+ * @see README.TXT
+ * @author Philipp Huppertz
+ * @author Philip Levis (RadioCountToLeds)
+ * @date   June 6 2005
+ */
+
+#include "RadioCountToFlash.h"
+#include "StorageVolumes.h"
+
+
+configuration RadioCountToFlashAppC {}
+implementation {
+  components MainC, RadioCountToFlashC as App, LedsC, PlatformLedsC;
+  components new AMSenderC(AM_RADIOCOUNTMSG);
+  components new AMReceiverC(AM_RADIOCOUNTMSG);
+  components new TimerMilliC() as RadioTimer;
+  components new TimerMilliC() as FlashTimer;
+  components ActiveMessageC;
+  components new LogStorageC(VOLUME_LOGTEST, TRUE);
+
+  
+  
+  
+  App.Boot -> MainC.Boot;
+  
+  App.Receive -> AMReceiverC;
+  App.AMSend -> AMSenderC;
+  App.AMControl -> ActiveMessageC;
+  App.Leds -> LedsC;
+  App.FailureLed -> PlatformLedsC.Led3;
+  App.FlashTimer -> FlashTimer;
+  App.RadioTimer -> RadioTimer;
+  App.Packet -> AMSenderC;
+  
+  App.LogRead -> LogStorageC.LogRead;
+  App.LogWrite -> LogStorageC.LogWrite;
+}
+
+
diff --git a/apps/tests/eyesIFX/RadioCountToFlash/RadioCountToFlashC.nc b/apps/tests/eyesIFX/RadioCountToFlash/RadioCountToFlashC.nc
new file mode 100644 (file)
index 0000000..0ec35e6
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+    * "Copyright (c) 2000-2005 The Regents of the University  of California.  
+    * All rights reserved.
+    *
+    * Permission to use, copy, modify, and distribute this software and its
+    * documentation for any purpose, without fee, and without written agreement is
+    * hereby granted, provided that the above copyright notice, the following
+    * two paragraphs and the author appear in all copies of this software.
+    * 
+    * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+    * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+    * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+    * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+    * 
+    * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+    * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+    * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+    * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+    * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+    *
+    * Copyright (c) 2002-2003 Intel Corporation
+    * All rights reserved.
+    *
+    * This file is distributed under the terms in the attached INTEL-LICENSE     
+    * file. If you do not find these files, copies can be found by writing to
+    * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+    * 94704.  Attention:  Intel License Inquiry.
+ */
+
+/**
+ * This application tests the coexistence of radio and flash.
+ * (based on RadioCountToLeds)
+ *
+ * @see README.TXT
+ * @author Philipp Huppertz
+ * @author Philip Levis (RadioCountToLeds)
+ * @date   June 6 2005
+ */
+
+#include "Timer.h"
+#include "RadioCountToFlash.h"
+#define LOG_LENGTH 15
+
+module RadioCountToFlashC {
+  uses {
+    interface Leds;
+    interface Boot;
+    interface Receive;
+    interface AMSend;
+    interface Timer<TMilli> as FlashTimer;
+    interface Timer<TMilli> as RadioTimer;
+    interface SplitControl as AMControl;
+    interface Packet;
+    interface LogRead;
+    interface LogWrite;
+    interface GeneralIO as FailureLed;
+  }
+}
+implementation {
+
+  message_t packet;
+
+  bool locked;
+  uint16_t sendingCounter = 0;
+  uint16_t receiveCounter = 0;
+  uint16_t readBuffer = 0;
+  uint16_t logCounter = 0;      
+  void failure() {
+    call FailureLed.set();
+    for (;;) {
+      ;
+    }
+  } 
+  
+  task void readingTask() {
+    if (call LogRead.read((void*) &readBuffer, sizeof(receiveCounter)) != SUCCESS) {
+      post readingTask();
+    }
+  }
+  
+  task void writingTask() {
+    if (call LogWrite.append((void*)receiveCounter, sizeof(receiveCounter)) != SUCCESS) {
+      post writingTask();
+    }
+  }
+  
+  event void Boot.booted() {
+    call LogWrite.erase();
+    call AMControl.start();
+  }
+
+  event void AMControl.startDone(error_t err) {
+    if (err == SUCCESS) {
+      call RadioTimer.startPeriodic(1000);
+    }
+    else {
+      call AMControl.start();
+    }
+  }
+
+  event void AMControl.stopDone(error_t err) {
+       // do nothing
+  }
+  
+  event void FlashTimer.fired() {
+    if (call LogRead.read((void*) &readBuffer, sizeof(receiveCounter)) != SUCCESS) {
+      post readingTask();
+    }
+  }
+      
+  event void RadioTimer.fired() {
+    dbg("RadioCountToLedsC", "RadioCountToLedsC: timer fired, counter is %hu.\n", counter);
+    if (locked) {
+      return;
+    }
+    else {
+      RadioCountMsg* rcm = (RadioCountMsg*)call Packet.getPayload(&packet, NULL);
+      if (call Packet.maxPayloadLength() < sizeof(RadioCountMsg)) {
+        return;
+      }
+      ++sendingCounter;
+      rcm->counter = sendingCounter;   
+      if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(RadioCountMsg)) == SUCCESS) {
+        dbg("RadioCountToLedsC", "RadioCountToLedsC: packet sent.\n", counter);        
+        locked = TRUE;
+      }
+    }
+  }
+
+  event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len) {
+    dbg("RadioCountToLedsC", "Received packet of length %hhu.\n", len);
+    if (len != sizeof(RadioCountMsg)) {return bufPtr;}
+    else {
+      RadioCountMsg* rcm = (RadioCountMsg*)payload;
+      receiveCounter = rcm->counter;
+      if (call LogWrite.append((void*)&receiveCounter, sizeof(receiveCounter)) != SUCCESS) {
+        post writingTask();
+      }
+    }
+    return bufPtr;
+  }
+
+  event void AMSend.sendDone(message_t* bufPtr, error_t error) {
+    if (&packet == bufPtr) {
+      locked = FALSE;
+    }
+  }
+
+  event void LogRead.readDone(void* buf, storage_len_t len, error_t error) {
+    --logCounter;
+    if (error != SUCCESS) {
+      failure();
+    }
+    readBuffer = *(uint16_t*)buf;
+    if ( logCounter > 0 ) {
+      if (readBuffer & 0x1) {
+        call Leds.led0On();
+      }
+      else {
+        call Leds.led0Off();
+      }
+      if (readBuffer & 0x2) {
+        call Leds.led1On();
+      }
+      else {
+        call Leds.led1Off();
+      }
+      if (readBuffer & 0x4) {
+        call Leds.led2On();
+      }
+      else {
+        call Leds.led2Off();
+      }
+      call FlashTimer.startOneShot(100);
+    } 
+  }  
+      
+  event void LogRead.seekDone(error_t error) {
+    if (error != SUCCESS) {
+      failure();
+    }
+  }
+  
+  event void LogWrite.appendDone(void* buf, storage_len_t len, bool recordsLost, error_t error) {
+    ++logCounter;
+    if (error != SUCCESS) {
+      failure();
+    }
+    if (logCounter > LOG_LENGTH) {
+      if (call LogWrite.sync() != SUCCESS) {
+        failure();
+      } 
+    } 
+  }
+
+  event void LogWrite.syncDone(error_t error) {
+    if (error != SUCCESS) {
+      failure();
+    }
+    call FlashTimer.startOneShot(100);
+  }
+      
+  event void LogWrite.eraseDone(error_t error) {
+    if (error != SUCCESS) {
+      failure();
+    }
+  }
+      
+}
+
diff --git a/apps/tests/eyesIFX/RadioCountToFlash/volumes-at45db.xml b/apps/tests/eyesIFX/RadioCountToFlash/volumes-at45db.xml
new file mode 100644 (file)
index 0000000..daa0d50
--- /dev/null
@@ -0,0 +1,3 @@
+<volume_table>
+  <volume name="LOGTEST" size="262144"/>
+</volume_table>
diff --git a/apps/tests/storage/Block/volumes-pxa27xp30.xml b/apps/tests/storage/Block/volumes-pxa27xp30.xml
new file mode 100644 (file)
index 0000000..50bf188
--- /dev/null
@@ -0,0 +1,3 @@
+<volume_table>
+  <volume name="BLOCKTEST" size="2097152"/>
+</volume_table>
diff --git a/apps/tests/storage/CircularLog/volumes-pxa27xp30.xml b/apps/tests/storage/CircularLog/volumes-pxa27xp30.xml
new file mode 100644 (file)
index 0000000..cc81eb1
--- /dev/null
@@ -0,0 +1,3 @@
+<volume_table>
+  <volume name="LOGTEST" size="2097152"/>
+</volume_table>
diff --git a/apps/tests/storage/Config/volumes-pxa27xp30.xml b/apps/tests/storage/Config/volumes-pxa27xp30.xml
new file mode 100644 (file)
index 0000000..31c6590
--- /dev/null
@@ -0,0 +1,3 @@
+<volume_table>
+  <volume name="CONFIGTEST" size="2097152"/>
+</volume_table>
diff --git a/apps/tests/storage/Log/volumes-pxa27xp30.xml b/apps/tests/storage/Log/volumes-pxa27xp30.xml
new file mode 100644 (file)
index 0000000..cc81eb1
--- /dev/null
@@ -0,0 +1,3 @@
+<volume_table>
+  <volume name="LOGTEST" size="2097152"/>
+</volume_table>
index 46c759671a2e129c3a59e2c41571c4a4cd994428..f990b6ccfe77630eac07c497de61a6cfb46c6513 100644 (file)
  */
 #include "StorageVolumes.h"
 
+/**
+ * Application to demonstrate the ConfigStorageC abstraction.  A value
+ * is written to, and read from, the flash storage. A successful test
+ * will turn on both the green and blue (yellow) LEDs.  A failed test
+ * is any other LED configuration.
+ *
+ * @author Prabal Dutta
+ */
 configuration BlinkConfigAppC {
 }
 implementation {
index 394f5b2e7b595cde838a3b457f373f69665abb86..91853c7da908484474f6db6a4549fe25ffbcfa14 100644 (file)
  * UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
  */
 
+/**
+ * Application to demonstrate the ConfigStorageC abstraction.  A value
+ * is written to, and read from, the flash storage. A successful test
+ * will turn on both the green and blue (yellow) LEDs.  A failed test
+ * is any other LED combination..
+ *
+ * @author Prabal Dutta
+ */
 module BlinkConfigC {
   uses {
     interface Boot;
index 01332157c8dc904d38bef593215138120fb96228..7cf9967d15af0c93a3c8d9e33b01456721ba4ba2 100644 (file)
@@ -8,7 +8,7 @@ Application to demonstrate the ConfigStorageC abstraction.  A value is
 written to, and read from, the flash storage.
 
 A successful test will turn on both the green and blue (yellow)
-LEDs. A failed test will turn on the red led.
+LEDs.  A failed test is any other LED combination.
 
 Tools:
 
diff --git a/doc/html/porting.html b/doc/html/porting.html
new file mode 100644 (file)
index 0000000..be84106
--- /dev/null
@@ -0,0 +1,378 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
+<title>Porting TinyOS 1.x Code to TinyOS 2.0</title>
+<meta name="author" content="Tahir Azim and Philip Levis" />
+<meta name="date" content="October 26 2006" />
+<style type="text/css">
+
+/*
+:Author: David Goodger
+:Contact: goodger@users.sourceforge.net
+:date: $Date$
+:version: $Revision$
+:copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+*/
+body {
+  font-family: Times;
+  font-size: 16px;
+}
+
+.first {
+  margin-top: 0 ! important }
+
+.last {
+  margin-bottom: 0 ! important }
+
+.hidden {
+  display: none }
+
+a.toc-backref {
+  text-decoration: none ;
+  color: black }
+
+blockquote.epigraph {
+  margin: 2em 5em ; }
+
+dd {
+  margin-bottom: 0.5em }
+
+/* Uncomment (& remove this text!) to get bold-faced definition list terms
+dt {
+  font-weight: bold }
+*/
+
+div.abstract {
+  margin: 2em 5em }
+
+div.abstract p.topic-title {
+  font-weight: bold ;
+  text-align: center }
+
+div.attention, div.caution, div.danger, div.error, div.hint,
+div.important, div.note, div.tip, div.warning, div.admonition {
+  margin: 2em ;
+  border: medium outset ;
+  padding: 1em }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+  color: red ;
+  font-weight: bold ;
+  font-family: sans-serif }
+
+div.hint p.admonition-title, div.important p.admonition-title,
+div.note p.admonition-title, div.tip p.admonition-title,
+div.admonition p.admonition-title {
+  font-weight: bold ;
+  font-family: sans-serif }
+
+div.dedication {
+  margin: 2em 5em ;
+  text-align: center ;
+  font-style: italic }
+
+div.dedication p.topic-title {
+  font-weight: bold ;
+  font-style: normal }
+
+div.figure {
+  margin-left: 2em }
+
+div.footer, div.header {
+  font-size: smaller }
+
+div.line-block {
+  display: block ;
+  margin-top: 1em ;
+  margin-bottom: 1em }
+
+div.line-block div.line-block {
+  margin-top: 0 ;
+  margin-bottom: 0 ;
+  margin-left: 1.5em }
+
+div.sidebar {
+  margin-left: 1em ;
+  border: medium outset ;
+  padding: 0em 1em ;
+  background-color: #ffffee ;
+  width: 40% ;
+  float: right ;
+  clear: right }
+
+div.sidebar p.rubric {
+  font-family: sans-serif ;
+  font-size: medium }
+
+div.system-messages {
+  margin: 5em }
+
+div.system-messages h1 {
+  color: red }
+
+div.system-message {
+  border: medium outset ;
+  padding: 1em }
+
+div.system-message p.system-message-title {
+  color: red ;
+  font-weight: bold }
+
+div.topic {
+  margin: 2em }
+
+h1 {
+  font-family: Arial, sans-serif;
+  font-size: 20px;
+}
+
+h1.title {
+ text-align: center;
+ font-size: 32px;
+}
+
+h2 {
+ font-size: 16px;
+ font-family: Arial, sans-serif;
+}
+
+h2.subtitle {
+  text-align: center }
+
+h3 {
+ font-size: 12px;
+ font-family: Arial, sans-serif;
+}
+
+hr {
+  width: 75% }
+
+ol.simple, ul.simple {
+  margin-bottom: 1em }
+
+ol.arabic {
+  list-style: decimal }
+
+ol.loweralpha {
+  list-style: lower-alpha }
+
+ol.upperalpha {
+  list-style: upper-alpha }
+
+ol.lowerroman {
+  list-style: lower-roman }
+
+ol.upperroman {
+  list-style: upper-roman }
+
+p.attribution {
+  text-align: right ;
+  margin-left: 50% }
+
+p.caption {
+  font-style: italic }
+
+p.credits {
+  font-style: italic ;
+  font-size: smaller }
+
+p.label {
+  white-space: nowrap }
+
+p.rubric {
+  font-weight: bold ;
+  font-size: larger ;
+  color: maroon ;
+  text-align: center }
+
+p.sidebar-title {
+  font-family: sans-serif ;
+  font-weight: bold ;
+  font-size: larger }
+
+p.sidebar-subtitle {
+  font-family: sans-serif ;
+  font-weight: bold }
+
+p.topic-title {
+  font-weight: bold }
+
+pre.address {
+  margin-bottom: 0 ;
+  margin-top: 0 ;
+  font-family: serif ;
+  font-size: 100% }
+
+pre.line-block {
+  font-family: serif ;
+  font-size: 100% }
+
+pre.literal-block, pre.doctest-block {
+  margin-left: 2em ;
+  margin-right: 2em ;
+  background-color: #eeeeee;
+  border-color: #000000;
+  border-width: thin; 
+  font-size: 14px
+}
+
+span.classifier {
+  font-family: sans-serif ;
+  font-style: oblique }
+
+span.classifier-delimiter {
+  font-family: sans-serif ;
+  font-weight: bold }
+
+span.interpreted {
+  font-family: sans-serif }
+
+span.option {
+  white-space: nowrap }
+
+span.option-argument {
+  font-style: italic }
+
+span.pre {
+  white-space: pre }
+
+span.problematic {
+  color: red }
+
+table {
+  margin-top: 0.5em ;
+  margin-bottom: 0.5em }
+
+table.citation {
+  border-left: solid thin gray ;
+  padding-left: 0.5ex }
+
+table.docinfo {
+  margin: 2em 4em;
+}
+
+table.footnote {
+  border-left: solid thin black ;
+  padding-left: 0.5ex }
+
+td, th {
+  padding-left: 0.5em ;
+  padding-right: 0.5em ;
+  vertical-align: top }
+
+th.docinfo-name, th.field-name {
+  font-weight: bold ;
+  text-align: left ;
+  white-space: nowrap;
+  }
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+  font-size: 100% }
+
+tt {}
+
+ul.auto-toc {
+  list-style-type: none }
+
+</style>
+</head>
+<body>
+<div class="document" id="porting-tinyos-1-x-code-to-tinyos-2-0">
+<h1 class="title">Porting TinyOS 1.x Code to TinyOS 2.0</h1>
+<table class="docinfo" frame="void" rules="none">
+<col class="docinfo-name" />
+<col class="docinfo-content" />
+<tbody valign="top">
+<tr><th class="docinfo-name">Author:</th>
+<td>Tahir Azim and Philip Levis</td></tr>
+<tr><th class="docinfo-name">Date:</th>
+<td>October 26 2006</td></tr>
+</tbody>
+</table>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">This document provides a few important points that describe
+major steps required for porting TinyOS 1.x code to TinyOS 2.0.
+It is based on Tahir Azim's experience porting Beacon Vector
+Routing (BVR[<a class="reference" href="#id1">1</a>]) from TinyOS 1.x to T2. This document is not
+a complete porting guide, but the hope is that it will provide
+some help or guidance.</p>
+</div>
+<div class="section">
+<h1><a id="porting-points" name="porting-points">1. Porting Points</a></h1>
+<p>As these observations come from porting a network protocol, they are
+rather protocol-centric and do not consider other abstractions such
+as storage. We hope to add such points in the future.</p>
+<blockquote>
+<ol class="arabic">
+<li><p class="first">SUCCESS was a non-zero error code in TinyOS 1.x, while FAIL was non-zero. So any &quot;if blocks&quot; of the following form need to be changed:</p>
+<pre class="literal-block">
+if (call Packet...) {
+    //SUCCESS!: do this...
+}
+</pre>
+</li>
+</ol>
+<p>In TinyOS 2.x, SUCCESS is equal to a zero error code, while other error codes are non-zero. So calls like this should be changed to make sure they test the result for equality with SUCCESS:</p>
+<pre class="literal-block">
+if (call Packet... () == SUCCESS ) {
+      //SUCCESS!: do this...
+  }
+</pre>
+<ol class="arabic simple" start="2">
+<li>The &quot;init()&quot; and &quot;start/stop()&quot; methods in StdControl have been separated in TinyOS 2.x. The init() method is now part of the &quot;Init&quot; interface. Therefore all modules implementing StdControl should now implement Init also. Modules wired to the StdControl interface of a module should also wire to its Init interface.</li>
+<li>The nx_bool data type should be replaced by nx_uint8_t.</li>
+<li>Radios need to be started manually using SplitControl.start() and SplitControl.stop() at the beginning of the simulation. In TinyOS 1.x, this was assumed to be done automatically by TOSSIM/TinyOS.</li>
+<li>Packets are now an abstract data type (ADT) in TinyOS 2.x. Therefore, destination addresses from packets can no longer be obtained by using &quot;msg -&gt; addr&quot;. Instead the AMPacket.destination() method of the AMPacket interface should be used for this purpose. AMSenderC or AMReceiverC can be used to wire the AMPacket interface.</li>
+<li>Similarly, in order to get a pointer to the payload of received message_t structures, and to get the payload lengths and maximum payload lengths of message_t structures, the Packet interface is used. This can also be wired to an AMSenderC or AMReceiverC component.  Similarly, instead of using &quot;msg-&gt;strength&quot; to get the strength of a received signal, CC2420Packet.getRssi(msg) can be used. The CC2420Packet interface can be wired to CC2420ActiveMessageC.</li>
+<li>Communication interfaces are very similar but require straightforward porting. SendMsg and ReceiveMsg interfaces (wherever used or provided by various modules) should be replaced by AMSend and Receive interfaces. At the lowest layer of the communication stack, AMSend and Receive interfaces should be wired to AMSenderC and AMReceiverC.</li>
+<li>Where a module that previously provided SendMsg is changed to provide AMSend, extra methods have to be added that are part of the AMSend signature. These include the cancel, getPayload and maxPayloadLength methods. The Packet interface wired to AMSenderC can generally be used to implement these methods.</li>
+<li>TOS_UART_ADDRESS no longer exists. Use an SerialAMSenderC component when you would like to send to the serial port.</li>
+<li>TOS_LOCAL_ADDRESS no longer exists. There is now a distinction between the local node's ID (which is TOS_NODE_ID) and the active message address. The active message address of a communication interface can be obtained through the AMPacket.localAddress() command. By default, node ID and AM address are the same. TOS_NODE_ID is bound at compile-time, while an interface's AM address can be changed at runtime.</li>
+<li>Calls such as Leds.greenToggle(), Leds.yellowToggle() etc need to be replaced by Leds.led1Toggle(), Leds.led2Toggle() etc.</li>
+<li>You should no longer use &quot;#ifdef PLATFORM_PC&quot; to separate pieces of code that are to run only on the 'pc' target. Instead, &quot;#ifdef TOSSIM&quot; is used to identify blocks of code that should be run only in TOSSIM.</li>
+<li>dbg messages no longer use one of the debug modes of the form, DBG_* as their first argument. Instead, they should be replaced with strings identifying the sources from where the messages originated.</li>
+</ol>
+</blockquote>
+</div>
+<div class="section">
+<h1><a id="author-s-address" name="author-s-address">2. Author's Address</a></h1>
+<div class="line-block">
+<div class="line">Tahir Azim</div>
+<div class="line">358 Gates Hall</div>
+<div class="line">Computer Systems Laboratory</div>
+<div class="line">Stanford University</div>
+<div class="line">Stanford, CA 94305</div>
+<div class="line"><br /></div>
+<div class="line">email - <a class="reference" href="mailto:tazim&#64;cs.stanford.edu">tazim&#64;cs.stanford.edu</a></div>
+<div class="line"><br /></div>
+<div class="line">Philip Levis</div>
+<div class="line">358 Gates Hall</div>
+<div class="line">Computer Systems Laboratory</div>
+<div class="line">Stanford University</div>
+<div class="line">Stanford, CA 94305</div>
+<div class="line"><br /></div>
+<div class="line">phone - +1 650 725 9046</div>
+<div class="line"><br /></div>
+<div class="line">email - <a class="reference" href="mailto:pal&#64;cs.stanford.edu">pal&#64;cs.stanford.edu</a></div>
+</div>
+</div>
+<div class="section">
+<h1><a id="citations" name="citations">3. Citations</a></h1>
+<table class="docutils footnote" frame="void" id="id1" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="id1">[1]</a></td><td>Rodrigo Fonseca, David Culler, Sylvia Ratnasamy, Scott Shenker, and Ion Stoica. &quot;Beacon Vector Routing: Scalable Point-to-Point Routing in Wireless Sensornets.&quot; In Proceedings of the Second USENIX/ACM Symposium on Network Systems Design and Implementation (NSDI 2005).</td></tr>
+</tbody>
+</table>
+</div>
+</div>
+</body>
+</html>
diff --git a/doc/html/tutorial/img/arbiter_pm_graph.png b/doc/html/tutorial/img/arbiter_pm_graph.png
new file mode 100644 (file)
index 0000000..0c9954b
Binary files /dev/null and b/doc/html/tutorial/img/arbiter_pm_graph.png differ
diff --git a/doc/html/tutorial/img/mviz.png b/doc/html/tutorial/img/mviz.png
new file mode 100644 (file)
index 0000000..ac9ad11
Binary files /dev/null and b/doc/html/tutorial/img/mviz.png differ
diff --git a/doc/html/tutorial/img/shared_resource_graph.png b/doc/html/tutorial/img/shared_resource_graph.png
new file mode 100644 (file)
index 0000000..a25ed7d
Binary files /dev/null and b/doc/html/tutorial/img/shared_resource_graph.png differ
diff --git a/doc/html/tutorial/lesson10.html b/doc/html/tutorial/lesson10.html
new file mode 100644 (file)
index 0000000..3c84d99
--- /dev/null
@@ -0,0 +1,556 @@
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+  <title>TinyOS Tutorial Lesson 10: Platforms</title>
+  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+
+<div class="title">Lesson 10: Platforms</div>
+<div class="subtitle">Last updated October 23 2006</div>
+
+<h1>Introduction</h1>
+
+<p>Many different hardware platforms (e.g micaZ, telos, eyesIFX) can be
+  used with TinyOS. This lesson shows you what a platform port consists
+  of, and how TinyOS reuses as much code as possible between different
+  platforms.
+  The lesson will proceed by showing how to do the port for an imaginary
+  mote called "yamp", which has a MSP430 microcontroller and a CC2420 
+  radio transceiver. 
+
+<p>
+  The <b>target audience</b> of this lesson consists of those people that want
+  to better understand what the difference between e.g "make micaz" and "make
+  telosb" is, and how these differences concretely map into the underlying
+  files, definitions, etc. 
+
+<p> Note that the material covered in this tutorial is <b>not</b>
+  strictly necessary for regular tinyos developpers, and you can safely skip
+  it if you have no intention of working down to the lowest level or
+  developping new platforms.
+
+</p>
+
+<h1>Chips vs Platforms</h1>
+
+<p>
+  Two key building blocks for any mote are the microcontroller and
+  radio transceiver. 
+  Of course, both a microcontroller and a radio can be used on 
+  more than one platform. This is indeed the case for the MSP430 and CC2420
+  that our yamp mote uses (telos, eyes, and tinynode use the MSP430; telos
+  and micaz use the CC2420).
+</p>
+
+<p>
+  Given this multiplicity of platforms, it would be vasly redundant if each
+  platform developper had to rewrite the software support for each chip
+  from scratch. While a chip may be physically wired in a different way on
+  different platforms (e.g., a radio is connected to a different digital
+  pins on the microcontroller), by far the largest part of the logic to
+  deal with a chip is platform-independent.
+</p>
+
+<p>
+  Thus, platform-independent code to support a chip is placed in a
+  chip-specific directory. Writing a platform port for a platform is then 
+  (essentially) a matter of <b>pulling in the code for each of the 
+  platform's chips, and "gluing"  things together</b>.
+  For example, the modules and components that support the CC2420 are in
+  tos/chips/cc2420. This radio is used on both the telos and micaZ motes; the
+  "gluing" is done by the modules in the tos/platforms/telosa/chips/cc2420 and
+  tos/platforms/micaz/chips/cc2420/ directories.
+</p>
+
+<p>
+  Note that in general there may
+  be more to a platform port than pulling in existing code for different
+  chips, in particular when a new platform uses a chip that is not yet
+  supported. Developping drivers for a new chip can be a non-trivial
+  undertaking (especially for radios and microcontrollers); these aspects
+  are not covered here. 
+</p>
+
+<h1>Initial platform bring-up</h1>
+
+<p>
+  As a first step to bring up the platform, we will stick to the bare minimum in
+  order to compile and install the Null application on our yamp mote. 
+</p>
+
+<p>
+  All platform-specific code goes in tos/platforms/<platformname>. 
+    For example, we have tos/platforms/micaz or tos/platforms/tinynode.
+    Our first step is to create a directory for the yamp platform:
+    <pre>
+      $ cd tinyos-2.x/tos/platforms
+      $ mkdir yamp
+    </pre>
+</p>
+
+<h2>The .platform file</h2>
+
+Each platform directory (such as tos/platforms/yamp) should contain a
+file named ".platform", that contains basic compiler parameters
+information for each platform. So, create the file
+"tos/platforms/yamp/.platform" (note the <b>.</b> in  "<b>.</b>platform" !!!), that contains the following:
+
+<pre>
+  push( @includes, qw(
+
+  %T/chips/cc2420
+  %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/power
+  ) );
+
+  @opts = qw(
+
+  -gcc=msp430-gcc
+  -mmcu=msp430x1611
+  -fnesc-target=msp430
+  -fnesc-no-debug
+  -fnesc-scheduler=TinySchedulerC,TinySchedulerC.TaskBasic,TaskBasic,TaskBasic,runTask,postTask
+
+  );
+
+</pre>
+    
+<p>
+  This file contains perl snippets that are intepreted by the ncc compiler. 
+  The first statement simply adds some directories to the include path that
+  is used when compiling an application for the yamp platform (the %T gets
+  expanded to the full location of tinyos-2.x/tos, using the TOS2DIR
+  environment variable). Note that we have included the CC2420 and MSP430
+  directories, as well as some libraries.
+</p>
+
+<p>
+  The second statement defines the @opts list, that contains various parameters
+  passed to nesc. Please consult the nesc documentation for information on the
+  meaning of these parameters.
+</p>
+
+<h2>The hardware.h file</h2>
+
+<p>
+  Each platform directory also has a file named "hardware.h" that is included by
+  default when compiling an application for that platform. This can define
+  platform-specific constants, pin names, or also include other "external"
+  header files (e.g. msp430hardware.h in our case, or atm128hardware.h for
+  platforms using the atm128 MCU).<br>
+
+  So, create the file "tos/platforms/yamp/hardware.h" with the following contents:
+</p>
+
+<pre>
+  #ifndef _H_hardware_h
+  #define _H_hardware_h
+
+  #include "msp430hardware.h"
+
+  // LEDs
+  TOSH_ASSIGN_PIN(RED_LED, 5, 4);
+  TOSH_ASSIGN_PIN(GREEN_LED, 5, 5);
+  TOSH_ASSIGN_PIN(YELLOW_LED, 5, 6);
+
+  // UART pins
+  TOSH_ASSIGN_PIN(SOMI0, 3, 2);
+  TOSH_ASSIGN_PIN(SIMO0, 3, 1);
+  TOSH_ASSIGN_PIN(UCLK0, 3, 3);
+  TOSH_ASSIGN_PIN(UTXD0, 3, 4);
+  TOSH_ASSIGN_PIN(URXD0, 3, 5);
+  TOSH_ASSIGN_PIN(UTXD1, 3, 6);
+  TOSH_ASSIGN_PIN(URXD1, 3, 7);
+  TOSH_ASSIGN_PIN(UCLK1, 5, 3);
+  TOSH_ASSIGN_PIN(SOMI1, 5, 2);
+  TOSH_ASSIGN_PIN(SIMO1, 5, 1);
+
+
+  #endif // _H_hardware_h
+</pre>
+
+<p>
+  This file simply pulls in msp430hardware.h from tos/chips/msp430 (the compiler
+  will find it because we have added this directory to our search path in the
+  .platform created previously) and defines some physical pins using macros from
+  msp430hardware.h. For example, on our yamp mote, the red led is physically
+  connected to the general purpose I/O (GPIO) pin 5.4.
+</p>
+
+<p>
+  Some other very important functions (that are defined in msp430hardware.h
+  and so pulled in indirectly via this hardware.h)
+  concern the disabling of interrupts for atomic sections (atomic blocks in nesc
+  code essentially get converted into __nesc_atomic_start() and
+  __nesc_atomic_end()). How interrupts are disabled is of course microcontroller
+  specific; the same applies to putting the microcontroller to sleep (as is done
+  by the scheduler when there are no more tasks to run, using the McuSleep
+  interface). These functions must be somehow defined for each platform, 
+  typically by means of an <tt>#include</tt>'d MCU-specific file.<br>
+<i>  As an exercise, try finding the definitions of</i> __nesc_atomic_start() <i>and
+</i>  __nesc_atomic_end()<i> for the micaZ and intelmote2 platforms.</i>
+
+</p>
+
+<h1>Setting up the build environment and building the "null" app</h1>
+Before pulling in existing chip drivers or writing any code, we must set up
+the build environment so that it is aware of and supports our platform.
+
+Once this is done, we will define the basic TinyOS module for our platform,
+and use the Null app (in tinyos-2.x/apps/null) in order to test that our
+platform is properly configured. As per it's description in its README file,
+Null is an empty skeleton application.  It is useful to test that the
+build environment is functional in its most minimal sense, i.e., you
+can correctly compile an application. So, let's go ahead and try to compile 
+Null for the yamp platform:
+
+<!-- <h2> Defining a make target</h3> -->
+
+<!-- At this point we have created all the necessary files in tos/platforms/yamp/ -->
+<!-- in order to run the Null application. But how do we compile it and install it -->
+<!-- on our yamp mote? -->
+
+<!-- We would like to enter "make yamp" in any application directory and have a -->
+<!-- yamp binary be built, just as e.g. "make micaz" builds us a micaz -->
+<!-- binary. But if we try it at this point we get an error message listing all the -->
+<!-- valid targets and telling us that yamp is not a valid target: -->
+
+<pre>
+  $ cd tinyos-2.x/apps/Null
+  $ make yamp
+/home/henridf/work/tinyos-2.x/support/make/Makerules:166: *** 
+
+Usage:  make <target> <extras>
+        make <target> help
+
+        Valid targets: all btnode3 clean eyesIFX eyesIFXv1 eyesIFXv2 intelmote2 mica2 mica2dot micaz null telos telosa telosb tinynode tmote
+        Valid extras: docs ident_flags nescDecls nowiring rpc sim sim-cygwin sim-fast tos_image verbose wiring
+
+ Welcome to the TinyOS make system!
+
+ You must specify one of the valid targets and possibly some combination of
+ the extra options.  Many targets have custom extras and extended help, so be
+ sure to try "make <target> help" to learn of all the available features.
+
+ Global extras:
+
+   docs    : compile additional nescdoc documentation
+   tinysec : compile with TinySec secure communication
+
+ERROR, "yamp tos-ident-flags tos_image" does not specify a valid target.  Stop. 
+  
+</pre>
+
+<p>
+The problem is that we need to define the platform in the <i>TinyOS build
+  system</i>, so that the make invocation above recognizes the yamp platform.
+The TinyOS build system is a Makefile-based set of rules and definitions
+that has a very rich functionality. This includes invoking
+necessary  compilation commands as with any build system, but goes much
+  further and includes support for other important aspects such as 
+device reprogramming or supporting multiple platforms and targets.
+</p>
+
+<p>
+A full description of the inner workings of the TinyOS build system is beyond
+  the scope of this tutorial. For now, we will simply see how to define the
+  yamp platform so that the "make yamp" command does what it should. (For those
+  that want to delve deeper, start with "tinyos-2.x/support/make/Makerules".)
+</p>
+
+<h2> Defining a make target</h2>
+
+The TinyOS build system resides in "tinyos-2.x/support/make". The strict
+minimum for a platform to be recognized by the build system (i.e., for the
+build system to understand that "yamp" is a legal platform when we enter "make
+yamp") is the existence of a <i>platformname</i>.target file in the
+aforementioned make directory.<br>
+So, create the file "tinyos-2.x/support/make/yamp.target" with the following
+contents:
+
+<pre>
+
+PLATFORM = yamp
+
+$(call TOSMake_include_platform,msp)
+
+yamp: $(BUILD_DEPS)
+       @:
+</pre>
+
+This sets the PLATFORM variable to yamp, includes the msp platform
+("make/msp/msp.rules") file, and provides in the last two lines a make rule
+for building a yamp application using standard Makefile syntax.
+
+Now, let's go back and try to compile the Null app as before. This time we get:
+
+<pre>
+[18:23 henridf@tinyblue: ~/work/tinyos-2.x/apps/Null] make yamp
+mkdir -p build/yamp
+    compiling NullAppC to a yamp binary
+ncc -o build/yamp/main.exe -Os -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=yamp -fnesc-cfile=build/yamp/app.c -board=   NullAppC.nc -lm 
+In file included from NullAppC.nc:42:
+In component `MainC':
+/home/henridf/work/tinyos-2.x/tos/system/MainC.nc:50: component PlatformC not found
+/home/henridf/work/tinyos-2.x/tos/system/MainC.nc:53: no match
+make: *** [exe0] Error 1
+</pre>
+
+So there's progress of sorts, since now we're getting a "real" compilation
+error as opposed to not even making it past the build system. Let's take a
+closer look at the output. The ncc compiler is unhappy about not finding a
+"PlatformC" component.
+
+The "PlatformC" component must be defined for each platform. Its role and
+placement in the system is described in more detail in TEP107. For now,
+suffice to cite from that TEP that:
+<i>A port of TinyOS to a new plaform MUST include a component PlatformC which
+  provides one and only one instance of the Init interface.</i>.
+
+
+Create the file "tos/platforms/yamp/PlatformP.nc" with the following contents:
+
+<pre>
+#include "hardware.h"
+
+module PlatformP{
+  provides interface Init;
+  uses interface Init as Msp430ClockInit;
+  uses interface Init as LedsInit;
+}
+implementation {
+  command error_t Init.init() {
+    call Msp430ClockInit.init();
+    call LedsInit.init();
+    return SUCCESS;
+  }
+
+  default command error_t LedsInit.init() { return SUCCESS; }
+
+}
+</pre>
+
+, and create the file "tos/platforms/yamp/PlatformC.nc" as:
+
+<pre>
+#include "hardware.h"
+
+configuration PlatformC
+{
+  provides interface Init;
+}
+implementation
+{
+  components PlatformP
+    , Msp430ClockC
+    ;
+
+  Init = PlatformP;
+  PlatformP.Msp430ClockInit -> Msp430ClockC.Init;
+}
+</pre>
+
+Now, compilation of the Null application finally works for the yamp platform:
+
+<pre>
+[19:47 henridf@tinyblue: ~/work/tinyos-2.x/apps/Null] make yamp
+mkdir -p build/yamp
+    compiling NullAppC to a yamp binary
+ncc -o build/yamp/main.exe -Os -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=yamp -fnesc-cfile=build/yamp/app.c -board=   NullAppC.nc -lm 
+    compiled NullAppC to build/yamp/main.exe
+            1216 bytes in ROM
+               6 bytes in RAM
+msp430-objcopy --output-target=ihex build/yamp/main.exe build/yamp/main.ihex
+    writing TOS image
+</pre>
+
+
+<h1>Getting Blink to work</h1>
+
+With the previous steps, we now have the basic foundation to start working on
+our yamp platform: the basic platform definitions are in place, and the build
+system recognizes and correctly acts upon the "make yamp" target. We haven't
+yet actually <i>programmed</i> our mote yet. 
+<p>
+The next step in the bring-up of a platform, that we will cover in this part,
+is to program a node with an application and verify that it actually
+works. We'll do this with Blink, because it is simple, and easy to verify that
+it works. As a bonus, we'll also have validated basic timer functionality once
+we see those Leds turning on and off.
+<p>
+As a first step, let's go to the Blink application directory and try to
+compile the application:
+<pre> 
+[19:06 henridf@tinyblue: ~/work/tinyos-2.x/apps/Blink] make yamp
+mkdir -p build/yamp
+    compiling BlinkAppC to a yamp binary
+ncc -o build/yamp/main.exe -Os -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=yamp -fnesc-cfile=build/yamp/app.c -board=   BlinkAppC.nc -lm 
+In file included from BlinkAppC.nc:45:
+In component `LedsC':
+/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:38: component PlatformLedsC not found
+/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:42: cannot find `Init'
+/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:43: cannot find `Led0'
+/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:44: cannot find `Led1'
+/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:45: cannot find `Led2'
+make: *** [exe0] Error 1
+</pre>
+
+The compiler cannot find the component "PlatformLedsC" that is referred to in 
+the file tos/system/LedsC.nc. As the name indicates, "PlatformLedsC" is a
+platform-specific component, and thus we will need to define this component
+for the yamp platform. 
+<p>
+Why should there be such a platform-specific component for accessing Leds?  This is because at
+the lowest level, i.e in hardware, Leds are implemented differently on
+different platforms. Typically, a Led is connected to a microcontroller I/O pin,
+and the Led is turned on/off by setting the appropriate output 0/1 on that
+pin. This is in fact the model used on all current TinyOS platforms. 
+But even in this simple and uniform model, (and disregarding
+the fact that future platforms may use different hardware implementations
+and not connect each Led directly to an I/O pin), we have that the
+lowest-level to turn on/off a Led must be defined on a per-platform basis. 
+<p> 
+Now, consider Leds from another perspective, namely that of the Leds.nc
+interface (defined in tos/interfaces/Leds.nc). In this interface, we have
+commands such as <tt>get();</tt> in principle such a command does not need to be
+platform-dependent: the code that maintains the current state of a Led and
+returns it via the get() call does not need to be re-written each time a Led
+is connected to a different pin (of course re-writing get() for each
+platform would  not be much overhead given its simplicity; this argument
+clearly becomes far stronger in more complex situations involving entire chips
+rather than individual GPIOs).
+<p> The key notion that the above example is simply that there is a boundary
+  above which software components are platform-independent, and below which
+  components are specifically written with one hardware platform in mind. 
+  This is at heart a very simple concept; its complete instantiation in TinyOS is of
+  course richer than the above example, and is the topic of TEP2 (Hardware
+  Abstraction Architecture).
+<p> Let's now return to the task at hand, which is to make Blink work on our
+  platform. If we take a closer look at the file "tos/system/LedsC.nc", we see
+  that it contains a configuration that wires the module LedsP with modules
+  Init, Leds0,  Leds1, and Leds2, all of which are to be provided by the
+  (still missing) PlatformLedsC. Taking a closer look at
+  "tos/system/LedsP.nc", we see that the Leds0,1,2 modules used by LedsP are
+  GeneralIO interfaces. The GeneralIO interface (see
+  "tos/interfaces/GeneralIO.nc" and TEP 117) simply encapsulates a digital I/O pin and
+  provides functions to control its direction and get/set its input/output
+  values. 
+<p> So, we need to create a PlatformLedsC configuration that shall provide
+  three GeneralIO interfaces and an Init. This is done by creating the file
+  "tos/platforms/yamp/PlatformLedsC.nc" with the following contents:
+
+<pre>
+#include "hardware.h"
+
+configuration PlatformLedsC {
+  provides interface GeneralIO as Led0;
+  provides interface GeneralIO as Led1;
+  provides interface GeneralIO as Led2;
+  uses interface Init;
+}
+implementation
+{
+  components 
+      HplMsp430GeneralIOC as GeneralIOC
+    , new Msp430GpioC() as Led0Impl
+    , new Msp430GpioC() as Led1Impl
+    , new Msp430GpioC() as Led2Impl
+    ;
+  components PlatformP;
+
+  Init = PlatformP.LedsInit;
+
+  Led0 = Led0Impl;
+  Led0Impl -> GeneralIOC.Port54;
+
+  Led1 = Led1Impl;
+  Led1Impl -> GeneralIOC.Port55;
+
+  Led2 = Led2Impl;
+  Led2Impl -> GeneralIOC.Port56;
+
+}
+</pre>
+
+We refer the reader to the TinyOS Programming Guide cited below for more
+explanations on how the above confiuration uses generics (ie with the "new"
+keyword). For the purpose of this lesson, the key point is that we are wiring
+to ports 5.4, 5.5, and 5.6 -- we shall suppose that these  are the MSP430 
+microcontroller pins to which the three Leds are connected on the yamp
+platform.  <p>
+
+With the above file in place, we can now compile Blink for the yamp platform. 
+How do we test that the application actually works? We have thus far presented
+yamp as an imaginary platform, but it turns out that the above application
+should work on any platform with the MSP430x1611 microcontroller and where the
+Leds are connected to microcontroller ports 5.4-5.6. 
+Not entirely coincidentally, these are exactly the Led wirings used by the
+telos/tmote platforms. So those readers that have a telos/tmote at hand can
+test this application on it. (Testing on a tinynode or eyes mote is also easy and only
+requires changing the pin wirings in PlatformLedsC to follow those of that
+platform; running this application on mica-family motes will require more
+changes since they use a different microcontroller).
+
+<p>
+Now, enter the following command (where you have suitably replaced /dev/ttyXXX by the appropriate serial port),
+<pre>
+  make yamp install bsl,/dev/ttyXXX
+</pre>
+and you will see the Leds of your impersonated (by a telos) yamp node Blinking!
+
+<h1>Conclusion</h1>
+
+<p>This lesson has introduced the notion of per-platform support in TinyOS
+  using as a guiding example the development of a platform port to an
+  imaginary "yamp" platform. We have seen how introducing support for a new
+  platform requires touching not only nesc code but also adding some rules to
+  the build system. This tutorial also touched upon the notions of Hardware
+  Abstraction Architecture (HAA) that is central to the clean and modular
+  support of different platforms and chips in TinyOS.
+<p>
+  The steps outlined here did not cover what is the hardest part of
+  a platform port: developping the components to drive a radio transceiver or
+  MCU (which are necessary if the platform uses chips that are not currently
+  supported in TinyOS). Developping such drivers is an advanced topic that is
+  beyond the scope of the tutorials; for those curious to gain some insight we
+  recommend perusing the code for a chip (e.g the CC2420 radio in
+  tos/chips/cc2420 or the xe1205 radio in tos/chips/xe1205) armed with that
+  chips datasheet and the platform schematics.
+<p>
+<a name=#related_docs>
+<h1>Related Documentation</h1>
+</a>
+<ul>
+<li> <a href="https://sourceforge.net/projects/nescc">nesc at sourceforge</a>
+<li> <a href="http://nescc.sourceforge.net/papers/nesc-ref.pdf">nesC reference manual</a>
+<li> <a href="http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf">TinyOS Programming Guide</a>
+<li> <a href="../tep102.html">TEP 2: Hardware Abstraction Architecture</a>
+<li> <a href="../tep106.html">TEP 106: Schedulers and Tasks</a>
+<li> <a href="../tep107.html">TEP 107: TinyOS 2.x Boot Sequence</a>
+<li> <a href="../tep117.html">TEP 117: Low-level I/O</a>
+</ul>
+
+<p>
+<hr>
+
+
+<!-- Begin footer -->
+<br>
+<hr>
+<center>
+<p>&lt;&nbsp;<b><a href="index.html">Top</a></b> 
+&nbsp;</b>
+</center>
+
+</body>
+</html>
diff --git a/doc/html/tutorial/lesson12.html b/doc/html/tutorial/lesson12.html
new file mode 100644 (file)
index 0000000..719e3dc
--- /dev/null
@@ -0,0 +1,206 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>TinyOS Tutorial Lesson 12: Network Protocols</title>
+  <link href="../../stylesheets/tutorial.css" rel="stylesheet"
+ type="text/css">
+</head>
+<body>
+<div class="title">Lesson 12: Network Protocols<br>
+</div>
+<div class="subtitle">Last updated Nov 3 2006</div>
+<p>This lesson introduces the two basic network primitives of Tinyos-2:
+Dissemination and Collection.<br>
+</p>
+<h1>Dissemination<br>
+</h1>
+<p>The goal of a dissemination protocol is to reliably deliver a piece of data to every
+node in the network. It allows administrators
+to reconfigure, query, and reprogram a network. Reliability is
+important because it makes the operation robust to temporary
+disconnections or high packet loss.&nbsp; Dissemination is&nbsp; fully
+explained in TEP 118.<br>
+</p>
+<p>In TinyOS 2.x, dissemination provides two interfaces: DisseminationValue and
+DisseminationUpdate. Let's take a look at these two interfaces:<br>
+</p>
+
+<p>tos/lib/net/DisseminationUpdate.nc:<br>
+</p>
+<pre>interface DisseminationUpdate&lt;t&gt; {<br>  command void change(t* newVal);<br>}</pre>
+
+<p>tos/lib/net/DisseminationValue.nc:<br>
+</p>
+<pre>interface DisseminationValue&lt;t&gt; {<br>  command const t* get();<br>  event void changed();<br>}</pre>
+<span style="font-family: monospace;"></span>
+
+<p>DisseminationUpdate is used by producers. The command <span
+ style="font-weight: bold; font-style: italic;">DisseminationUpdate.change()</span> should be
+called each time the producer wants to disseminate a new value, passing this
+ new value as a parameter.<br>
+DisseminationValue is for consumers. The event <span
+ style="font-weight: bold; font-style: italic;">DisseminationValue.changed()</span> is
+signalled each time the disseminated value is changed (the producer has
+called <span style="font-weight: bold; font-style: italic;">change</span>),
+and the command<span style="font-style: italic;"> <span
+ style="font-weight: bold;">get</span></span> allows to obtain this new
+value. <br>
+</p>
+We build now a simple application (EasyDissemination) where one node
+(the producer) periodically disseminates the value of a counter to rest
+of the nodes in the network (consumers).
+As a first step, c<code></code>reate a new directory in <tt>apps</tt>
+named <span style="font-family: monospace;">EasyDissemination</span>:
+<pre>$ cd tinyos-2.x/apps<br>$ mkdir EasyDissemination<br></pre>
+Inside this directory, create a file <code>EasyDisseminationC.nc</code>,
+which
+has this code:
+<pre>#include &lt;Timer.h&gt;<br><br>module EasyDisseminationC {<br>  uses interface Boot;<br>  uses interface DisseminationValue&lt;uint16_t&gt; as Value;<br>  uses interface DisseminationUpdate&lt;uint16_t&gt; as Update;<br>  uses interface Leds;<br>  uses interface Timer&lt;TMilli&gt;;<br>}<br><br>implementation {<br><br>  uint16_t counter;<br><br>  task void ShowCounter() {<br>    if (counter &amp; 0x1) <br>      call Leds.led0On();<br>    else <br>      call Leds.led0Off();<br>    if (counter &amp; 0x2) <br>      call Leds.led1On();<br>    else <br>      call Leds.led1Off();<br>    if (counter &amp; 0x4) <br>      call Leds.led2On();<br>    else<br>      call Leds.led2Off();<br>  }<br>  <br>  event void Boot.booted() {<br>    counter = 0;<br>    if ( TOS_NODE_ID  == 1 ) <br>      call Timer.startPeriodic(2000);<br>  }<br><br>  event void Timer.fired() {<br>    counter = counter + 1;<br>    // show counter in leds<br>    post ShowCounter();<br>    // disseminate counter value<br>    call Update.change(&amp;counter);<br>  }<br><br>  event void Value.changed() {<br>    const uint16_t* newVal = call Value.get();<br>    // show new counter in leds<br>    counter = *newVal;<br>    post ShowCounter();<br>  }<br>}<br></pre>
+We assume that the&nbsp; base station is the node with ID = 1. First
+note that the base station will periodically (every 2 seconds)
+increment a 3-bit counter, display the counter using its three leds,&nbsp; and disseminate it
+through the network. This is done using the change command provided in
+the DisseminationUpdate interface:<br>
+<pre>    call Update.change(&amp;counter);</pre>
+Second, note that when a node receives a change notification, it
+updates its counter value and shows it on the leds:<br>
+<pre>  event void Value.changed() {<br>    const uint16_t* newVal = call Value.get();<br>    // show new counter in leds<br>    counter = *newVal;<br>    post ShowCounter();<br>  }<br></pre>
+The <code>EasyDisseminationAppC.nc</code>
+provides the needed wiring:
+<pre>configuration EasyDisseminationAppC {}<br>implementation {<br>  components EasyDisseminationC;<br><br>  components MainC;<br>  EasyDisseminationC.Boot -&gt; MainC;<br><br>  components new DisseminatorC(uint16_t, 0x1234) as Diss16C;<br>  EasyDisseminationC.Value -&gt; Diss16C;<br>  EasyDisseminationC.Update -&gt; Diss16C;<br><br>  components LedsC;<br>  EasyDisseminationC.Leds -&gt; LedsC;<br><br>  components new TimerMilliC();<br>  EasyDisseminationC.Timer -&gt; TimerMilliC;<br>}<br></pre>
+<p>Note that both Dissemination interfaces we use are provided by the
+module DisseminatorC. <br>
+This module provides&nbsp; the Dissemination service:<br>
+</p>
+<p>tos/lib/net/Dissemination/DisseminationC.nc:</p>
+<prehead></prehead>
+<pre> generic configuration DisseminatorC(typedef t, uint16_t key) {<br>  provides interface DisseminationValue&lt;t&gt;;<br>  provides interface DisseminationUpdate&lt;t&gt;;<br>}<br></pre>
+Note that we need to specify to the Disseminartor module a type t and a
+key.&nbsp; In our case, the value we&nbsp; want to&nbsp; disseminate is
+just an unsigned&nbsp; two-byte counter. The key allows to have
+different instances of DisseminatroC. <br>
+<br>
+To compile this program we use create the following Makefile:<br>
+<pre>COMPONENT=EasyDisseminationAppC<br>CFLAGS += -I$(TOSDIR)/lib/net<br><br>include $(MAKERULES)<br></pre>
+Now install this program into several nodes (make sure you have one
+base station, that is, one node whose ID is 1) and see how the counter
+displayed in the base station is "disseminated" to all the nodes
+belonging to the network. You will also notice that dissemination works across
+resets, i.e., if you reset a node it will rapidly re-'synchronize' and display
+the correct value after it reboots.
+<br>
+<br>
+For more information, read TEP118 [Dissemination].<br>
+<br>
+<h1>Collection<br>
+</h1>
+<p>Collection is the complementary operation to disseminating and it
+consists in "collecting" the data generated in the network into a base
+stations. The general approach used is to build one
+or more collection <em>trees</em>, each of which is rooted at a base
+station. When a node has data which needs to be collected, it
+sends the data up the tree, and it forwards collection data that
+other nodes send to it. <br>
+</p>
+<p>We build now a simple application (EasyCollection) where nodes
+periodically send information to a base station which collects all the
+data.<br>
+As a first step, c<code></code>reate a new directory in <tt>apps</tt>
+named <span style="font-family: monospace;">EasyCollection</span>:
+</p>
+<pre>$ cd tinyos-2.x/apps<br>$ mkdir EasyCollection<br></pre>
+Inside this directory, create a file <code>EasyCollectionC.nc</code>,
+which
+has the following code:
+<pre>#include &lt;Timer.h&gt;<br><br>module EasyCollectionC {<br>  uses interface Boot;<br>  uses interface SplitControl as RadioControl;<br>  uses interface StdControl as RoutingControl;<br>  uses interface Send;<br>  uses interface Leds;<br>  uses interface Timer&lt;TMilli&gt;;<br>  uses interface RootControl;<br>  uses interface Receive;<br>}<br>implementation {<br>  message_t packet;<br>  bool sendBusy = FALSE;<br><br>  typedef nx_struct EasyCollectionMsg {<br>    nx_uint16_t data;<br>  } EasyCollectionMsg;<br><br>  event void Boot.booted() {<br>    call RadioControl.start();<br>  }<br>  <br>  event void RadioControl.startDone(error_t err) {<br>    if (err != SUCCESS)<br>      call RadioControl.start();<br>    else {<br>      call RoutingControl.start();<br>      if (TOS_NODE_ID == 1) <br>   call RootControl.setRoot();<br>      else<br>   call Timer.startPeriodic(2000);<br>    }<br>  }<br><br>  event void RadioControl.stopDone(error_t err) {}<br><br>  void sendMessage() {<br>    EasyCollectionMsg* msg = (EasyCollectionMsg*)call Send.getPayload(&amp;packet);<br>    msg-&gt;data = 0xAAAA;<br>    <br>    if (call Send.send(&amp;packet, sizeof(EasyCollectionMsg)) != SUCCESS) <br>      call Leds.led0On();<br>    else <br>      sendBusy = TRUE;<br>  }<br>  event void Timer.fired() {<br>    call Leds.led2Toggle();<br>    if (!sendBusy)<br>      sendMessage();<br>  }<br>  <br>  event void Send.sendDone(message_t* m, error_t err) {<br>    if (err != SUCCESS) <br>      call Leds.led0On();<br>    sendBusy = FALSE;<br>  }<br>  <br>  event message_t* <br>  Receive.receive(message_t* msg, void* payload, uint8_t len) {<br>    call Leds.led1Toggle();    <br>    return msg;<br>  }<br>}<br></pre>
+<p>&nbsp;Lets take a look at this program. First note that all nodes
+turn on the radio into the Boot sequence:<br>
+</p>
+<p></p>
+<pre>&nbsp; event void Boot.booted() {<br>&nbsp;&nbsp;&nbsp; call RadioControl.start();<br>&nbsp; }</pre>
+<p>Once we are sure that the radio is on, we start the routing sub-system
+(that
+is, to generate the collection <span style="font-style: italic;">tree</span>):<br>
+</p>
+<pre>call RoutingControl.start();</pre>
+Next we need need to specify the root of the collection tree, that is,
+the node that will receive all the data packets. For this, we use the
+interface RootControl:<br>
+tos/lib/net/RootControl.nc<br>
+<pre>interface RootControl {<br>    command error_t setRoot();<br>    command error_t unsetRoot();<br>    command bool isRoot();<br>}<br></pre>
+<p>This interface controls whether the current node is a root of the
+tree. Using the setRoot() command and assuming that the base station ID
+is 1, we select the root of the collection <span
+ style="font-style: italic;">tree</span> as follows:<br>
+</p>
+<pre>if (TOS_NODE_ID == 1) <br>&nbsp;&nbsp;&nbsp; call RootControl.setRoot();  <br>else<br>    call Timer.startPeriodic(2000);</pre>
+<p>The remaining nodes in the network periodically generate some data
+and send it to the base station.&nbsp; To send and receive data we use
+two interfaces that will be wired to the collection tree. That is, when
+we call the send command, the data packet will be sent through the
+collection tree.&nbsp; Similarly, the receive event will be only called
+in the root of the tree, that is, in the base station. When the base
+station receives a "collected" packet it just toggle a led.&nbsp; Now
+we will see how to wire these interfaces .<br>
+The <code>EasyCollectionAppC.nc</code>
+provides the needed wiring:<br>
+</p>
+<pre>configuration EasyCollectionAppC {}<br>implementation {<br>  components EasyCollectionC, MainC, LedsC, ActiveMessageC;<br>  components CollectionC as Collector;<br>  components new CollectionSenderC(0xee);<br>  components new TimerMilliC();<br><br>  EasyCollectionC.Boot -&gt; MainC;<br>  EasyCollectionC.RadioControl -&gt; ActiveMessageC;<br>  EasyCollectionC.RoutingControl -&gt; Collector;<br>  EasyCollectionC.Leds -&gt; LedsC;<br>  EasyCollectionC.Timer -&gt; TimerMilliC;<br>  EasyCollectionC.Send -&gt; CollectionSenderC;<br>  EasyCollectionC.RootControl -&gt; Collector;<br>  EasyCollectionC.Receive -&gt; Collector.Receive[0xee];<br>}<br></pre>
+<p>Most of the collection interfaces (RoutingControl, RootControl and
+Receive) are provided by the CollectionC module.&nbsp; The send
+interface is provided by CollectionSenderC which is
+a&nbsp; virtualized collection sender abstraction module.<br>
+This is an extract of the signature of the CollectionC module and
+CollectionSenderC:<br>
+tos/lib/net/ctp/CollectionC.nc<br>
+</p>
+<pre>configuration CollectionC {<br>  provides {<br>    interface StdControl;<br>    interface Send[uint8_t client];<br>    interface Receive[collection_id_t id];<br>    interface Receive as Snoop[collection_id_t];<br>    interface Intercept[collection_id_t id];<br><br>    interface Packet;<br>    interface CollectionPacket;<br>    interface CtpPacket;<br><br>    interface CtpInfo;<br>    interface CtpCongestion;<br>    interface RootControl;    <br>  }<br></pre>
+<p>tos/lib/net/ctp/CollectionSenderC:<br>
+</p>
+<pre>  generic configuration CollectionSenderC(collection_id_t collectid) {<br>&nbsp; provides {<br>&nbsp;&nbsp;&nbsp; interface Send;<br>&nbsp;&nbsp;&nbsp; interface Packet;<br>&nbsp; }</pre>
+<p>Note that the sender and receive interfaces requires a
+collection_id_t to differentiate different possible collections trees. <br>
+Note also that the CollectionC module provides some other
+interfaces in addition to the ones used in this example. As we explained
+previously, the CollectionC module generates a collection tree that
+will be using for
+the routing. These interfaces can be used get information or modify
+this routing tree. For instance, if we want to obtain information about
+this tree we use
+the CtpInfo interface&nbsp; (see tos/lib/net/ctp/CtpInfo.nc) and if we
+want to indicate/query if any node/sink is congested we use the
+CtpCongestion interface (see tos/lib/net/ctp/CtpCongestion.nc)<br>
+</p>
+<p>Finally, to compile this program we create the following
+Makefile:<br>
+</p>
+<pre>COMPONENT=EasyCollectionAppC<br>CFLAGS += -I$(TOSDIR)/lib/net \<br>          -I$(TOSDIR)/lib/net/le \<br>          -I$(TOSDIR)/lib/net/ctp<br>include $(MAKERULES)<br></pre>
+Now install this program into several nodes (make sure you have one
+base station, that is, one node whose ID is 1) and see how all the
+packets generated in the nodes are collected in the base station.<br>
+<br>
+For more information, read TEP119&nbsp; [Collection].<br>
+<br>
+<h1>To experiment further <br>
+</h1>
+If you want to experiment with a more complex application take a look
+at apps/test/TestNetwork/ which combines dissemination and collection
+into a single application.<br>
+<br>
+<h1>Related Documentation</h1>
+<ul>
+  <li><a href="../tep108.html">TEP 118: Dissemination</a></li>
+  <li><a href="../tep119.html">TEP 119: Collection</a><br>
+  </li>
+</ul>
+<p>
+</p>
+<hr><br>
+<center>
+<p>&lt;&nbsp;<b><a href="lesson1.html">Previous Lesson</a></b> |&nbsp; <b><a
+ href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson3.html">Next
+Lesson </a>&nbsp;&gt;</b>
+</p>
+</center>
+</body>
+</html>
diff --git a/doc/html/tutorial/lesson13.html b/doc/html/tutorial/lesson13.html
new file mode 100644 (file)
index 0000000..5499a5d
--- /dev/null
@@ -0,0 +1,379 @@
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+  <title>TinyOS Tutorial Lesson 13: TinyOS Toolchain</title>
+  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+
+<div class="title">Lesson 13: TinyOS Toolchain</div>
+<div class="subtitle">Last updated October 29 2006</div>
+    
+<p> This lesson describes the details of the TinyOS toolchain, including
+the build system, how to create your own Makefile, and how to find out
+more information on the various tools included with TinyOS.
+
+<h1>TinyOS Build System</h1>
+
+As you saw in <a href="lesson1.html">Lesson 1</a>, TinyOS applications
+are built using a somewhat unconventional application of the 
+<i>make</i> tool. For instance, in the <code>apps/Blink</code> directory,
+
+<pre>$ make mica2
+</pre>
+
+compiles Blink for the mica2 platform,
+
+<pre>$ make mica2 install
+</pre>
+
+compiles and installs (using the default parallel port programmer) Blink
+for the mica2, and
+
+<pre>$ make mica2 reinstall mib510,/dev/ttyS0
+</pre>
+
+installs the previously compiled mica2 version of Blink using the MIB510
+serial port programmer connected to serial port /dev/ttyS0.
+
+<p>
+As these examples show, the TinyOS build system is controlled by passing
+arguments to make that specify the target platform, the desired action, 
+and various options. These arguments can be categorised as follows:
+
+<ul>
+<li>Target platform: one of the supported TinyOS platforms, e.g., <b>mica2</b>,
+<b>telosb</b>, <b>tinynode</b>. A target platform is always required,
+except when using the <b>clean</b> action.<p>
+
+<li>Action: the action to perform. By default, the action is to compile
+the application in the current directory, but you can also specify:
+
+  <ul>
+  <li> <b>help</b>: display a help message for the target platform.
+  <li> <b>install,<i>N</i></b>: compile and install. The <i>N</i> argument
+       is optional and specifies the mote id (default 1).
+  <li> <b>reinstall,<i>N</i></b>: install only (fails if the application wasn't previously compiled). <i>N</i> is as for <b>install</b>.
+  <li> <b>clean</b>: remove compiled application for all platforms.
+  <li> <b>sim</b>: compile for the simulation environment for the specified platform (see <a href="lesson11.html">Lesson 11</a> for details).
+  </ul>
+
+  Example: to compile for simulation for the micaz:
+  <pre>$ make micaz sim</pre>
+
+<li>Compilation option: you can change the way compilation proceeds by
+specifying:
+  <ul>
+  <li> <b>debug</b>: compile for debugging. This enables debugging, and
+       turns off optimisations (e.g., inlining) that make debugging
+       difficult.
+  <li> <b>debugopt</b>: compile for debugging, but leave optimisations
+       enabled. This can be necessary if compiling with <b>debug</b>
+       gives code that is too slow, or if the bug only shows up when
+       optimisation is enabled.
+  <li> <b>verbose</b>: enable a lot of extra output, showing all commands
+       executed by <i>make</i> and the details of the nesC compilation
+       including the full path of all files loaded. This can be helpful
+       in tracking down problems (e.g., when the wrong version of a
+       component is loaded).
+  <li> <b>wiring</b>, <b>nowiring</b>: enable or disable the use of
+       the nescc-wiring to check the wiring annotations in a nesC
+       program. See the nescc-wiring man page for more details.
+  </ul>
+
+  Example: to do a verbose compilation with debugging on the telosb:
+  <pre>$ make debug verbose telosb</pre>
+
+  <p>Additionally, you can pass additional compilation options by
+  setting the CFLAGS environment variable when you invoke make. For instance, 
+  to compile <code>apps/RadioCountoToLeds</code> for a mica2 with
+  a 900MHz radio set to ~916.5MHz, you would do:
+
+  <pre>$ env CFLAGS="-DCC1K_DEF_FREQ=916534800" make mica2 </pre>
+
+  Note that this will not work with applications whose Makefile 
+  defines CFLAGS (but this practice is discouraged, see the section
+  on <a href="#makefile">writing Makefiles</a> below).<p>
+
+<li>Installation option: some platforms have multiple programmers, and
+some programmers require options (e.g., to specify which serial port
+to use). The programmer is specified by including its name amongst the
+<i>make</i> arguments. Known programmers include <b>bsl</b> for
+msp430-based platforms and <b>avrisp</b> (STK500), <b>dapa</b> (MIB500
+and earlier), <b>mib510</b> (MIB510) and <b>eprb</b> (MIB600) for mica
+family motes.
+
+<p>Arguments to the programmer are specified with a comma after the
+programmer name, e.g.,
+
+<pre>$ make mica2dot reinstall mib510,/dev/ttyUSB1 </pre>
+<pre>$ make telosb reinstall bsl,/dev/ttyUSB1 </pre>
+
+to specify that the programmer is connected to serial port /dev/ttyUSB1.
+
+<p>More details on the programmers and their options can be found in
+your mote documentation.
+
+</ul>
+
+<h1>Customising the Build System</h1>
+
+You may find that you are often specifying the same options, e.g., that
+your mib510 programmer is always connected to /dev/ttyS1 or that you
+want to use channel 12 of the CC2420 radio rather than the default
+TinyOS 2 channel (26). To do this, put the following lines
+
+<pre>
+MIB510 ?= /dev/ttyS1
+PFLAGS = -DCC2420_DEF_CHANNEL=12
+</pre>
+in a file called <code>Makelocal</code> in the <code>support/make</code>
+directory. If you now compile in <code>apps/RadioCountToLeds</code>, you
+will see:
+<pre>
+$ make micaz install mib510
+    compiling RadioCountToLedsAppC to a micaz binary
+ncc -o build/micaz/main.exe -Os <b>-DCC2420_DEF_CHANNEL=12</b> ... RadioCountToLedsAppC.nc -lm
+    compiled RadioCountToLedsAppC to build/micaz/main.exe
+    ...
+    installing micaz binary using mib510
+uisp -dprog=mib510 <b>-dserial=/dev/ttyS1</b> ...
+</pre>
+
+The definition of <code>PFLAGS</code> passes an option to the nesC
+compiler telling it to define the C preprocessor symbol
+<code>CC2420_DEF_CHANNEL</code> to 12. The CC2420 radio stack checks
+the value of this symbol when setting its default channel.
+
+<p>The definition of <code>MIB510</code> sets the value of the
+argument to the <b>mib510</b> installation option, i.e.,
+<pre>$ make micaz install mib510 </pre>
+is now equivalent to
+<pre>$ make micaz install mib510,/dev/ttyS1 </pre>
+
+Note that the assignment to MIB510 was written using the <code>?=</code>
+operator. If you just use regular assignment (<code>=</code>), then the
+value in <code>Makelocal</code> will override any value you specify
+on the command line (which is probably not what you want...).
+
+<p><code>Makelocal</code> can contain definitions for any <i>make</i>
+variables used by the build system. Unless you understand the details of
+how this works, we recommend you restrict yourselves to defining:
+
+  <ul>
+  <li> <code>PFLAGS</code>: extra options to pass to the nesC compiler. Most
+       often used to define preprocessor symbols as seen above.
+  <li> <code><i>X</i></code>: set the argument for <i>make</i> argument <i>
+       x</i>, e.g., <code>MIB510</code> as seen above. You can, e.g., set the 
+       default mote id to 12 by adding <code>INSTALL ?= 12</code> and 
+       <code>REINSTALL ?= 12</code> to <code>Makelocal</code>.
+  </ul>
+
+<p>Some useful preprocessor symbols that you can define with 
+<code>PFLAGS</code> include:
+  <ul>
+  <li> DEFINED_TOS_AM_ADDRESS: the motes group id (default is 0x22).
+  <li> CC2420_DEF_CHANNEL: CC2420 channel (default is 26).
+  <li> CC1K_DEF_FREQ: CC1000 frequency (default is 434.845MHz).
+  <li> TOSH_DATA_LENGTH: radio packet payload length (default 28).
+  </ul>
+<p>
+
+<a name="makefile">
+<h1>Application Makefiles</h1>
+</a>
+
+To use the build system with your application, you must create a makefile
+(a file called <code>Makefile</code>) which contains at the minimum:
+
+<pre>
+COMPONENT=<i>TopLevelComponent</i>
+include $(MAKERULES)
+</pre>
+where <i>TopLevelComponent</i> is the name of the top-level component
+of your application.
+
+<p>TinyOS applications commonly also need to specify some options to the
+nesC compiler, and build some extra files alongside the TinyOS
+application. We will see examples of both, by looking at, and making a
+small change to, the <code>apps/RadioCountToLeds</code> application.
+
+<p>The RadioCountToLeds Makefile uses <code>mig</code> (see <a
+href="lesson4.html">Lesson 4</a>) to build files describing the layout
+of its messages, for use with python and Java tools:
+
+<pre>
+COMPONENT=RadioCountToLedsAppC
+<b>BUILD_EXTRA_DEPS = RadioCountMsg.py RadioCountMsg.class</b>
+
+RadioCountMsg.py: RadioCountToLeds.h
+       mig python -target=$(PLATFORM) $(CFLAGS) -python-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o $@
+
+RadioCountMsg.class: RadioCountMsg.java
+       javac RadioCountMsg.java
+
+RadioCountMsg.java: RadioCountToLeds.h
+       mig java -target=$(PLATFORM) $(CFLAGS) -java-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o $@
+
+include $(MAKERULES)
+</pre>
+
+The first and last line of this Makefile are the basic lines present in
+all TinyOS Makefiles; the line in bold defining BUILD_EXTRA_DEPS
+specifies some additional <i>make</i> targets to build alongside the
+main TinyOS application (if you are not familiar with make, this may be a
+good time to read a make tutorial, e.g., <a
+href="http://oucsace.cs.ohiou.edu/~bhumphre/makefile.html">this
+one</a>).
+
+<p>When you compile RadioCountToLeds for the first time, you will see that
+the two extra targets, <code>RadioCountMsg.py</code> and 
+<code>RadioCountMsg.class</code>, are automatically created:
+<pre>
+$ make mica2
+mkdir -p build/mica2
+mig python -target=mica2  -python-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o RadioCountMsg.py
+mig java -target=mica2  -java-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o RadioCountMsg.java
+javac RadioCountMsg.java
+    compiling RadioCountToLedsAppC to a mica2 binary
+    ...
+</pre>
+
+As this Makefile is written, these generated files are not deleted when
+you execute <code>make clean</code>. Fix this by adding the following line:
+<pre>
+CLEAN_EXTRA = $(BUILD_EXTRA_DEPS) RadioCountMsg.java
+</pre>
+to <code>apps/RadioCountToLeds/Makefile</code>. This defines the CLEAN_EXTRA
+make variable to be the same as BUILD_EXTRA_DEPS, with RadioCountMsg.java
+added to the end. The build system's <b>clean</b> target deletes all files
+in CLEAN_EXTRA:
+<pre>
+$ make clean
+rm -rf build RadioCountMsg.py RadioCountMsg.class RadioCountMsg.java
+rm -rf _TOSSIMmodule.so TOSSIM.pyc TOSSIM.py
+</pre>
+
+Finally, to see how to pass options to the nesC compiler, we will change
+RadioCountToLeds's source code to set the message sending period based
+on the preprocessor symbol <code>SEND_PERIOD</code>. Change the line in
+<code>RadioCountToLedsC.nc</code> that reads
+<pre> call MilliTimer.startPeriodic(1000);</pre>
+to
+<pre> call MilliTimer.startPeriodic(SEND_PERIOD);</pre>
+and add the following line to RadioCountToLeds's Makefile:
+<pre>
+CFLAGS += -DSEND_PERIOD=2000
+</pre>
+Note the use of <code>+=</code> when defining CFLAGS: this allows the user
+to also pass options to nesC when invoking make as we saw above (<code>env CFLAGS=x make ...</code>). 
+
+<p>Now compiling RadioCountToLeds gives:
+<pre>
+$ make mica2
+    ...
+    compiling RadioCountToLedsAppC to a mica2 binary
+ncc -o build/mica2/main.exe ... <b>-DSEND_PERIOD=2000</b> ... RadioCountToLedsAppC.nc -lm
+    compiled RadioCountToLedsAppC to build/mica2/main.exe
+    ...
+</pre>
+
+<h1>TinyOS Tools</h1>
+
+The TinyOS build system is designed to make it easier to write Makefiles
+for applications that support multiple platforms, programmers, etc in
+a uniform way. However, it's use is not compulsory, and all the tools it
+is built on can be used in your own build system (e.g., your own Makefile
+or simple build script). Below we show how to build and install the
+RadioCountToLeds application for a micaz with the mib510 programmer
+using just a few commands.
+
+<p>First, we compile RadioCountToLedsAppC.nc (the main component of
+the application) using the nesC compiler, ncc:
+<pre>
+$ ncc -target=micaz -o rcl.exe -Os -finline-limit=100000 -Wnesc-all -Wall RadioCountToLedsAppC.nc
+</pre>
+
+This generates an executable file, <code>rcl.exe</code>. Next, we want
+to install this program on a mote with mote id 15. First, we create a
+new executable, <code>rcl.exe-15</code>, where the variables storing the
+mote's identity are changed to 15, using the
+<code>tos-set-symbols</code> command:
+<pre>
+$ tos-set-symbols rcl.exe rcl.exe-15 TOS_NODE_ID=15 ActiveMessageAddressC\$addr=15
+</pre>
+
+Finally, we install this executable on the micaz using <code>uisp</code>, 
+to a mib510 programmer connected to port /dev/ttyUSB1:
+<pre>$ uisp -dpart=ATmega128 -dprog=mib510 -dserial=/dev/ttyUSB1 --erase --upload if=rcl.exe-15
+Firmware Version: 2.1
+Atmel AVR ATmega128 is found.
+Uploading: flash
+</pre>
+
+If you wish to follow this route, note two things: first, you can find out
+what commands the build system is executing by passing the <code>-n</code>
+option to make, which tells it to print rather than execute commands:
+<pre>
+$ make -n micaz install.15 mib510
+mkdir -p build/micaz
+echo "    compiling RadioCountToLedsAppC to a micaz binary"
+ncc -o build/micaz/main.exe -Os -finline-limit=100000 -Wall -Wshadow -Wnesc-all -target=micaz -fnesc-cfile=build/micaz/app.c -board=micasb  -fnesc-dump=wiring -fnesc-dump='interfaces(!abstract())' -fnesc-dump='referenced(interfacedefs, components)' -fnesc-dumpfile=build/micaz/wiring-check.xml RadioCountToLedsAppC.nc -lm
+nescc-wiring build/micaz/wiring-check.xml
+...
+</pre>
+
+Second, all the commands invoked by the build system should have man pages
+describing their behaviour and options. For instance, try the following
+commands:
+<pre>
+$ man tos-set-symbols
+$ man ncc
+$ man nescc
+</pre>
+    
+<h1>Related Documentation</h1>
+</a>
+<ul>
+<li> mica mote Getting Started Guide at <a href="http://www.xbow.com">Crossbow</a>
+<li> telos mote Getting Started Guide for <a href="http://www.moteiv.com">Moteiv</a>
+<li> <a href="lesson1.html">Lesson 1</a> introduced the build system.
+<li> <a href="lesson10.html">Lesson 10</a> describes how to add a new platform
+to the build system.
+<li> GNU make man page.
+<li> man pages for the nesC compiler (man ncc, man nescc) and the various
+TinyOS tools.
+</ul>
+
+<!-- Begin footer -->
+<br>
+<hr>
+<center>
+<p>
+<b>&lt;&nbsp;<a href="lesson12.html">Previous Lesson </a></b>
+&nbsp;|&nbsp; 
+<b><a href="index.html">Top</a>&nbsp;&gt;</b> 
+</center>
+
+</body>
+</html>
+
+<!--  LocalWords:  toolchain mib telosb tinynode sim micaz inlining debugopt nc
+ -->
+<!--  LocalWords:  nowiring nescc CFLAGS env DCC practice bsl msp avrisp STK lm
+ -->
+<!--  LocalWords:  dapa eprb PFLAGS RadioCountToLedsAppC ncc uisp dprog dserial
+ -->
+<!--  LocalWords:  TOS TOSH TopLevelComponent MAKERULES RadioCountToLeds DEPS
+ -->
+<!--  LocalWords:  RadioCountMsg py mig classname java javac mkdir rf TOSSIM
+ -->
+<!--  LocalWords:  TOSSIMmodule pyc RadioCountToLeds's MilliTimer startPeriodic
+ -->
+<!--  LocalWords:  DSEND rcl exe finline Wnesc tos ActiveMessageAddressC addr
+ -->
+<!--  LocalWords:  dpart ATmega Atmel AVR Wshadow fnesc cfile micasb dumpfile
+ -->
+<!--  LocalWords:  interfacedefs telos Moteiv
+ -->
diff --git a/doc/html/tutorial/lesson7.html b/doc/html/tutorial/lesson7.html
new file mode 100644 (file)
index 0000000..eb58f15
--- /dev/null
@@ -0,0 +1,380 @@
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+  <title>Lesson 7: Permanent Data Storage</title>
+  <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+
+<div class="title">Lesson 7: Permanent Data Storage</div>
+<div class="subtitle">Last Modified: November 5, 2006</div>
+
+<p>This lesson introduces permanent (non-volatile) data storage in
+TinyOS.  Permanent storage allows a node to persist data even if power
+is disconnected or the node is reprogrammed with a new image.  You
+will become familar with different kinds of data storage including
+small objects, logs, and large objects.  You will be exposed to the
+TinyOS interfaces and components that support permanent data storage
+on motes and you will learn how to:
+
+<p>
+
+<ul>
+
+<li>Divide the flash chip into volumes, which allows multiple and/or
+different type of data to be stored.
+
+<li>Store configuration data that survives a power cycle.
+
+<li>Provide a link to example code using the logging abstraction.
+
+<li>Provide a link to example code use large objects storage in
+non-volatile flash.
+
+</ul>
+
+
+<h1>Introduction</h1>
+
+TinyOS 2.x provides three basic storage abstractions: small objects,
+circular logs, and large objects.  TinyOS 2.x also provides
+<i>interfaces</i> to abstract the underlying storage services and
+<i>components</i> that <i>provide</i> (implement) these interfaces.
+
+<h2>Interfaces</h2>
+
+Let's take a look at some of the interfaces that are in the
+<code>tos/interfaces</code> directory to familiarize ourselves with
+the general functionality of the storage system:
+
+
+<p>
+<ul>
+
+<li><code>
+<a href="../../../tos/interfaces/BlockRead.nc">BlockRead</a></code> 
+
+<li><code>
+<a href="../../../tos/interfaces/BlockWrite.nc">BlockWrite</a></code>
+
+<li><code>
+<a href="../../../tos/interfaces/Mount.nc">Mount</a></code>
+
+<li><code>
+<a href="../../../tos/interfaces/ConfigStorage.nc">ConfigStorage</a></code>
+
+<li><code>
+<a href="../../../tos/interfaces/LogRead.nc">LogRead</a></code>
+
+<li><code>
+<a href="../../../tos/interfaces/LogWrite.nc">LogWrite</a></code>
+
+
+</ul>
+
+<h2>Components</h2>
+
+<p>Components provide concrete implementations of the interfaces.  You
+should be familiar with these components because your code needs to
+specify both the <i>interfaces</i> your application
+<i>uses</i> as well as the <i>components</i> which <i>provide</i>
+(implement) these interfaces:
+
+<p>
+<ul>
+
+<li><code><a href="../../../tos/chips/stm25p/ConfigStorageC.nc">ConfigStorageC</a></code>
+
+<li><code><a href="../../../tos/chips/stm25p/LogStorageC.nc">LogStorageC</a></code>
+
+<li><code><a href="../../../tos/chips/stm25p/BlockStorageC.nc">BlockStorageC</a></code>
+
+</ul>
+
+<p>
+
+<h2>Naming Wrappers</h2>
+
+<p>The preceding components are actually <em>naming wrappers</em>.
+Since TinyOS supports multiple platforms, each of which might have its
+own implementation of the storage drivers, platform-specific naming
+wrappers are used to bridge the general storage interfaces to their
+underlying, platform-specific implementations.
+
+<p>For example, the preceding links are all specific to the ST
+Microelectronics M25Pxx family of flash memories used in the Telos and
+Tmote Sky motes.  You <em>do not</em> need to worry about the details
+of where these files reside because TinyOS's make system includes the
+correct drivers automatically.  However, you <em>do</em> need to know
+what these components are called because your code must list them in a
+<code>components</code> declaration.
+
+<p>If you are curious, the following links will let you browse the
+naming wrappers for the Atmel AT45DB family of flash memories used in
+the Mica2/MicaZ motes:
+
+<p>
+<ul>
+
+<li><code><a href="../../../tos/chips/at45db/ConfigStorageC.nc">ConfigStorageC</a></code>
+
+<li><code><a href="../../../tos/chips/at45db/LogStorageC.nc">LogStorageC</a></code>
+
+<li><code><a href="../../../tos/chips/at45db/BlockStorageC.nc">BlockStorageC</a></code>
+
+</ul>
+
+<p>Finally, the following links will let you browse the naming
+wrappers for the Intel imote2 flash memory:
+
+<p>
+<ul>
+
+<li><code><a href="../../../tos/platforms/intelmote2/ConfigStorageC.nc">ConfigStorageC</a></code>
+
+<li><code><a href="../../../tos/platforms/intelmote2/LogStorageC.nc">LogStorageC</a></code>
+
+<li><code><a href="../../../tos/platforms/intelmote2/BlockStorageC.nc">BlockStorageC</a></code>
+
+</ul>
+
+
+<h1>Volumes</h1>
+
+<p>TinyOS 2.x divides a flash chip into one or more fixed-sized
+<em>volume</em>s that are specified at compile-time using an XML file.
+This file, called the volume table, allows the application developer
+to specify the name, size, and (optionally) the base address of each
+volume in the flash.  Each volume provides a single type of storage
+abstraction (e.g. configuration, log, or block storage).  The
+abstraction type defines the physical layout of data on the flash
+memory.  A volume table might look like:
+
+<pre>
+&lt;volume_table&gt;
+  &lt;volume name="CONFIGLOG" size="65536"/&gt;
+  &lt;volume name="PACKETLOG" size="65536"/&gt;
+  &lt;volume name="SENSORLOG" size="131072"/&gt;
+  &lt;volume name="CAMERALOG" size="524288"/&gt;
+&lt;/volume_table&gt;
+</pre>
+
+<p>The volume table for a particular application must be placed in the
+application's directory (where one types 'make') and must be named
+<code>volumes-CHIPNAME.xml</code> where CHIPNAME is replaced with the
+platform-specific flash chip's name.  For example, the Telos mote uses
+the ST Microelectronics M25P family of flash memories.  The drivers
+for these chips can be found in the <code>tos/chips/stm25p</code>
+directory.  Therefore, a Telos-based application that uses the storage
+abstractions needs a file named <code>volumes-stm25p.xml</code>.
+
+<p>Note that the size parameter is a multiple of the erase unit for a
+particular flash chip.  See Section 4.1 in <a href="#fn1">TEP 103</a>
+for more details.
+
+<h1>Storing Configuration Data</h1>
+
+<p>In <a name="fn2"><a href="lesson3.html">Lesson 3</a></a>, we
+implemented a simple application called BlinkToRadio that used a
+single timer, set to fire at a fixed rate, to toggle the LEDs.
+
+<p>See <a href="../../../apps/tutorials/BlinkConfig/">
+<code>tinyos-2.x/apps/tutorials/BlinkConfig/</code></a> for the
+accompanying code.
+
+<p>This lesson shows how parameters, like the timer period, can be
+configured at runtime and persisted across node power cycles.  The
+ability to store configuration data is useful in many applications.
+For example, it may be necessary to store a node's coordinates which
+are only known after the node is deployed.  Let's walk through the
+steps to use the <code>ConfigStorage</code> abstraction:
+
+<ol>
+
+<li>Create a <code>volumes-CHIPNAME.xml</code> file, enter the volume
+table in this file, and place the file in the application directory.
+Note that <code>CHIPNAME</code> is the flash chip used on your target
+plaform.  For example, <code>CHIPNAME</code> will be
+<code>stm25p</code> for the Telos platform and <code>at45db</code> for
+the MicaZ platform.  Our file will have the following contents:
+
+<pre>
+&lt;volume_table&gt;
+  &lt;volume name="LOGTEST" size="262144"/&gt;
+  &lt;volume name="CONFIGTEST" size="131072"/&gt;
+&lt;/volume_table&gt;
+</pre>
+
+This volume information is used by the toolchain to create an include
+file.  The auto-generated file, however, has to be included manually.
+Place the following line in the configuration file which declares the
+ConfigStorageC component (e.g. <code>BlinkConfigAppC.nc</code>):
+
+<pre>
+#include "StorageVolumes.h"
+</pre>
+
+<li>Config storage <em>uses</em> the <code>Mount</code> and
+<code>ConfigStorage</code> interfaces (note that we rename
+<code>ConfigStorage</code> to <code>Config</code>).
+
+<pre>
+module BlinkConfigC {
+  uses {
+    ...
+    interface Mount;
+    interface ConfigStorage as Config;
+    ...
+  }
+}
+</pre>
+
+<li>Each interface must be wired to an <em>implementation</em> that
+will provide it:
+
+<pre>
+configuration BlinkConfigAppC {
+}
+implementation {
+  components BlinkConfigC as App;
+  components new ConfigStorageC(VOLUME_CONFIGTEST); 
+  ...
+
+  App.Mount      -> ConfigStorageC.Mount;
+  App.Config     -> ConfigStorageC.ConfigStorage;
+  ...
+}
+</pre>
+
+<li>Before the flash chip can be used, it must be mounted using the
+two-phase mount/mountDone command.  Here we show chaining how this
+might be chained into the boot sequence:
+
+<pre>
+  event void Boot.booted() {
+    call AMControl.start();
+  }
+
+  event void AMControl.startDone(error_t error) {
+    if (error != SUCCESS) {
+      call AMControl.start();
+    }
+    if (call Mount.mount() != SUCCESS) {
+      // Handle failure
+    }
+  }
+</pre>
+
+<li>If the Mount.mount succeeds, then the <code>Mount.mountDone</code>
+event will be signaled.  In this case, we call the
+<code>ConfigStore.mount</code> command from with the event handler:
+
+<pre>
+  event void Mount.mountDone(error_t error) {
+    if (error != SUCCESS) {
+      // Handle failure
+    }
+    else{
+      call Config.write(CONFIG_ADDR, &period, sizeof(period));
+    }
+  }
+</pre>
+
+<li>Once mounted, the flash can be written:
+
+<pre>
+  event void Mount.mountDone(error_t error) {
+    if (error != SUCCESS) {
+      // Handle failure
+    }
+    else{
+      call Config.write(CONFIG_ADDR, &period, sizeof(period));
+    }
+  }
+</pre>
+
+<li>Data is not necessarily "written" to flash when
+<code>ConfigStore.write</code> is called.  To ensure data is persisted
+to flash, a <code>ConfigStore.commit</code> call is required:
+
+<pre>
+  event void Config.writeDone(storage_addr_t addr, void *buf, 
+    storage_len_t len, error_t result) {
+    // Verify addr and len
+
+    if (result == SUCCESS) {
+      // Note success
+    }
+    else {
+      // Handle failure
+    }
+    if (call Config.commit() != SUCCESS) {
+      // Handle failure
+    }
+  }
+</pre>
+
+<li>Finally, when the commit is complete, data can be read back from
+the flash:
+
+<pre>
+  event void Config.commitDone(error_t error) {
+    if (call Config.read(CONFIG_ADDR, &period2, sizeof(period2)) != SUCCESS) {
+      // Handle failure
+    }
+  }
+
+  event void Config.readDone(storage_addr_t addr, void* buf, 
+    storage_len_t len, error_t result) __attribute__((noinline)) {
+    memcpy(&period2, buf, len);
+
+    if (period == period2) {
+      call Leds.led2On();
+    }
+
+    if (len == 2 && addr == CONFIG_ADDR) {
+      call Leds.led1On();
+    }
+  }
+</pre>
+
+</ol>
+
+<h1>Logging Data</h1>
+
+See <a href="../../../apps/tests/storage/Log/">
+<code>tinyos-2.x/apps/tests/storage/Log/</code></a> for an example of
+code that uses the Log storage abstraction. Log is generally used for
+append-based data streams consisting of relatively small data items.
+It provides atomicity guarantees for data writes.
+
+<h1>Storing Large Objects</h1>
+
+See <a href="../../../apps/tests/storage/Block/">
+<code>tinyos-2.x/apps/tests/storage/Block/</code></a> for an example
+of code that uses the Block storage abstraction. Block is generally
+used for storing large objects that cannot easily fit in RAM.
+
+<h1>Conclusions</h1>
+
+This lesson introduced the basic storage abstractions in Tiny 2.x.
+
+<a name=#related_docs>
+<h1>Related Documentation</h1>
+
+<ul>
+<li> (1) <a name="fn1"><a href="../tep103.html">TEP 103: Permanent Data Storage</a></a>
+<li> (2) <a name="fn2"><a href="lesson1.html">Lesson 1: Getting Started with TinyOS and nesC</a></a>
+<i>TinyOS Programming</i></a>
+</ul>
+
+<!-- Begin footer -->
+<br>
+<hr>
+<center>
+<p>&lt;&nbsp;<b><a href="lesson6.html">Previous Lesson</a></b> |&nbsp; <b><a
+ href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson8.html">Next Lesson </a>&nbsp;&gt;</b>
+</center>
+
+</body>
+</html>
diff --git a/doc/html/tutorial/lesson9.html b/doc/html/tutorial/lesson9.html
new file mode 100644 (file)
index 0000000..ad668ca
--- /dev/null
@@ -0,0 +1,93 @@
+  <html>
+    <head>
+      <title>TinyOS Tutorial Lesson 9: Concurrency in TinyOS</title>
+      <link href="../../stylesheets/tutorial.css" rel="stylesheet" type="text/css">
+    </head>
+    <body>
+      
+      <div class="title">Lesson 9: Concurrency</div>
+      <div class="subtitle">Last updated 30 October 2006</div>
+
+      <h1>Introduction</h1>
+
+      <p>This tutorial introduces the concept of <tt>async</tt> code,
+       which represents interrupt handlers and other time-critical functionality.
+       It describes the relationship between async code and tasks</p>
+
+      
+      <h1>Sync vs. Async</h1>
+      <p><A HREF="lesson2.html">Lesson 2</A> introduced tasks as a
+       mechanism to defer processing until later. Because tasks are
+       run-to-completion (a new task does not start until the previous one
+       finished), well-written components keep keep them short and spread
+       complex processing across several tasks. Not all TinyOS code is
+       run from a task, however: when a processor has an interrupt,
+       it immediately jumps to the interrupt handler code.</p>
+
+      <p>Because interrupt handler code can theoretically run at almost any
+       time, it has to be much more careful than task code. The interrupt
+       might start executing in the middle of a task, and it needs to make sure
+       that it does not corrupt variables that the task is using. The complexities
+       this introduces motivate most service-level TinyOS code to be in tasks.
+       Interrupt handlers therefore usually post tasks to defer their processing
+       as soon as they can, simplifying the code.</p>
+
+      <p>Some code, however, such as the interrupt handlers themselves cannot 
+       be in a task. Only a small subset of TinyOS code has been written to safely
+      run in preemptive context: these functions have the <tt>async</tt> keyword.
+       If an async function needs to call a command or signal an event that is not
+       async, then it must post a task to do so. Code that does not have the
+      async keyword is <i>synchronous</i>, as synchronous functions do not preempt
+      one another. However, as most TinyOS functions are synchronous, there is no
+      keyword (it is the default). This restriction is in one direction only.
+       Synchronous (task) code can call
+       async functions, but async code cannot call synchronous functions.</p>
+
+      <h1>An Example Async Function</h1>
+
+      <p><tt>Leds</tt> is a very common interface whose commands are all async.
+       It is often the case that low-level code needs to control the LEDs (e.g.,
+       when testing), and so these functions can be safely called from interrupts.
+       If the Leds commands were not async, then an interrupt handler would have
+       to post a task to toggle them, possibly introducing enough delay to make
+       debugging difficult.</p>
+
+      <pre>
+interface Leds {
+  async command void led0On();
+  async command void led0Off();
+  async command void led0Toggle();
+  async command void led1On();
+  async command void led1Off();
+  async command void led1Toggle();
+  async command void led2On();
+  async command void led2Off();
+  async command void led2Toggle();
+  async command uint8_t get();
+  async command void set(uint8_t val);
+}
+      </pre>
+
+
+      <p>Calling async functions is easy; a caller doesn't need to do anything special:
+       a component can just call Leds commands. The challenging part is implementing
+       async functions.</p>
+
+      
+       
+      <p>Commands and events that are executed as part
+       of a hardware event handler must be declared with the <b>async</b>
+       keyword (more about the async keyword in Lesson 8). </p>
+      
+      <p>Because tasks and hardware event handlers may be preempted by other
+       asynchronous code, nesC programs are susceptible to certain race
+       conditions. Races are avoided either by accessing shared data
+       exclusively  within tasks, or by having all accesses within <b>atomic</b>
+       statements. The nesC compiler reports potential <b>data races</b> to the
+       programmer at compile-time. It is possible the compiler may report a
+       false positive. In this case a variable can be declared with the <b>norace</b>
+       keyword. The norace keyword should be used with extreme caution. </p>
+      
+      <p>Please see the <a href="../../doc/nesc/ref.pdf">nesC Language
+         Reference Manual</a> for more information on programming in nesC. <br>
+         &nbsp;
diff --git a/doc/pdf/tinyos-programming.pdf b/doc/pdf/tinyos-programming.pdf
new file mode 100644 (file)
index 0000000..9ef23ed
Binary files /dev/null and b/doc/pdf/tinyos-programming.pdf differ
diff --git a/doc/txt/porting.txt b/doc/txt/porting.txt
new file mode 100644 (file)
index 0000000..8e7dbde
--- /dev/null
@@ -0,0 +1,85 @@
+========================================================
+Porting TinyOS 1.x Code to TinyOS 2.0
+========================================================
+
+:Author: Tahir Azim and Philip Levis
+:Date: October 26 2006
+
+.. Note::
+   This document provides a few important points that describe 
+   major steps required for porting TinyOS 1.x code to TinyOS 2.0.
+   It is based on Tahir Azim's experience porting Beacon Vector
+   Routing (BVR[1_]) from TinyOS 1.x to T2. This document is not
+   a complete porting guide, but the hope is that it will provide
+   some help or guidance.
+
+1. Porting Points
+====================================================================
+
+As these observations come from porting a network protocol, they are
+rather protocol-centric and do not consider other abstractions such
+as storage. We hope to add such points in the future.
+
+  1.    SUCCESS was a non-zero error code in TinyOS 1.x, while FAIL was non-zero. So any "if blocks" of the following form need to be changed::
+
+           if (call Packet...) {
+               //SUCCESS!: do this...
+           }
+
+  In TinyOS 2.x, SUCCESS is equal to a zero error code, while other error codes are non-zero. So calls like this should be changed to make sure they test the result for equality with SUCCESS::
+
+         if (call Packet... () == SUCCESS ) { 
+               //SUCCESS!: do this...
+           }
+
+  2.    The "init()" and "start/stop()" methods in StdControl have been separated in TinyOS 2.x. The init() method is now part of the "Init" interface. Therefore all modules implementing StdControl should now implement Init also. Modules wired to the StdControl interface of a module should also wire to its Init interface. 
+
+  3.    The nx_bool data type should be replaced by nx_uint8_t.
+
+  4.    Radios need to be started manually using SplitControl.start() and SplitControl.stop() at the beginning of the simulation. In TinyOS 1.x, this was assumed to be done automatically by TOSSIM/TinyOS. 
+
+  5.    Packets are now an abstract data type (ADT) in TinyOS 2.x. Therefore, destination addresses from packets can no longer be obtained by using "msg -> addr". Instead the AMPacket.destination() method of the AMPacket interface should be used for this purpose. AMSenderC or AMReceiverC can be used to wire the AMPacket interface.
+
+  6.    Similarly, in order to get a pointer to the payload of received message_t structures, and to get the payload lengths and maximum payload lengths of message_t structures, the Packet interface is used. This can also be wired to an AMSenderC or AMReceiverC component.  Similarly, instead of using "msg->strength" to get the strength of a received signal, CC2420Packet.getRssi(msg) can be used. The CC2420Packet interface can be wired to CC2420ActiveMessageC.
+
+  7.    Communication interfaces are very similar but require straightforward porting. SendMsg and ReceiveMsg interfaces (wherever used or provided by various modules) should be replaced by AMSend and Receive interfaces. At the lowest layer of the communication stack, AMSend and Receive interfaces should be wired to AMSenderC and AMReceiverC. 
+
+  8.    Where a module that previously provided SendMsg is changed to provide AMSend, extra methods have to be added that are part of the AMSend signature. These include the cancel, getPayload and maxPayloadLength methods. The Packet interface wired to AMSenderC can generally be used to implement these methods. 
+
+  9.    TOS_UART_ADDRESS no longer exists. Use an SerialAMSenderC component when you would like to send to the serial port.
+
+  10.   TOS_LOCAL_ADDRESS no longer exists. There is now a distinction between the local node's ID (which is TOS_NODE_ID) and the active message address. The active message address of a communication interface can be obtained through the AMPacket.localAddress() command. By default, node ID and AM address are the same. TOS_NODE_ID is bound at compile-time, while an interface's AM address can be changed at runtime.
+
+  11.    Calls such as Leds.greenToggle(), Leds.yellowToggle() etc need to be replaced by Leds.led1Toggle(), Leds.led2Toggle() etc.
+
+  12.    You should no longer use "#ifdef PLATFORM_PC" to separate pieces of code that are to run only on the 'pc' target. Instead, "#ifdef TOSSIM" is used to identify blocks of code that should be run only in TOSSIM. 
+
+  13.    dbg messages no longer use one of the debug modes of the form, DBG_* as their first argument. Instead, they should be replaced with strings identifying the sources from where the messages originated. 
+
+2. Author's Address
+====================================================================
+
+| Tahir Azim
+| 358 Gates Hall
+| Computer Systems Laboratory
+| Stanford University
+| Stanford, CA 94305
+|
+| email - tazim@cs.stanford.edu
+|
+| Philip Levis
+| 358 Gates Hall
+| Computer Systems Laboratory
+| Stanford University
+| Stanford, CA 94305
+|
+| phone - +1 650 725 9046
+|
+| email - pal@cs.stanford.edu
+
+3. Citations
+====================================================================
+
+.. [1] Rodrigo Fonseca, David Culler, Sylvia Ratnasamy, Scott Shenker, and Ion Stoica. "Beacon Vector Routing: Scalable Point-to-Point Routing in Wireless Sensornets." In Proceedings of the Second USENIX/ACM Symposium on Network Systems Design and Implementation (NSDI 2005).
+
diff --git a/overall-todo.txt b/overall-todo.txt
new file mode 100644 (file)
index 0000000..55e2545
--- /dev/null
@@ -0,0 +1,119 @@
+nesC: 
+- David Gay's todo list
+- everyone: use, report problems, improvement requests (minor only, please)
+
+tools:
+- select, patch, build, package tools (Kristin)
+  Java, cygwin, avr+msp gcc+gdb+binutils+libc, graphviz, avarice
+  support using JREs rather than only JDKs
+- javax.comm replacement (Cory)
+- build-system (tools/make) (Cory)
+
+packaging:
+- cleanup the tinyos tools story (tinyos-1.x/tools), make into cleanly
+  compilable + installable package
+    initial setup: Phil B.
+- cleanup our jar story (aka, no more giant CLASSPATH)
+  drop useless stuff, merge into single jar?
+- tinyos RPMs should come with compiled .class files (see JRE requirement)
+  (alternately, they could all be placed in the single jar file...)
+- source vs binary rpms? (i.e., provide binary-only rpms if possible)
+
+regression testing:
+- from 1.2 (Ion)
+
+TinyOS core (platform-independent):
+- booting (Phil L.)
+- scheduler (Phil L.)
+- routing
+  - protocols, implementations
+- SNMS (Gil)
+- Deluge (Jonathan)
+- OSKI (Phil L.)
+- protocol stack
+- tinyos 1.x compatibility layer
+
+Apps:
+- tests
+- tutorial apps (see tutorial)
+- surge-like
+- TOSBase
+
+Tutorial:
+- update, write apps, you name it
+
+mica2/mica2dot/micaz:
+- booting (Martin)
+- adc (Hu)
+- timer (Martin)
+- storage (David G.)
+- hardware id (Martin)
+- built-in sensors [dropped]
+
+storage:
+- at45db (David G.)
+- stm25p (Jonathan)
+- intel mote (Lama)
+
+csma radio:
+- cc1000 (Joe, David G.???)
+- cc2420 (Joe)
+- infineon (TU Berlin)
+
+security:
+- cc1000, tinysec
+- cc2420
+
+buses:
+- i2c (Joe: doc+msp430) (need: other platforms)
+- spi (Joe: doc+msp430) (need: other platforms?)
+- bus sharing/allocation (Joe, Vlado?)
+
+msp430:
+- booting (done)
+- adc (TU Berlin)
+- timer (Cory)
+
+telos a/b:
+- booting
+- hardware id (Gil)
+- built-in sensors
+
+eyes:
+- booting
+- hardware id
+
+intel mote 2:
+- booting (Phil B.)
+- timer
+- storage (Lama)
+- hardware id
+
+sensor boards:
+- micasb
+- basicsb
+- any others?? (mts400 (weather), mda300ca (data ack), telos?, eyes?)
+
+PC-side java:
+- guis for standard apps
+- net.tinyos.message (mig-support)
+- net.tinyos.packet (r/w TinyOS packets)
+- net.tinyos.mcenter
+- net.tinyos.sf (serial forwarder)
+- net.tinyos.sim (tossim)
+- net.tinyos.tools (basic user tools)
+- net.tinyos.util (utility classes)
+
+PC-side other:
+- XML mig / ncg-like (based on new nesC attribute stuff?)
+- matlab
+- C support for:
+  - serial protocol (over serial ports and tcp sockets)
+  - serial forwarder protocol (over tcp sockets)
+  - serial forwarder
+  - simple listening
+  - mig / ncg
+- other-language support for:
+  - serial forwarder protocol (over tcp sockets)
+  - mig / ncg
+  - which languages? (python, perl?)
diff --git a/support/sdk/java/net/tinyos/mviz/DDocument.java b/support/sdk/java/net/tinyos/mviz/DDocument.java
new file mode 100644 (file)
index 0000000..df45c4b
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.tinyos.mviz;
+
+// DDocument.java
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.*;
+
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.table.*;
+
+import net.tinyos.message.*;
+
+public class DDocument
+    extends JPanel 
+    implements ActionListener{    
+
+    protected String directory;
+    protected JPanel canvas;
+    protected Vector layers;
+       
+    private Color currentColor;
+       
+    public float[] maxValues;
+    public int selectedFieldIndex;
+    public int selectedLinkIndex;
+    public ImageIcon icon;
+    public Image image;
+       
+       
+    public DNavigate navigator;
+    public Color getColor(){ return currentColor; }
+    public Vector sensed_motes;
+    public Vector sensed_links;
+    public ArrayList moteModels;
+    public ArrayList linkModels;
+    private JTextField jText;
+    private DrawTableModel tableModel;
+    private JTable jTable;
+       
+    private String[] toStringArray(Vector v) {
+       String[] array = new String[v.size()];
+       for (int i = 0; i < v.size(); i++) {
+           array[i] = (String)v.elementAt(i);
+       }
+       return array;
+    }
+    
+    public DDocument(int width, int height, Vector fieldVector, Vector linkVector, String dir) {
+       super();
+       layers = new Vector();
+       directory = dir;
+       
+       setOpaque(false);
+       setLayout(new BorderLayout(6,6));
+       try{ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+       } catch (Exception ignore){}
+               
+       selectedFieldIndex = 0;
+       selectedLinkIndex = 0;
+       canvas = new DPanel(this);
+       canvas.setLayout(null);
+       canvas.setDoubleBuffered(true);
+       canvas.setPreferredSize(new Dimension(width, height));
+       canvas.setMinimumSize(new Dimension(width, height));
+       canvas.setSize(new Dimension(width, height));
+       canvas.setOpaque(false);
+       canvas.setBorder(new SoftBevelBorder(SoftBevelBorder.LOWERED));
+       add(canvas, BorderLayout.CENTER);
+       sensed_motes = fieldVector;
+       sensed_links = linkVector;
+       moteIndex = new HashMap();
+       linkIndex = new HashMap();
+               
+       String imgName = directory + "/mote.gif";
+       try {
+           image = Toolkit.getDefaultToolkit().getImage(imgName);
+       }
+       catch (Exception e) {
+           System.out.println(e);
+       }
+       System.out.println(imgName);
+               
+               
+       canvas.addComponentListener(new ComponentListener(){
+               public void componentResized(ComponentEvent e) {
+                   navigator.redrawAllLayers();
+               }
+               public void componentHidden(ComponentEvent arg0) {
+               }
+               public void componentMoved(ComponentEvent arg0) {
+               }
+               public void componentShown(ComponentEvent arg0) {
+               }                       
+           });
+
+               
+               
+       // Make control area
+       JPanel west = new JPanel();
+       west.setDoubleBuffered(true);
+       west.setLayout(new BoxLayout(west, BoxLayout.Y_AXIS));
+       add(west, BorderLayout.WEST);
+       currentColor = Color.GRAY;
+       navigator = new DNavigate(sensed_motes, sensed_links, this);
+       west.add(navigator);
+       west.add(Box.createVerticalStrut(10));
+       tableModel = new DrawTableModel(sensed_motes);
+       jTable = new JTable(tableModel);
+       jTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+       JScrollPane scroller = new JScrollPane(jTable);
+       scroller.setPreferredSize(new Dimension(350, 200));
+       scroller.setMinimumSize(new Dimension(350, 200));
+       scroller.setSize(new Dimension(350, 200));
+       west.add(scroller);
+               
+       enableEvents(LinkSetEvent.EVENT_ID);
+       enableEvents(ValueSetEvent.EVENT_ID);
+    }
+    public void actionPerformed(ActionEvent e) {
+    }
+
+    private void zMove(int direction){
+       tableModel.updateTable();
+    }
+    public int width_canvas = 600;
+    public int height_canvas = 600;
+       
+    protected ArrayList motes = new ArrayList();
+    protected ArrayList links = new ArrayList();
+    protected DMoteModel selected = null;
+    
+    protected HashMap moteIndex;
+    protected HashMap linkIndex;
+       
+    // Provided default ctor that calls the regular ctor
+    public DDocument(Vector fieldVector, Vector linkVector) {
+       this(300, 300, fieldVector, linkVector, ".");    // this syntax calls one ctor from another
+    }
+       
+       
+    public DShape getSelected() {
+       return null;
+    }
+       
+    public void setSelected(DShape selected) {
+    }
+
+    Random rand = new Random();
+
+
+    private DMoteModel createNewMote(int moteID){
+       DMoteModel m = new DMoteModel(moteID, rand, this);
+       //System.out.println("Adding mote " + moteID);
+       motes.add(m);
+       moteIndex.put(new Integer(moteID), m);
+       tableModel.add(m);
+
+       navigator.addMote(m);
+       return m;
+    }
+    
+    public void setMoteValue(int moteID, String name, int value) {
+       ValueSetEvent vsv = new ValueSetEvent(this, moteID, name, value);
+       EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+       eq.postEvent(vsv);
+    }
+
+    private DLinkModel createNewLink(DMoteModel start, DMoteModel end) {
+       DLinkModel dl = new DLinkModel(start, end, rand, this);
+       links.add(dl);
+       linkIndex.put(start.getId() + " " + end.getId(), dl);
+       //System.out.println("Put with key <" + start.getId() + " " + end.getId() + ">");
+       return dl;
+    }
+    
+    public void setLinkValue(int startMote, int endMote, String name, int value) {
+       LinkSetEvent lsv = new LinkSetEvent(this, name, value, startMote, endMote);
+       EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+       eq.postEvent(lsv);
+    }
+
+    protected void processEvent(AWTEvent event) {
+       if (event instanceof ValueSetEvent) {
+           ValueSetEvent vsv = (ValueSetEvent)event;
+           String name = vsv.name();
+           int moteID = vsv.moteId();
+           int value = vsv.value();
+           DMoteModel m = (DMoteModel)moteIndex.get(new Integer(moteID));
+           if (m == null) {
+               m = createNewMote(moteID);
+           }
+           //System.out.println("Set " + moteID + ":" + name + " to " + value);
+           m.setMoteValue(name, value);
+           navigator.redrawAllLayers();
+       }
+       else if (event instanceof LinkSetEvent) {
+           LinkSetEvent lsv = (LinkSetEvent)event;
+           String name = lsv.name();
+           int startMote = lsv.start();
+           int endMote = lsv.end();
+           int value = lsv.value();
+           DMoteModel m = (DMoteModel)moteIndex.get(new Integer(startMote));
+           if (m == null) {
+               m = createNewMote(startMote);
+           }
+           DMoteModel m2 = (DMoteModel)moteIndex.get(new Integer(endMote));
+           if (m2 == null) {
+               m2 = createNewMote(endMote);
+           }
+           DLinkModel dl = (DLinkModel)linkIndex.get(startMote + " " + endMote);
+           if (dl == null) {
+               //System.out.println("Does not contain key <" + startMote + " " + endMote + ">");
+               dl = createNewLink(m, m2);
+           }
+           //System.out.println("Setting " + name + " " + startMote + " -> " + endMote + " to " + value);
+           dl.setLinkValue(name, value);
+           navigator.redrawAllLayers();
+       }
+       else {
+           super.processEvent(event);
+       }
+    }
+       
+    public static void usage() {
+       System.err.println("usage: tos-mviz [-comm source] [-dir image_dir] message_type [message_type ...]");
+    }
+       
+    // Just a test main -- put a little DDocument on screen
+    public static void main(String[] args)     {
+       JFrame frame = new JFrame("MViz");
+       Vector packetVector = new Vector();
+       String source = null;
+       String dir = ".";
+       if (args.length > 0) {
+           for (int i = 0; i < args.length; i++) {
+               if (args[i].equals("-comm")) {
+                   source = args[++i];
+               }
+               else if (args[i].equals("-dir")) {
+                   dir = args[++i];
+               }
+               else {
+                   String className = args[i];
+                   packetVector.add(className);
+               }
+           }
+       }
+       else if (args.length != 0) {
+           usage();
+           System.exit(1);
+       }
+       if (packetVector.size() == 0) {
+           usage();
+           System.exit(1);
+       }
+       
+       DataModel model = new DataModel(packetVector);
+       DDocument doc = new DDocument(600, 600, model.fields(), model.links(), dir);
+        
+       frame.setContentPane(doc);
+       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+       frame.pack();
+       frame.setVisible(true);
+       
+       MessageInput input = new MessageInput(packetVector, source, doc);
+       input.start();
+    }
+       
+    private void repaintAllMotes(){            
+       Iterator it = motes.iterator();
+       while(it.hasNext()){
+           ((DMoteModel)it.next()).requestRepaint();
+       }
+    }
+    private void repaintAllLinks(){            
+       Iterator it = links.iterator();
+       while(it.hasNext()){
+           ((DLink)it.next()).repaint();
+       }
+    }
+    //#########################################################################//
+       
+       
+       
+    private class DrawTableModel
+       extends AbstractTableModel
+       implements DMoteModelListener {
+       private Vector fields;
+       
+       public DrawTableModel(Vector fields) {
+           this.fields = fields;
+       }
+       //-----------------------------o
+       public String getColumnName(int col){
+           switch(col) {
+           case 0:
+               return "X";
+           case 1:
+               return "Y";
+           default:
+               return (String)fields.elementAt(col - 2);
+           }
+       }
+       //-----------------------------o
+       public int getColumnCount() { return fields.size() + 2; }
+       //-----------------------------o
+       public int getRowCount() {
+           return DDocument.this.motes.size();
+       }           
+       //-----------------------------o
+       public Object getValueAt(int row, int col) {
+           DMoteModel model = (DMoteModel) DDocument.this.motes.get(row);
+           switch(col) {
+           case 0:
+               return "" + (int)model.getLocX();
+           case 1:
+               return "" + (int)model.getLocY();
+           default:
+               return("" + (int)model.getValue(col - 2));
+           }
+       }
+       //-----------------------------o
+       public void shapeChanged(DMoteModel changed, int type){
+           int row = findModel(changed);
+           if (row != -1) fireTableRowsUpdated(row, row);      
+       }
+       //-----------------------------o
+       public void add(DMoteModel model){
+           model.addListener(this);
+           int last = DDocument.this.motes.size()-1;
+           fireTableRowsInserted(last, last);
+       }
+       //-----------------------------o
+       public void remove(DMoteModel model){
+           int row = findModel(model);
+           if (row != -1) fireTableRowsDeleted(row, row);              
+       }
+       //-----------------------------o
+       public void updateTable(){
+           fireTableDataChanged();
+       }
+       //-----------------------------o
+       private int findModel(DMoteModel changed){
+           for (int i=0; i<DDocument.this.motes.size(); i++){
+               if ((DMoteModel)DDocument.this.motes.get(i) == changed)
+                   return i;
+           }
+           return -1;              
+                       
+       }
+    }
+    
+    private class DPanel extends JPanel {
+       private DDocument doc;
+       private int lastX = -1;
+       private int lastY = -1;
+       
+       public DPanel(DDocument d) {
+           super();
+           doc = d;
+           addMouseListener( new MouseAdapter() {
+                   private boolean withinRange(int val, int low, int high) {
+                       return (val >= low && val <= high);
+                   }
+                   public void mousePressed(MouseEvent e) {
+                       lastX = e.getX();
+                       lastY = e.getY();
+                       Iterator it = doc.motes.iterator();
+                       while (it.hasNext()) {
+                           DMoteModel model = (DMoteModel)it.next();
+                           if (withinRange(e.getX(),
+                                           model.getLocX() - 20,
+                                           model.getLocX() + 20) &&
+                               withinRange(e.getY(),
+                                           model.getLocY() - 20,
+                                           model.getLocY() + 20)) {
+                               selected = model;
+                               return;
+                           }
+                       }
+                   }
+                   public void mouseReleased(MouseEvent e) {
+                       if (doc.selected != null) {
+                           doc.selected = null;
+                           lastX = -1;
+                           lastY = -1;
+                       }
+                   }
+               });
+           addMouseMotionListener(new MouseMotionAdapter() {
+                   public void mouseDragged(MouseEvent e) {
+                       if (doc.selected != null) {
+                           if (lastY == -1) {
+                               lastY = e.getY();
+                           }
+                           if (lastX == -1) {
+                               lastX = e.getX();
+                           }
+                           int x = e.getX();
+                           int y = e.getY();   
+                           int dx = x-lastX;
+                           int dy = y-lastY;
+                           lastX = x;
+                           lastY = y;
+                           
+                           selected.move(selected.getLocX() + dx, selected.getLocY() + dy);
+                       }
+                       doc.navigator.redrawAllLayers();
+                   }
+               });
+       }
+
+       public void paintComponent(Graphics g) {
+           super.paintComponent(g);
+           setOpaque(false);
+           //System.out.println("Painting panel!");
+           doc.navigator.redrawAllLayers();
+       }
+    }
+
+    private class CanvasMouse extends MouseAdapter {
+
+    }
+    protected class ValueSetEvent extends AWTEvent {
+       public static final int EVENT_ID = AWTEvent.RESERVED_ID_MAX + 1;
+       private String name;
+       private int value;
+       private int mote;
+       
+       public ValueSetEvent(Object target, int mote, String name, int value) {
+           super(target, EVENT_ID);
+           this.value = value;
+           this.name = name;
+           this.mote = mote;
+       }
+       
+       public String name() {
+           return name;
+       }
+
+       public int value() {
+           return value;
+       }
+
+       public int moteId() {
+           return mote;
+       }
+    }
+
+
+    protected class LinkSetEvent extends AWTEvent {
+       public static final int EVENT_ID = AWTEvent.RESERVED_ID_MAX + 2;
+       private String name;
+       private int value;
+       private int start;
+       private int end;
+       
+       public LinkSetEvent(Object target, String name, int value, int start, int end) {
+           super(target, EVENT_ID);
+           this.value = value;
+           this.name = name;
+           this.start = start;
+           this.end = end;
+       }
+       
+       public String name() {
+           return name;
+       }
+
+       public int value() {
+           return value;
+       }
+
+       public int start() {
+           return start;
+       }
+
+       public int end() {
+           return end;
+       }
+    }
+}
diff --git a/support/sdk/java/net/tinyos/mviz/DLayer.java b/support/sdk/java/net/tinyos/mviz/DLayer.java
new file mode 100644 (file)
index 0000000..d094168
--- /dev/null
@@ -0,0 +1,365 @@
+/*\r
+ * Copyright (c) 2006 Stanford University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Stanford University nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package net.tinyos.mviz;\r
+\r
+// DDocument.java\r
+\r
+import java.awt.*;\r
+\r
+import javax.imageio.ImageIO;\r
+import javax.swing.*;\r
+\r
+import java.util.*;\r
+import java.awt.event.*;\r
+import java.io.*;\r
+\r
+import javax.swing.*;\r
+import javax.swing.border.Border;\r
+import javax.swing.border.LineBorder;\r
+import javax.swing.table.*;\r
+\r
+import java.awt.image.*;\r
+\r
+\r
+// Standard imports for XML\r
+import javax.xml.parsers.*;\r
+import org.xml.sax.*;\r
+import org.w3c.dom.*;\r
+\r
+\r
+\r
+\r
+public class DLayer extends JPanel implements ActionListener{\r
+       \r
+    public static final int MOTE = 0;\r
+    public static final int LINK = 1;\r
+    public static final int FIELD = 2;\r
+    private static final Color[] COLORS = {\r
+       new Color(231, 220, 206),\r
+       new Color(250, 210, 99),\r
+       new Color(209, 230, 179)\r
+    };\r
+       \r
+    private int type;\r
+    protected int index;\r
+    protected int zIndex;\r
+    protected int z_index = 0;\r
+    private ArrayList layer = new ArrayList();\r
+       \r
+    private JLabel label;\r
+    private JCheckBox check;\r
+    private String[][] DISPLAYS = { {"circle", "img", "txt"}, {"line", "line+label", "label"}, {"color 256", "color 1024", "color 4096", "color 16384"}};\r
+    private JComboBox displays;\r
+       \r
+    private ArrayList models;\r
+    private ArrayList linkModels;\r
+    private JButton up;\r
+    private JButton down;\r
+       \r
+    protected int paintMode = 0;\r
+    // Values chosen for COLOR so that readings can be right shifted\r
+    // that many bits to be in range 0-255\r
+    static public final int COLOR_256 = 0;\r
+    static public final int OVAL = 1;\r
+    static public final int COLOR_1024 = 2;\r
+    static public final int IMG = 3;\r
+    static public final int COLOR_4096 = 4;\r
+    static public final int TXT_MOTE = 5;\r
+    static public final int COLOR_16384 = 6;\r
+    static public final int LINE = 7;\r
+    static public final int LABEL = 8;\r
+    static public final int LINE_LABEL = 9;\r
+    \r
+    protected DNavigate navigator;\r
+       \r
+    private String name;\r
+    private DDocument parent;\r
+       \r
+    public DLayer(int zIndex, int index, String label, int type, DDocument parent, ArrayList models, DNavigate navigator){\r
+       this.parent = parent;\r
+       this.type = type;\r
+       this.models = models;\r
+       this.zIndex = zIndex;\r
+       this.index = index;\r
+       this.navigator = navigator;\r
+       this.name = label;\r
+       if (type == MOTE) {\r
+           this.paintMode = OVAL;\r
+       }\r
+       else if (type == LINK) {\r
+           this.paintMode = LINE;\r
+       }\r
+\r
+       \r
+       SpringLayout layout = new SpringLayout();\r
+       setLayout(layout);\r
+       setMaximumSize(new Dimension(350, 25));\r
+       setPreferredSize(new Dimension(350, 25));\r
+       setSize(new Dimension(350, 25));\r
+       setDoubleBuffered(true);\r
+       setBackground(COLORS[type]);\r
+       setBorder(new LineBorder(new Color(155, 155, 155)));\r
+               \r
+       check = new JCheckBox();\r
+       check.setSize(35, 25);\r
+       check.setMaximumSize(new Dimension(35, 25));\r
+       check.setMinimumSize(new Dimension(35, 25));\r
+       check.setPreferredSize(new Dimension(35, 25));\r
+       \r
+       up = new JButton("^");\r
+       up.setFont(new Font("Times", Font.PLAIN, 9));\r
+       up.setSize(25, 25);\r
+       up.setMaximumSize(new Dimension(25, 25));\r
+       up.setMinimumSize(new Dimension(25, 25));\r
+       up.setPreferredSize(new Dimension(25, 25));\r
+       up.setMargin(new Insets(2, 2, 2, 2));\r
+\r
+       down = new JButton("v");\r
+       down.setFont(new Font("Times", Font.PLAIN, 8));\r
+       down.setSize(25, 25);\r
+       down.setMaximumSize(new Dimension(25, 25));\r
+       down.setMinimumSize(new Dimension(25, 25));\r
+       down.setPreferredSize(new Dimension(25, 25));\r
+       down.setMargin(new Insets(2, 2, 2, 2));\r
+\r
+       this.label = new JLabel(" " + label, JLabel.LEFT);\r
+       this.label.setSize(125, 25);\r
+       this.label.setMaximumSize(new Dimension(125, 25));\r
+       this.label.setMinimumSize(new Dimension(125, 25));\r
+       this.label.setPreferredSize(new Dimension(125, 25));\r
+       switch (type) {\r
+       case MOTE:\r
+           this.label.setBackground(new Color(255, 200, 200));\r
+           break;\r
+       case FIELD:\r
+           this.label.setBackground(new Color(200, 255, 200));\r
+           break;\r
+       case LINK:\r
+           this.label.setBackground(new Color(200, 200, 255));\r
+           break;\r
+       default:\r
+           // do nothing\r
+       }\r
+       \r
+       displays = new JComboBox(DISPLAYS[type]);\r
+       displays.setSize(100, 25);\r
+       //displays.setMaximumSize(new Dimension(125, 25));\r
+       displays.setMinimumSize(new Dimension(125, 25));\r
+       displays.setPreferredSize(new Dimension(125, 25));\r
+       \r
+       \r
+       check.addActionListener(this);\r
+       up.addActionListener(this);\r
+       down.addActionListener(this);\r
+       displays.addActionListener(this);\r
+\r
+       layout.putConstraint(SpringLayout.WEST, this, 0, SpringLayout.WEST, down);\r
+       layout.putConstraint(SpringLayout.EAST, check, 0, SpringLayout.WEST, down);\r
+       layout.putConstraint(SpringLayout.EAST, down, 0, SpringLayout.WEST, up);\r
+       layout.putConstraint(SpringLayout.EAST, up, 0, SpringLayout.WEST, this.label);\r
+       layout.putConstraint(SpringLayout.EAST, this.label, 0, SpringLayout.WEST, displays);\r
+       layout.putConstraint(SpringLayout.EAST, displays, 0, SpringLayout.EAST, this);\r
+\r
+       \r
+       add(check);\r
+       add(down);\r
+       add(up);\r
+       add(this.label);\r
+       add(displays);\r
+\r
+       \r
+               \r
+    }\r
+       \r
+    public boolean isFieldSelected(){\r
+       return (type==FIELD && check.isSelected());\r
+    }\r
+       \r
+    public void actionPerformed(ActionEvent e) {\r
+       if (e.getSource() == check) {\r
+           if (check.isSelected()){\r
+               parent.selectedFieldIndex = index;\r
+               //repaintLayer(g);\r
+               //System.out.println("redraw index " +zIndex +" on layer");\r
+           } else if(type==FIELD){\r
+               //System.out.println("clear");\r
+               //parent.canvas.repaint();\r
+               //repaintLayer(g);\r
+           } else {\r
+               //repaintLayer(g);\r
+           }\r
+       } else if (e.getSource() == up){\r
+           parent.navigator.moveLayerUp(this.zIndex);\r
+       } else if (e.getSource() == down){\r
+           parent.navigator.moveLayerDown(this.zIndex);\r
+       } else if (e.getSource() == displays){\r
+           String selected = (String)displays.getSelectedItem();\r
+           if (selected.equals("circle")){\r
+               paintMode = OVAL;\r
+           } else if (selected.equals("img")){\r
+               paintMode = IMG;                        \r
+           } else if (selected.equals("txt")){\r
+               paintMode = TXT_MOTE;                   \r
+           } else if (selected.equals("color 256")) {\r
+               paintMode = COLOR_256;\r
+           } else if (selected.equals("color 1024")) {\r
+               paintMode = COLOR_1024;\r
+           } else if (selected.equals("color 4096")) {\r
+               paintMode = COLOR_4096;\r
+           } else if (selected.equals("color 16384")) {\r
+               paintMode = COLOR_16384;\r
+           } else if (selected.equals("line")) {\r
+               paintMode = LINE;\r
+           } else if (selected.equals("label")) {\r
+               paintMode = LABEL;\r
+           } else if (selected.equals("line+label")) {\r
+               paintMode = LINE_LABEL;\r
+           }\r
+       }\r
+       //System.out.println("Repainting parent?");\r
+       //parent.repaint();\r
+    }\r
+\r
+    public void init(){\r
+       if (type==LINK){\r
+           //addLinks(true);\r
+       } else {\r
+           addMotes(true);\r
+       }\r
+    }\r
+\r
+    public String toString() {\r
+       return "Layer " +  name + " " + type;\r
+    }\r
+    \r
+       \r
+    // private void addLinks(boolean paint){\r
+    //                 Iterator it = models.iterator();\r
+    //                 while(it.hasNext()){\r
+    //                         DLink mm = (DLink) it.next();\r
+    //                         //canvas.add(mm);\r
+    //                         if (paint) mm.repaint();\r
+    //                 }       \r
+    //     }\r
+       \r
+    protected void addMote(DMoteModel model, boolean paint){\r
+       DShape mote = new DMote(model, this.parent, this);\r
+       layer.add(mote);\r
+    }\r
+       \r
+    private void addMotes(boolean paint){\r
+       Iterator it = models.iterator();\r
+        while(it.hasNext()){\r
+           addMote((DMoteModel) it.next(), paint);\r
+       }           \r
+    }\r
+    \r
+       \r
+    public void updateIndex(int index, boolean repaint){\r
+       zIndex = index;\r
+       z_index = (navigator.totalLayers - zIndex)*100;\r
+       //if (repaint) redrawLayer();\r
+       //parent.canvas.setLayer(d.canvas, length - i);\r
+    }\r
+\r
+    public void paintScreenBefore(Graphics g) \r
+    {\r
+\r
+        Dimension d = parent.canvas.getSize();\r
+        int x = 0;\r
+        int y = 0;\r
+        int xstep = (int)(d.width / 40);\r
+       int ystep = (int)(d.height / 40);  \r
+\r
+        for(;x < d.width; x += xstep){\r
+            for(y = 0;y < d.height; y += ystep){\r
+                double val = 0;\r
+                double sum = 0;\r
+                double total = 0;\r
+                double min = 10000000;\r
+                Iterator it = models.iterator();\r
+                while(it.hasNext()){\r
+                    DMoteModel m = (DMoteModel) it.next();\r
+                    double dist = distance(x, y, m.x, m.y);   \r
+                    if(true){ //121\r
+                        if(dist < min) min = dist;\r
+                        val += ((double)(((int)m.getValue(index)) >> paintMode ))  / dist /dist;\r
+                        sum += (1/dist/dist);\r
+                    }\r
+                }\r
+                int reading = (int)(val / sum);\r
+               //System.out.println("Reading: " + reading);\r
+                if (reading > 255)\r
+                    reading = 255;\r
+                g.setColor(new Color(reading, reading, reading));\r
+               //System.out.println("Filling "  + x + "+" + step + " " + y + "+" + step + " with " + g.getColor());\r
+                g.fillRect(x, y, xstep, ystep);\r
+            }\r
+        }\r
+\r
+       \r
+    }\r
+\r
+    public double distance(int x, int y, int x1, int y1){\r
+        return Math.sqrt( (x-x1)*(x-x1)+(y-y1)*(y-y1));\r
+    }\r
+\r
+    protected void repaintLayer(Graphics g){\r
+       if (check.isSelected()){\r
+           //System.out.println("Repaint layer " + name);\r
+           if  (type==FIELD){\r
+               paintScreenBefore(g);\r
+           } else if (type == LINK) {\r
+               Iterator it = models.iterator();\r
+               //System.out.print("Draw links: ");\r
+               while (it.hasNext()) {\r
+                   DLinkModel model = (DLinkModel)it.next();\r
+                   DLink lnk = new DLink(model, parent, this);\r
+                   lnk.paintShape(g);\r
+                   //System.out.print("+");\r
+               }\r
+               //System.out.println();\r
+           }\r
+           else if (type == MOTE) {\r
+               Iterator it = models.iterator();\r
+               //System.out.print("Draw motes: ");\r
+               while (it.hasNext()){\r
+                   DMoteModel model = (DMoteModel)it.next();\r
+                   DShape m = new DMote(model, parent, this);\r
+                   m.paintShape(g);\r
+                   //System.out.print("+");\r
+               }\r
+               //System.out.println();\r
+           }\r
+       }       \r
+    }\r
+}\r
diff --git a/support/sdk/java/net/tinyos/mviz/DLink.java b/support/sdk/java/net/tinyos/mviz/DLink.java
new file mode 100644 (file)
index 0000000..725d19b
--- /dev/null
@@ -0,0 +1,173 @@
+/*\r
+ * Copyright (c) 2006 Stanford University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Stanford University nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package net.tinyos.mviz;\r
+\r
+// DShape.java\r
+import java.awt.*;\r
+import java.util.*;\r
+import javax.swing.*;\r
+import java.awt.event.*;\r
+import java.awt.geom.Line2D;\r
+\r
+public class DLink \r
+extends JComponent \r
+implements DLinkModelListener\r
+{\r
+       \r
+       protected DLinkModel model;\r
+       protected DDocument document;\r
+    private DLayer layer;\r
+    // remember the last point for mouse tracking\r
+       private int lastX, lastY;\r
+       \r
+       // Move or Resize ?\r
+       private int action;\r
+    private static final int MOVE = 0;\r
+       //=========================================================================//\r
+    public DLink(DLinkModel model, DDocument document, DLayer layer) {\r
+               super();\r
+               this.model = model;\r
+               this.layer = layer;\r
+               this.document = document;\r
+               model.addListener(this);\r
+               \r
+               // Mouse listeners.\r
+               addMouseListener( \r
+                       new MouseAdapter() \r
+                       {\r
+                           public void mousePressed(MouseEvent e) {\r
+                               selected();\r
+                               lastX = e.getX()+getX();\r
+                               lastY = e.getY()+getY();\r
+                               \r
+                               if (e.isControlDown()){ \r
+                               }else if(e.isAltDown()){ \r
+                               }else if(e.isShiftDown()){\r
+                               }else{ DetermineAction(lastX, lastY); }                     \r
+                           }\r
+                       }\r
+               );\r
+\r
+               addMouseMotionListener( \r
+                       new MouseMotionAdapter() \r
+                       {\r
+                           public void mouseDragged(MouseEvent e) {\r
+                               \r
+                               int x = e.getX()+getX();\r
+                               int y = e.getY()+getY();\r
+                               // compute delta from last point\r
+                               int dx = x-lastX;\r
+                               int dy = y-lastY;\r
+                               lastX = x;\r
+                               lastY = y;\r
+                               \r
+                               switch(action){\r
+                               case MOVE: DoAction(dx, dy); break;\r
+                               }\r
+                           }\r
+                       }\r
+               );\r
+               \r
+               synchToModel();         \r
+       }\r
+   \r
+       //=========================================================================//\r
+       public DLinkModel getModel() {\r
+               return(model);\r
+       }\r
+       \r
+       //=========================================================================//\r
+       public void shapeChanged(DLinkModel changed, int type) {\r
+           synchToModel();\r
+           repaint();\r
+       }\r
+       //=========================================================================//\r
+    public void paintShape(Graphics g){\r
+           Graphics2D g2 = (Graphics2D) g;\r
+           g.setColor(Color.BLACK);\r
+           int diffX = (model.m1.getLocX() - model.m2.getLocX());\r
+           int diffY = (model.m1.getLocY() - model.m2.getLocY());\r
+           if (diffX == 0 && diffY == 0) {\r
+               return;\r
+           }\r
+           if (diffX == 0) {diffX = 1;}\r
+           if (diffY == 0) {diffY = 1;}\r
+           int midX = (model.m1.getLocX() + model.m2.getLocX()) / 2;\r
+           int midY = (model.m1.getLocY() + model.m2.getLocY()) / 2;\r
+           midY += 8;\r
+           midX += 10;\r
+           //midX += Math.abs(((double)diffX / ((double)Math.abs(diffY) + (double)Math.abs(diffX))) * 60);\r
+           if (diffX * diffY < 0) {\r
+               midY += Math.abs(((double)diffX / ((double)Math.abs(diffY) + (double)Math.abs(diffX))) * 10);\r
+               midX += Math.abs(((double)diffX / ((double)Math.abs(diffY) + (double)Math.abs(diffX))) * 10);\r
+           }\r
+           else {\r
+               midY -= Math.abs(((double)diffX / ((double)Math.abs(diffY) + (double)Math.abs(diffX))) * 10);\r
+               midX += Math.abs((double)diffX / ((double)Math.abs(diffY) + (double)Math.abs(diffX)) * 10);\r
+           }\r
+           switch(layer.paintMode) {\r
+           case DLayer.LINE_LABEL:\r
+               g.setColor(Color.BLACK);\r
+               g2.drawString(document.sensed_links.elementAt(layer.index) + ": " + (int)model.getValue(layer.index), midX, midY);\r
+           case DLayer.LINE:\r
+               g2.setStroke(new BasicStroke(3));\r
+               g2.setColor(Color.RED);\r
+               g2.draw(new Line2D.Double(model.m1.getLocX(),  model.m1.getLocY(), model.m2.getLocX(), model.m2.getLocY()));\r
+               break;\r
+           case DLayer.LABEL:\r
+               g.setColor(Color.BLACK);\r
+               g2.drawString(document.sensed_links.elementAt(layer.index) + ": " + (int)model.getValue(layer.index), midX, midY);\r
+               break;\r
+           }\r
+       }\r
+    //=========================================================================//\r
+    public void paintComponent(Graphics g) {\r
+    }\r
+       //=========================================================================//\r
+       private void DetermineAction(int x, int y){\r
+        action = MOVE;         \r
+       }\r
+       //=========================================================================//\r
+       private void DoAction(int dx, int dy){\r
+       }\r
+       //=========================================================================//\r
+       private void synchToModel(){\r
+           setBounds(model.getTop(), model.getLeft(), model.getWidth(), model.getHeight());\r
+       }\r
+       //=========================================================================//\r
+       private void selected(){    \r
+       }\r
+\r
+}\r
+\r
+\r
+\r
diff --git a/support/sdk/java/net/tinyos/mviz/DLinkModel.java b/support/sdk/java/net/tinyos/mviz/DLinkModel.java
new file mode 100644 (file)
index 0000000..560d78a
--- /dev/null
@@ -0,0 +1,162 @@
+/*\r
+ * Copyright (c) 2006 Stanford University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Stanford University nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package net.tinyos.mviz;\r
+\r
+// DShapeModel.java\r
+/*\r
+ Store the data state for a single shape:\r
+  type, two points, color\r
+ Supports DShapeModelListeners.\r
+*/\r
+import java.awt.*;\r
+\r
+import javax.swing.*;\r
+import java.util.*;\r
+import java.awt.event.*;\r
+import java.io.*;\r
+\r
+\r
+class DLinkModel \r
+extends Object \r
+implements Serializable {\r
+\r
+       public static final int VALUE = 0;\r
+       public static final int MOTION = 1;\r
+       public static final int ANY = 1;\r
+       \r
+       \r
+    public DDocument root;\r
+    transient private ArrayList listeners;\r
+    \r
+    protected int x12, y12;\r
+    protected int[] values;\r
+    \r
+    DMoteModel m1;\r
+    DMoteModel m2;\r
+    \r
+    protected int COLOR_MAX = 230;\r
+       \r
+    public DLinkModel(DMoteModel m1, DMoteModel m2, Random rand, DDocument root){\r
+        this.root = root;\r
+        this.m1 = m1;\r
+        this.m2 = m2;\r
+        \r
+        x12 = getMiddle(m1.x, m2.x);\r
+        y12 = getMiddle(m1.y, m2.y);\r
+        \r
+        values = new int[root.sensed_links.size()];\r
+        \r
+        for (int i=0; i<root.sensed_links.size(); i++){\r
+            values[i] = 0;\r
+        }   \r
+        \r
+\r
+        //.listeners = null;\r
+    }\r
+\r
+    protected void setLinkValue(String name, int value) {\r
+       int index = root.sensed_links.indexOf(name);\r
+       if (index < 0) return;\r
+       values[index] = value;\r
+       //System.out.println("Setting link value " + index + " to " + value);\r
+    }\r
+    private int getMiddle(int x1, int x2){\r
+       return (x1 + x2)/2;\r
+    }\r
+    \r
+    public Color setColor(float value){\r
+        int color = (int)(value)%COLOR_MAX;\r
+        return new Color(color+15, color, color+25);\r
+    } \r
+       \r
+       public int getValue() { return(values[root.selectedLinkIndex]); }\r
+       public int getValue(int index) {\r
+           //System.out.println("Gettting link value " + index);\r
+           return(values[index]);\r
+       }\r
+    public int getValue(String name) {\r
+       int index = root.sensed_links.indexOf(name);\r
+       if (index < 0) return 0 ;\r
+       return values[index];\r
+    }\r
+       public int getTop() { return(Math.min(m1.y, m2.y)); }           \r
+       public int getBottom() { return(Math.max(m1.y, m2.y)); }                \r
+       public int getLeft() { return(Math.min(m1.x, m2.x)); }          \r
+       public int getRight() { return(Math.max(m1.x, m2.x)); }\r
+       \r
+       public int getWidth() { return(Math.abs(m1.x - m2.x)); }\r
+       public int getHeight() { return(Math.abs(m1.y - m2.y)); }\r
+\r
+    protected Color getColor() {\r
+       return Color.RED;\r
+    }\r
+       public void setValue(int value){\r
+           values[root.selectedLinkIndex] = value;\r
+           fireChanges();\r
+       }\r
+\r
+    \r
+       public int getLocX() {\r
+           return x12;\r
+       }       \r
+       public int getLocY() {\r
+           return y12;\r
+       }               \r
+       \r
+       \r
+       public void addListener(DLinkModelListener listener) {\r
+           if (listeners == null) listeners = new ArrayList();\r
+           Iterator it = listeners.iterator();\r
+               while (it.hasNext()) { if (it.next() == listener) return; };            \r
+               listeners.add(listener);            \r
+       }\r
+\r
+       public void removeListener(DLinkModelListener listener) {\r
+           if (listeners == null) return;          \r
+           Iterator it = listeners.iterator();\r
+               while (it.hasNext()) {\r
+                   if (it.next() == listener){\r
+                       it.remove();\r
+                       return;\r
+                   }           \r
+               }                       \r
+       }\r
+       //=========================================================================/\r
+       protected void fireChanges(){\r
+           if (listeners==null) return;\r
+           Iterator it = listeners.iterator();\r
+               while (it.hasNext()) \r
+                  ((DLinkModelListener)(it.next())).shapeChanged(this, ANY);\r
+       }\r
+       \r
+}\r
+\r
diff --git a/support/sdk/java/net/tinyos/mviz/DLinkModelListener.java b/support/sdk/java/net/tinyos/mviz/DLinkModelListener.java
new file mode 100644 (file)
index 0000000..4432f24
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Copyright (c) 2006 Stanford University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Stanford University nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package net.tinyos.mviz;\r
+\r
+\r
+import java.util.EventListener;\r
+\r
+public interface DLinkModelListener{\r
+    public void shapeChanged(DLinkModel changed, int type); \r
+}\r
diff --git a/support/sdk/java/net/tinyos/mviz/DMote.java b/support/sdk/java/net/tinyos/mviz/DMote.java
new file mode 100644 (file)
index 0000000..f192e0f
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 2006 Stanford University.\r * All rights reserved.\r *\r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * - Redistributions of source code must retain the above copyright\r *   notice, this list of conditions and the following disclaimer.\r * - Redistributions in binary form must reproduce the above copyright\r *   notice, this list of conditions and the following disclaimer in the\r *   documentation and/or other materials provided with the\r *   distribution.\r * - Neither the name of the Stanford University nor the names of\r *   its contributors may be used to endorse or promote products derived\r *   from this software without specific prior written permission.\r *\r * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r * OF THE POSSIBILITY OF SUCH DAMAGE.\r */\r\rpackage net.tinyos.mviz;\r\rimport java.awt.*;\r\r\rpublic class DMote\rextends DShape \rimplements DMoteModelListener\r{\r    \r    private DDocument document;\r    private DMoteModel model;\r    \r    public DMote(DMoteModel model, DDocument document, DLayer layer) {\r        super(model, document, layer);\r    this.document = document;\r      this.model = model;\r    }\r    \r\r    static int counter =0;\r    public void paintShape(Graphics g) {\r    int x = model.getLocX();\r       int y = model.getLocY();\r       //System.out.println("Mode " + layer.paintMode);\r       switch(layer.paintMode){\r       case DLayer.IMG:\r           Image img = model.getImage();\r          java.awt.MediaTracker tracker = new java.awt.MediaTracker(this);\r       tracker.addImage(img, 0);\r      if (document.selected == model) {\r          g.setColor(Color.RED);\r         g.fillOval(x-22, y-22, 44, 44);\r            }\r      g.drawImage(img, x-20, y-20, 40, 40, document.canvas);\r         try {tracker.waitForAll();}\r            catch(InterruptedException e){} \r       //System.out.println("Draw image " + img + " " + x + " " + y + " " + img.getHeight(document.canvas) + " " + tracker.isErrorAny());\r\r            //img = model.getIcon().getImage();\r            //System.out.println("Draw image " + img + " " + x + " " + y);\r         //document.canvas.getGraphics().drawImage(img, x, y, this.model.root);\r         break;\r     case DLayer.OVAL:\r          if (document.selected != model) {\r          g.setColor(Color.GRAY);\r            }\r      else {\r             g.setColor(Color.RED);\r     }\r      counter++;\r     g.fillOval(x-20, y-20, 40, 40);\r        break;\r     case DLayer.TXT_MOTE:\r      g.setFont(new Font("Helvetica", Font.PLAIN, 8));\r       g.setColor(Color.BLACK);\r       g.drawString(document.sensed_motes.elementAt(layer.index) + ": " + (int)model.getValue(layer.index), x+22, y-2);\r       break;\r     default:\r       }\r\r    }\r\r}\r\r\r
\ No newline at end of file
diff --git a/support/sdk/java/net/tinyos/mviz/DMoteModel.java b/support/sdk/java/net/tinyos/mviz/DMoteModel.java
new file mode 100644 (file)
index 0000000..d430818
--- /dev/null
@@ -0,0 +1,233 @@
+/*\r
+ * Copyright (c) 2006 Stanford University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Stanford University nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package net.tinyos.mviz;\r
+\r
+// DShapeModel.java\r
+/*\r
+  Store the data state for a single shape:\r
+  type, two points, color\r
+  Supports DShapeModelListeners.\r
+*/\r
+import java.awt.*;\r
+\r
+import javax.swing.*;\r
+import java.util.*;\r
+import java.awt.event.*;\r
+import java.io.*;\r
+\r
+\r
+class DMoteModel \r
+    extends Object \r
+    implements Serializable {\r
+\r
+    public static final int VALUE = 0;\r
+    public static final int MOTION = 1;\r
+    public static final int ANY = 1;\r
+       \r
+       \r
+    public DDocument root;\r
+    transient private ArrayList listeners;\r
+    \r
+    protected int x, y, id;\r
+    protected float[] values;\r
+    protected Color[] colors;\r
+    protected int[] sizes;\r
+    \r
+    protected int SHAPE_SIZE_MAX = 100;\r
+    protected int COLOR_MAX = 230;\r
+    \r
+    \r
+       \r
+    public DMoteModel(int id, int x, int y, float[] values, DDocument root) {\r
+        this.root = root;\r
+        this.x = x;\r
+        this.y = y;\r
+       this.id = id;\r
+       \r
+        values = new float[root.sensed_motes.size()];\r
+        colors = new Color[root.sensed_motes.size()];\r
+        sizes = new int[root.sensed_motes.size()];\r
+        \r
+        for (int i=0; i<values.length; i++){\r
+            colors[i] = setColor(values[i]);\r
+        }\r
+        for (int i=0; i<values.length; i++){\r
+            sizes[i] = setShapeSize(values[i]);\r
+        }\r
+        \r
+        listeners = null;\r
+    }\r
+\r
+       \r
+    public DMoteModel(DDocument root, int id, String name){\r
+       \r
+    }\r
+       \r
+    public DMoteModel(int id, Random rand, DDocument root){\r
+        this.root = root;\r
+       this.id = id;\r
+               \r
+        x = 20 + rand.nextInt(root.canvas.getWidth() - 20);\r
+        y = 20 + rand.nextInt(root.canvas.getHeight()- 20);\r
+        \r
+        values = new float[root.sensed_motes.size()];\r
+       \r
+        colors = new Color[root.sensed_motes.size()];\r
+        sizes = new int[root.sensed_motes.size()];\r
+        \r
+        for (int i=0; i<root.sensed_motes.size(); i++){\r
+            values[i] = rand.nextFloat()*1000;     \r
+            colors[i] = setColor(values[i]);\r
+            sizes[i] = setShapeSize(values[i]);\r
+        }   \r
+        \r
+        listeners = null;\r
+    }\r
+    \r
+    public int getId() {\r
+       return id;\r
+    }\r
+    \r
+    public Color setColor(float value){\r
+        int color = (int)(value)%COLOR_MAX;\r
+        return new Color(color+15, color, color+25);\r
+    }\r
+    public int setShapeSize(float value){\r
+        return SHAPE_SIZE_MAX;\r
+        //return (int)(value/root.maxValues[root.selectedFieldIndex] * SHAPE_SIZE_MAX);\r
+    }    \r
+       \r
+    public float getValue(int index) {\r
+       if (values.length <= index) {\r
+           return 0;\r
+       }\r
+       else {\r
+           return(values[index]);\r
+       }\r
+    }\r
+\r
+    public boolean setMoteValue(String field, int value){\r
+       int index = root.sensed_motes.indexOf(field);\r
+       if (index < 0) return false;\r
+       colors[index] = setColor((float)value);\r
+       setValue(index, (float) value);\r
+       return true;\r
+    }\r
+\r
+    \r
+    public int getX() { return(x); }\r
+    public int getY() { return(y); }\r
+    public ImageIcon getIcon(){ return root.icon; }\r
+       \r
+    public void setValue(int index, float value){\r
+       values[index] = value;\r
+       fireChanges();\r
+    }    \r
+    public void applyDeltas(int dx, int dy) {        \r
+       x += dx;\r
+       y += dy;\r
+       fireChanges();\r
+    }\r
+    public Image getImage() {\r
+       return root.image;\r
+    }\r
+    public int getWidth(int index) {\r
+       return getIcon().getImage().getWidth(this.root);\r
+       //return sizes[index];\r
+    }  \r
+    public int getHeight(int index) {\r
+       return getIcon().getImage().getHeight(this.root);\r
+       //return sizes[index];\r
+    }  \r
+    public int getLeft(){\r
+       return getLocX() - getWidth(0)/2;\r
+    }\r
+    public int getTop(){\r
+       return getLocY() - getHeight(0)/2;\r
+    } \r
+    public int getLocX() {\r
+       return x;\r
+    }  \r
+    public int getLocY() {\r
+       return y;\r
+    }          \r
+    public Color getColor(int index) { \r
+       return colors[index]; \r
+    }\r
+       \r
+       \r
+    public void addListener(DMoteModelListener listener) {\r
+       if (listeners == null) listeners = new ArrayList();\r
+       Iterator it = listeners.iterator();\r
+       while (it.hasNext()) { if (it.next() == listener) return; };            \r
+       listeners.add(listener);            \r
+    }\r
+\r
+    public void removeListener(DMoteModelListener listener) {\r
+       if (listeners == null) return;      \r
+       Iterator it = listeners.iterator();\r
+       while (it.hasNext()) {\r
+           if (it.next() == listener){\r
+               it.remove();\r
+               return;\r
+           }           \r
+       }                       \r
+    }\r
+    //=========================================================================/\r
+    protected void fireChanges(){\r
+       if (listeners==null) return;\r
+       Iterator it = listeners.iterator();\r
+       while (it.hasNext()) \r
+           ((DMoteModelListener)(it.next())).shapeChanged(this, ANY);\r
+    }\r
+    public void requestRepaint(){\r
+       fireChanges();\r
+    }\r
+       \r
+    //=========================================================================/\r
+    public void move(int x, int y){\r
+        this.x = x;\r
+        this.y = y;\r
+       fireChanges();      \r
+    }\r
+\r
+    public boolean equals(Object o) {\r
+       if (o instanceof DMoteModel) {\r
+           DMoteModel dm = (DMoteModel)o;\r
+           if (dm.getId() == getId()) {\r
+               return true;\r
+           }\r
+       }\r
+       return false;\r
+    }\r
+}\r
+\r
diff --git a/support/sdk/java/net/tinyos/mviz/DMoteModelListener.java b/support/sdk/java/net/tinyos/mviz/DMoteModelListener.java
new file mode 100644 (file)
index 0000000..2fbb5d4
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Copyright (c) 2006 Stanford University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Stanford University nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package net.tinyos.mviz;\r
+\r
+\r
+import java.util.EventListener;\r
+\r
+public interface DMoteModelListener{\r
+    public void shapeChanged(DMoteModel changed, int type); \r
+}\r
diff --git a/support/sdk/java/net/tinyos/mviz/DNavigate.java b/support/sdk/java/net/tinyos/mviz/DNavigate.java
new file mode 100644 (file)
index 0000000..f0464eb
--- /dev/null
@@ -0,0 +1,212 @@
+/*\r
+ * Copyright (c) 2006 Stanford University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Stanford University nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package net.tinyos.mviz;\r
+\r
+\r
+// DDocument.java\r
+\r
+import java.awt.*;\r
+\r
+import javax.imageio.ImageIO;\r
+import javax.swing.*;\r
+\r
+import java.util.*;\r
+import java.awt.event.*;\r
+import java.io.*;\r
+\r
+import javax.swing.table.*;\r
+import java.awt.image.*;\r
+\r
+\r
+// Standard imports for XML\r
+import javax.xml.parsers.*;\r
+import org.xml.sax.*;\r
+import org.w3c.dom.*;\r
+\r
+\r
+public class DNavigate extends JPanel implements ActionListener{\r
+    private DDocument parent;\r
+    protected ArrayList layers = new ArrayList();\r
+    private int _tmp_i = 0;\r
+    protected int totalLayers = 0;\r
+       \r
+    private int default_width = 600;\r
+    private int default_height = 600;\r
+    \r
+    public DNavigate(Vector label_motes, Vector label_links, DDocument parent){\r
+               this.parent = parent;\r
+               BoxLayout layout = new BoxLayout(this,BoxLayout.PAGE_AXIS);\r
+               this.setLayout(layout);\r
+               //this.setBackground(new Color(10,100,200));\r
+\r
+               totalLayers = 2 * label_motes.size() + label_links.size();\r
+               \r
+               this._tmp_i = 0;\r
+               addLayer(label_motes, DLayer.MOTE, parent.motes);\r
+               addLayer(label_links, DLayer.LINK, parent.links);\r
+               addLayer(label_motes, DLayer.FIELD, parent.motes);      \r
+               updateLayerIndex(false);\r
+\r
+\r
+               // debug prints\r
+               Iterator it = layers.iterator();\r
+               while (it.hasNext()){\r
+                   DLayer m = (DLayer)it.next();\r
+                   //System.out.println("setting layer: zIndex=" + m.z_index + ", index=" + m.zIndex);\r
+               }\r
+        \r
+       }\r
+\r
+    protected void addMote(DMoteModel model){\r
+       Iterator it = layers.iterator();\r
+       while(it.hasNext()){\r
+           DLayer layer = (DLayer)it.next();\r
+           layer.addMote(model, true);\r
+       }\r
+   }\r
+       \r
+       private void addLayer(Vector labels, int type, ArrayList models){\r
+           for (int i=0; i<labels.size(); i++, _tmp_i++){\r
+               DLayer d = new DLayer(_tmp_i, i, (String)labels.elementAt(i), type, parent, models, this);\r
+               this.add(d);\r
+               layers.add(d);\r
+           }\r
+       }\r
+       \r
+       private void updateLayerIndex(boolean repaint){\r
+               int length = layers.size();\r
+               Iterator it = layers.iterator();\r
+               int i = 0;\r
+               while (it.hasNext()){\r
+                   DLayer d = (DLayer)it.next();\r
+                   d.updateIndex(i, repaint);\r
+                   ++i;\r
+        }\r
+       }\r
+       \r
+       public void redrawNavigator(){\r
+           //System.out.println("Redrawing navigator.");\r
+           Iterator it = layers.iterator();\r
+           while (it.hasNext()){\r
+               remove((DLayer)it.next());\r
+           }\r
+           it = layers.iterator();\r
+           while (it.hasNext()){\r
+               add((DLayer)it.next());\r
+           }\r
+          \r
+           revalidate();\r
+           //repaint();\r
+           //parent.repaint();\r
+           //parent.canvas.repaint();\r
+           redrawAllLayers();\r
+       }\r
+       \r
+       public void moveLayerUp(int zIndex){\r
+               if (zIndex == 0){ return; }\r
+               DLayer d = (DLayer) layers.remove(zIndex);\r
+               layers.add(zIndex-1, d);\r
+               updateLayerIndex(true);\r
+               redrawNavigator();\r
+               redrawAllLayers(); \r
+       }\r
+       \r
+       public void moveLayerDown(int zIndex){\r
+               if (zIndex == layers.size()-1){ return; }\r
+               DLayer d = (DLayer) layers.remove(zIndex);\r
+               layers.add(zIndex+1, d);\r
+               updateLayerIndex(true);\r
+               redrawNavigator();\r
+               redrawAllLayers();\r
+       }\r
+       \r
+       public void init(){\r
+               Iterator it = layers.iterator();\r
+               while (it.hasNext()){\r
+                   DLayer layer = (DLayer)it.next();\r
+                   layer.init();\r
+               }\r
+       }\r
+\r
+       \r
+\r
+    public void paint() {\r
+       //System.out.println("Painting navigator");\r
+       redrawNavigator();\r
+       Iterator it = layers.iterator();\r
+    }\r
+       \r
+    public void actionPerformed(ActionEvent e) {\r
+       // TODO Auto-generated method stub\r
+       \r
+    }\r
+\r
+    \r
+    private long currentSecond = -1;\r
+    private long PERIOD = 500;\r
+    \r
+    protected void redrawAllLayers(){\r
+       Date date = new Date();\r
+       if (date.getTime() - currentSecond < PERIOD){\r
+           //System.out.println("time: " + (date.getTime() - currentSecond));\r
+           return;\r
+       } else {\r
+           currentSecond = date.getTime();\r
+       }\r
+           \r
+       int start = totalLayers-1;\r
+       for (int i=0; i<totalLayers; i++){\r
+           DLayer a = (DLayer)layers.get(i);\r
+           if (a.isFieldSelected()){\r
+               start = a.zIndex;\r
+               break;\r
+           }\r
+       }\r
+       DLayer bg = (DLayer)layers.get(start);\r
+       Image offscreen = new BufferedImage(parent.canvas.getWidth(), parent.canvas.getHeight(), BufferedImage.TYPE_INT_ARGB);\r
+       Graphics g = offscreen.getGraphics();\r
+       Graphics2D g2d = (Graphics2D)g;\r
+       g2d.clearRect(0, 0, parent.canvas.getWidth(), parent.canvas.getHeight());\r
+       g2d.fillRect(0, 0, parent.canvas.getWidth(), parent.canvas.getHeight());\r
+\r
+       for (int i=start; i>=0; i--){\r
+           DLayer a = (DLayer)layers.get(i);\r
+           a.repaintLayer(g);\r
+       }\r
+       parent.canvas.getGraphics().drawImage(offscreen, 0, 0, this);\r
+    }\r
+\r
+    public void update(Graphics g) {\r
+       paint(g);\r
+    }\r
+           \r
+}\r
diff --git a/support/sdk/java/net/tinyos/mviz/DShape.java b/support/sdk/java/net/tinyos/mviz/DShape.java
new file mode 100644 (file)
index 0000000..a4222af
--- /dev/null
@@ -0,0 +1,150 @@
+/*\r
+ * Copyright (c) 2006 Stanford University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Stanford University nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package net.tinyos.mviz;\r
+\r
+\r
+// DShape.java\r
+import java.awt.*;\r
+import java.util.*;\r
+import javax.swing.*;\r
+import java.awt.event.*;\r
+\r
+abstract class DShape \r
+extends JComponent \r
+implements DMoteModelListener\r
+{\r
+       \r
+       protected DMoteModel model;\r
+       protected DDocument document;\r
+       public Image img;\r
+       \r
+\r
+       \r
+    // remember the last point for mouse tracking\r
+       private int lastX, lastY;\r
+       protected DLayer layer;\r
+       \r
+       // Move or Resize ?\r
+       private int action;\r
+    private static final int MOVE = 0;\r
+       //=========================================================================//\r
+       public DShape(DMoteModel model, DDocument document, DLayer layer) {\r
+               super();\r
+               this.model = model;\r
+               this.img = document.image;\r
+               this.document = document;\r
+               this.layer = layer;\r
+               model.addListener(this);\r
+\r
+               addMouseMotionListener( \r
+                       new MouseMotionAdapter() \r
+                       {\r
+                           public void mouseDragged(MouseEvent e) {\r
+                               \r
+                               int x = e.getX()+getX();\r
+                               int y = e.getY()+getY();\r
+                               // compute delta from last point\r
+                               int dx = x-lastX;\r
+                               int dy = y-lastY;\r
+                               lastX = x;\r
+                               lastY = y;\r
+                               \r
+                               switch(action){\r
+                               case MOVE: DoAction(dx, dy); break;\r
+                               }\r
+                           }\r
+                       }\r
+               );\r
+               \r
+               synchToModel();         \r
+       }\r
+   \r
+       //=========================================================================//\r
+       public DMoteModel getModel() {\r
+               return(model);\r
+       }\r
+       \r
+       //=========================================================================//\r
+       public void shapeChanged(DMoteModel changed, int type) {\r
+           synchToModel();\r
+           repaint();\r
+       }\r
+       //=========================================================================//\r
+       public abstract void paintShape(Graphics g);\r
+       //=========================================================================//\r
+    public void paintComponent(Graphics g) {\r
+    }\r
+       //=========================================================================//\r
+       private void DetermineAction(int x, int y){\r
+        action = MOVE;         \r
+       }\r
+       //=========================================================================//\r
+       private void DoAction(int dx, int dy){\r
+           model.applyDeltas(dx, dy);\r
+       }\r
+       //=========================================================================//\r
+       private void synchToModel(){\r
+               int x=0, y=0, w=0, h=0;\r
+               switch(layer.paintMode){\r
+               case DLayer.IMG:\r
+               x = model.getLocX();\r
+               y = model.getLocY();\r
+               //w = model.getWidth(layer.index);\r
+               //h = model.getHeight(layer.index);\r
+               w = 250;\r
+               h = 250;\r
+                       break;\r
+               case DLayer.OVAL:\r
+                       x = model.getLocX();\r
+               y= model.getLocY();\r
+               w = 10;\r
+               h = 10;\r
+                       break;\r
+               case DLayer.TXT_MOTE:\r
+                       x = model.getLocX();\r
+               y= model.getLocY();\r
+               w = 250;\r
+               h = 250;\r
+                       break;\r
+               }\r
+               //setLocation(x, y);\r
+               setBounds(0, 0, 0, 0);\r
+       }\r
+       //=========================================================================//\r
+       private void selected(){\r
+           document.setSelected(this);     \r
+       }\r
+\r
+}\r
+\r
+\r
+\r
diff --git a/support/sdk/java/net/tinyos/mviz/DShapeModel.java b/support/sdk/java/net/tinyos/mviz/DShapeModel.java
new file mode 100644 (file)
index 0000000..37e548f
--- /dev/null
@@ -0,0 +1,218 @@
+/*\r
+ * Copyright (c) 2006 Stanford University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Stanford University nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package net.tinyos.mviz;\r
+\r
+\r
+// DShapeModel.java\r
+/*\r
+ Store the data state for a single shape:\r
+  type, two points, color\r
+ Supports DShapeModelListeners.\r
+*/\r
+import java.awt.*;\r
+\r
+import javax.swing.*;\r
+import java.util.*;\r
+import java.awt.event.*;\r
+import java.io.*;\r
+\r
+\r
+class DShapeModel extends Object implements Serializable {\r
+\r
+       // The 5 standard things for a DShapeModel to store\r
+    protected char type;\r
+    protected int x1, y1, x;\r
+    protected int x2, y2, y;\r
+    protected Color fill; \r
+    \r
+    protected float value;\r
+    \r
+    protected int HALF_WIDTH = 20;\r
+    protected int HALF_HEIGHT = 20;\r
+\r
+    // NOTE: "transient" -- not serialized\r
+    transient private ArrayList listeners;\r
+      \r
+    public DShapeModel(char type, int x, int y, float value) {\r
+        this.type = type;\r
+        this.x = x;\r
+        this.y = y;\r
+        this.value = value;\r
+        int color = (int)(value)%230;\r
+        this.fill = new Color(color+15, color, color+25);\r
+        \r
+        listeners = null;\r
+        \r
+        this.x1 = x - this.HALF_WIDTH;\r
+        this.x2 = x + this.HALF_WIDTH;\r
+        this.y1 = y - this.HALF_HEIGHT;\r
+        this.y2 = y + this.HALF_HEIGHT;\r
+    }\r
+    \r
+    // Construct a DShapeModel with default size.\r
+       public DShapeModel(char type, Color color) {\r
+               this(type, 50, 50, 89, 89, color);\r
+       }\r
+    \r
+    public DShapeModel(){\r
+        this('m', new Color(12,24,48));\r
+    }\r
+\r
+       public DShapeModel(char type, int x1, int y1, int x2, int y2, Color fill) {\r
+               this.type = type;\r
+               this.x1 = x1;\r
+               this.y1 = y1;\r
+               this.x2 = x2;\r
+               this.y2 = y2;\r
+               this.fill = fill;\r
+               \r
+               listeners = null;\r
+       }\r
+       \r
+       public DShapeModel(DShapeModel other) {\r
+               this.type = other.type;\r
+               this.x1 = other.x1;\r
+               this.y1 = other.y1;\r
+               this.x2 = other.x2;\r
+               this.y2 = other.y2;\r
+               this.fill = other.fill;\r
+               \r
+               listeners = null;\r
+       }\r
+       \r
+       public char getType() { return(type); }\r
+       \r
+       public int getX1() { return(x1); }\r
+       public int getY1() { return(y1); }\r
+       public int getX2() { return(x2); }\r
+       public int getY2() { return(y2); }\r
+       \r
+       \r
+       // Below here, code not done\r
+       \r
+       \r
+       public void applyDeltas(int dx1, int dy1, int dx2, int dy2) {\r
+           x1 += dx1;\r
+           x2 += dx2;\r
+           y1 += dy1;\r
+           y2 += dy2;\r
+        \r
+        x += dx1;\r
+        y += dy1;\r
+           fireChanges();\r
+       }\r
+       \r
+       public int getWidth() {\r
+           return Math.abs(x2-x1)+1;\r
+       }\r
+       \r
+       public int getHeight() {\r
+           return Math.abs(y2-y1)+1;\r
+       }\r
+       \r
+       public int getLocX() {\r
+           return Math.min(x1, x2);\r
+       }\r
+       \r
+       public int getLocY() {\r
+           return Math.min(y1, y2);\r
+       }\r
+                       \r
+       \r
+       \r
+       public Color getColor() { return(fill); }\r
+       public void setColor(Color color) {\r
+           if (fill.equals(color)) return;\r
+           fill = color;\r
+           fireChanges();\r
+       }\r
+       \r
+       \r
+       public void addListener(DShapeModelListener listener) {\r
+           if (listeners == null) listeners = new ArrayList();\r
+           Iterator it = listeners.iterator();\r
+               while (it.hasNext()) {\r
+                   if (it.next() == listener)\r
+                       return;\r
+               }\r
+               listeners.add(listener);            \r
+       }\r
+\r
+       public void removeListener(DShapeModelListener listener) {\r
+           if (listeners == null) return;          \r
+           Iterator it = listeners.iterator();\r
+               while (it.hasNext()) {\r
+                   if (it.next() == listener){\r
+                       it.remove();\r
+                       return;\r
+                   }           \r
+               }                       \r
+       }\r
+       //=========================================================================/\r
+       protected void fireChanges(){\r
+           if (listeners==null) return;\r
+           Iterator it = listeners.iterator();\r
+               while (it.hasNext()) \r
+                  ((DShapeModelListener)(it.next())).shapeChanged(this);\r
+       }\r
+       //=========================================================================/\r
+       public void rotate(){\r
+           // Get old height/width and locations.\r
+           int x = getLocX();  int y = getLocY();\r
+           int w = getWidth(); int h = getHeight();\r
+           int dL = (h/2-w/2);\r
+           // Get the locations right.\r
+           x-=dL;      y+= dL;\r
+           x1=x;       x2=x+h-1;\r
+           y1=y;       y2=y+w-1;       \r
+               fireChanges();\r
+       }\r
+       //=========================================================================/\r
+       // Rotation with respect to center.\r
+       public void scale(int magnitude){\r
+           if (x1<x2){ x1-=magnitude;  x2+=magnitude;\r
+           }else{              x1+=magnitude;  x2-=magnitude;  }\r
+           if (y1<y2){ y1-=magnitude;  y2+=magnitude;\r
+           }else{              y1+=magnitude;  y2-=magnitude;  }    \r
+           fireChanges();\r
+       }\r
+       //=========================================================================/\r
+       public void move(int x, int y){\r
+           int h = getHeight();\r
+           int w = getWidth();\r
+           x1=x; x2=x+w-1;\r
+           y1=y; y2=y+h-1;\r
+           fireChanges();          \r
+       }\r
+       \r
+}\r
+\r
diff --git a/support/sdk/java/net/tinyos/mviz/DShapeModelListener.java b/support/sdk/java/net/tinyos/mviz/DShapeModelListener.java
new file mode 100644 (file)
index 0000000..c4abc02
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+ * Copyright (c) 2006 Stanford University.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Stanford University nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD\r
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package net.tinyos.mviz;\r
+\r
+import java.util.EventListener;\r
+\r
+// DShapeModelListener.java\r
+/*\r
+ Interface to listen for shape change notifications.\r
+ As a courtesy, the notification includes a pointer to the\r
+ model that changed. However, there is not detail about\r
+ what the exact change was.\r
+*/\r
+\r
+public interface DShapeModelListener{\r
+    public void shapeChanged(DShapeModel changed); \r
+}\r
diff --git a/support/sdk/java/net/tinyos/mviz/DataModel.java b/support/sdk/java/net/tinyos/mviz/DataModel.java
new file mode 100644 (file)
index 0000000..94cc91c
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.tinyos.mviz;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+public class DataModel {
+    Vector packetClasses = new Vector();
+    Vector fields = new Vector();
+    Vector links = new Vector();
+
+    public DataModel(Vector messageNames) {
+       createPackets(messageNames);
+       parseFieldsAndLinks();
+    }
+
+    public Vector fields() {
+       return fields;
+    }
+
+    public Vector links() {
+       return links;
+    }
+       
+    private void createPackets(Vector messageNames) {
+       for (int i = 0; i < messageNames.size(); i++) {
+           try {
+               System.out.println("Making " + messageNames.elementAt(i));
+               Class c = Class.forName((String)messageNames.elementAt(i));
+               packetClasses.add(c);
+           }
+           catch (ClassNotFoundException ex) {
+               System.err.println("Unable to find message type " + messageNames.elementAt(i) + ": please check your CLASSPATH.");
+           }
+       }
+    }
+
+    private boolean isSubClass(Class subC, Class superC) {
+       if (subC == superC) {return false;}
+       for (Class tmp = subC.getSuperclass(); tmp != null; tmp = tmp.getSuperclass()) {
+           if (tmp.equals(superC)) {
+               return true;
+           }
+       }
+       return false;
+    }
+
+    private void parseFieldsAndLinks() {
+       net.tinyos.message.Message msg = new net.tinyos.message.Message(0);
+       Class messageClass = msg.getClass();
+       for (int i = 0; i < packetClasses.size(); i++) {
+           Class pkt = (Class)packetClasses.elementAt(i);
+           if (!(isSubClass(pkt, messageClass))) {
+               continue;
+           }
+           loadFieldsAndLinks(pkt);
+       }
+    }
+
+    private void loadFieldsAndLinks(Class pkt) {
+       Method[] methods = pkt.getMethods();
+       for (int i = 0; i < methods.length; i++) {
+           Method method = methods[i];
+           String name = method.getName();
+           if (name.startsWith("get_") && !name.startsWith("get_link")) {
+               name = name.substring(4); // Chop off "get_"
+               Class[] params = method.getParameterTypes();
+               if (params.length == 0 && !method.getReturnType().isArray()) {
+                   loadField(name, method, method.getReturnType());
+                   System.out.println("Loading " + name);
+               }
+           }
+           else if (name.startsWith("get_link_") && name.endsWith("_value")) {
+               name = name.substring(9); // chop off "get_link_"
+               name = name.substring(0, name.length() - 6); // chop off "_value"
+               Class[] params = method.getParameterTypes();
+               if (params.length == 0) {
+                   loadLink(name, method, method.getReturnType());
+               }
+           }
+       }
+    }
+
+    private void loadField(String name, Method method, Class param) {
+       fields.add(name);
+    }
+    private void loadLink(String name, Method method, Class param) {
+       System.out.println("Loading link <" + name + ">");
+       links.add(name);
+    }
+}
diff --git a/support/sdk/java/net/tinyos/mviz/Makefile b/support/sdk/java/net/tinyos/mviz/Makefile
new file mode 100644 (file)
index 0000000..7ea734f
--- /dev/null
@@ -0,0 +1,6 @@
+# Top-level Makefile for tools/java 
+
+SUBDIRS = 
+ROOT = ../../..
+include $(ROOT)/Makefile.include
+
diff --git a/support/sdk/java/net/tinyos/mviz/MessageInput.java b/support/sdk/java/net/tinyos/mviz/MessageInput.java
new file mode 100644 (file)
index 0000000..26d1e46
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.tinyos.mviz;
+
+import java.lang.reflect.*;
+import java.io.*;
+import java.util.*;
+
+import net.tinyos.message.*;
+import net.tinyos.packet.*;
+import net.tinyos.util.*;
+
+
+public class MessageInput implements net.tinyos.message.MessageListener {
+    private Vector msgVector = new Vector();
+    private MoteIF moteIF;
+    private DDocument document;
+    
+    public MessageInput(Vector packetVector, String commSource, DDocument doc) {
+       document = doc;
+       loadMessages(packetVector);
+       createSource(commSource);
+       installListeners();
+    }
+
+    private void loadMessages(Vector packetVector) {
+       for (int i = 0; i < packetVector.size(); i++) {
+           String className = (String)packetVector.elementAt(i);
+         try {
+           Class c = Class.forName(className);
+           Object packet = c.newInstance();
+           Message msg = (Message)packet;
+           msgVector.addElement(msg);
+         }
+         catch (Exception e) {
+             System.err.println(e);
+         }
+       }
+    }
+
+    private void createSource(String source) {
+       if (source != null) {
+           moteIF = new MoteIF(BuildSource.makePhoenix(source, PrintStreamMessenger.err));
+       }
+       else {
+           moteIF = new MoteIF(BuildSource.makePhoenix(PrintStreamMessenger.err));
+       }
+    }
+
+    private void addMsgType(Message msg) {
+       moteIF.registerListener(msg, this);
+    }
+    
+    private void installListeners() {
+       Enumeration msgs = msgVector.elements();
+       while (msgs.hasMoreElements()) {
+           Message m = (Message)msgs.nextElement();
+           this.addMsgType(m);
+       }
+    }
+
+    public void start() {}
+   
+    public void messageReceived(int to, Message message) {
+       Hashtable table = new Hashtable();
+       Hashtable linkTable = new Hashtable();
+       //System.out.println("Received message:");
+       //System.out.println(message);
+
+       Class pktClass = message.getClass();
+       Method[] methods = pktClass.getMethods();
+       for (int i = 0; i < methods.length; i++) {
+           Method method = methods[i];
+           String name = method.getName();
+           Class[] params = method.getParameterTypes();
+           Class returnType = method.getReturnType();
+           if (params.length != 0 || returnType.isArray()) {
+               continue;
+           }
+           if (name.startsWith("get_") && !name.startsWith("get_link")) {
+               name = name.substring(4); // Chop off "get_"
+               try {
+                   //System.out.println(name + " returns " + res);
+                   Integer result = (Integer)method.invoke(message, null);
+                   table.put(name, result);
+               }
+               catch (java.lang.IllegalAccessException exc) {
+                   System.err.println("Unable to access field " + name);
+               }
+               catch (java.lang.reflect.InvocationTargetException exc) {
+                   System.err.println("Unable to access target " + name);
+               }
+           }
+           else if (name.startsWith("get_link_")) {
+               name = name.substring(9); // chop off "get_link_"
+               try {
+                   Integer result = (Integer)method.invoke(message, null);
+                   linkTable.put(name, result);
+               }
+               catch (java.lang.IllegalAccessException exc) {
+                   System.err.println("Unable to access field " + name);
+               }
+               catch (java.lang.reflect.InvocationTargetException exc) {
+                   System.err.println("Unable to access target " + name);
+               }
+           }
+       }
+       if (table.containsKey("origin")) {
+           Integer origin = (Integer)table.get("origin");
+           //table.remove("origin");
+           Enumeration elements = table.keys();
+           while (elements.hasMoreElements()) {
+               String key = (String)elements.nextElement();
+               Integer value = (Integer)table.get(key);
+               document.setMoteValue(origin.intValue(), key, value.intValue());
+           }
+           elements = linkTable.keys();
+           while (elements.hasMoreElements()) {
+               String key = (String)elements.nextElement();
+               if (!key.endsWith("_value")) {
+                   continue;
+               }
+               Integer value = (Integer)linkTable.get(key);
+               key = key.substring(0, key.length() - 6); // chop off "_value"
+               String addrkey = key + "_addr";
+               if (!linkTable.containsKey(addrkey)) {
+                   continue;
+               }
+               Integer addr = (Integer)linkTable.get(addrkey);
+               document.setLinkValue(origin.intValue(), addr.intValue(), key, value.intValue());
+           }
+       }
+       else {
+           System.err.println("Could not find origin field, discarding message.");
+       }
+       
+    }
+
+}
diff --git a/support/sdk/java/net/tinyos/mviz/images/tmote_sky.gif b/support/sdk/java/net/tinyos/mviz/images/tmote_sky.gif
new file mode 100644 (file)
index 0000000..f3bd192
Binary files /dev/null and b/support/sdk/java/net/tinyos/mviz/images/tmote_sky.gif differ
diff --git a/support/sdk/java/net/tinyos/mviz/images/tmote_sky.jpg b/support/sdk/java/net/tinyos/mviz/images/tmote_sky.jpg
new file mode 100644 (file)
index 0000000..2c507d6
Binary files /dev/null and b/support/sdk/java/net/tinyos/mviz/images/tmote_sky.jpg differ
diff --git a/support/sdk/java/net/tinyos/mviz/images/tmote_sky.png b/support/sdk/java/net/tinyos/mviz/images/tmote_sky.png
new file mode 100644 (file)
index 0000000..2cf018e
Binary files /dev/null and b/support/sdk/java/net/tinyos/mviz/images/tmote_sky.png differ
index 3910e3fed9a39992bd1c9033ca7b8812acf825cc..8b027ee89f7777c1df1a261e3a62a6766fb07d0b 100644 (file)
Binary files a/support/sdk/java/tinyos.jar and b/support/sdk/java/tinyos.jar differ
diff --git a/tools/tinyos/misc/tos-mviz b/tools/tinyos/misc/tos-mviz
new file mode 100755 (executable)
index 0000000..94e16cd
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/bash
+#
+# $Id$ 
+#
+
+printenv CLASSPATH
+java net.tinyos.mviz.DDocument $*
+
diff --git a/tools/tinyos/misc/tos-mviz.1 b/tools/tinyos/misc/tos-mviz.1
new file mode 100644 (file)
index 0000000..a619c29
--- /dev/null
@@ -0,0 +1,18 @@
+.TH tos-mviz 1 "Oct 24, 2006"
+.LO 1
+.SH NAME
+
+tos-mviz - Launch MViz, the TinyOS network visualizer 
+.SH SYNOPSIS
+
+\fBtos-mviz\fR [\fB-comm\fR \fIserial-source\fR] \fImig-class\fR [\fImig-class]...
+.SH DESCRIPTION
+
+\fBtos-mviz\fR launches MViz, the TinyOS network visualizer. MViz is a replacement
+for the Surge application of earlier TinyOS versions. MViz reads packets from
+a packet source and displays their data in a GUI. MViz takes the class names of
+mig-generated Java classes as parameters; it parses these packets and displays their
+fields. For MViz to be able to understand a mig packet, it must have an \fIorigin\fR
+field which denotes which node the data is from. Please see TinyOS tutorial 12: MViz,
+for more detail.
+
diff --git a/tools/tinyos/misc/tos-storage-pxa27xp30 b/tools/tinyos/misc/tos-storage-pxa27xp30
new file mode 100755 (executable)
index 0000000..120dd0b
--- /dev/null
@@ -0,0 +1,152 @@
+#!/usr/bin/python
+# -*- python -*-
+# 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
+#
+# @author Jonathan Hui <jhui@archedrock.com>
+# @author Kaisen Lin
+#
+# $Revision$
+# $Date$
+#
+                                  
+from re import match
+from sys import *
+from xml.dom import minidom
+
+NUM_SECTORS = 16
+SECTOR_SIZE = 2097152
+
+volumes = {}
+
+volumeNames = []
+volumeSizes = []
+volumeOffsets = []
+freeSectors = NUM_SECTORS*[ True ]
+
+def error_exit( s ):
+    stderr.write( "ERROR: " + s + "\n" )
+    exit( 2 )
+
+try:
+    dom = minidom.parse( stdin )
+except xml.parsers.expat.ExpatError:
+    error_exit( "input invalid" )
+
+# initialize reserved piece
+volumes [ "PXARESERVED" ] = "blah"
+volumeNames.append( "VOLUME_PXARESERVED" )
+volumeSizes.append( 1 )
+volumeOffsets.append( 0 )
+freeSectors[ 0 ] = False
+
+# extract information
+for volume in dom.documentElement.getElementsByTagName( "volume" ):
+    name = volume.getAttribute( "name" )
+    size = volume.getAttribute( "size" )
+    base = volume.getAttribute( "base" )
+    if name == "":
+        error_exit( "volume has no name" )
+    elif not match( "^[a-zA-Z0-9_]+$", name ):
+        error_exit( "volume has invalid name '%s'" % name )
+    elif volumes.has_key( name ):
+        error_exit( "duplicate volume definition '%s'" % name )
+    else:
+        volumes[ name ] = "blah"
+    
+    if size == "":
+        error_exit( "volume '%s' has no size" % name )
+    try:
+        size = int( size )
+    except ValueError:
+        error_exit( "volume '%s' has invalid size" % name )
+    if base != "":
+        try:
+            base = int( base )
+        except ValueError:
+            error_exit( "volume '%s' has invalid base" % name )
+
+    if ( size & ( SECTOR_SIZE - 1 ) ) != 0:
+        error_exit( "size of volume '%s' is not a multiple of %d" % \
+                    ( name, SECTOR_SIZE ) )
+    if base != "" and ( base & ( SECTOR_SIZE - 1 ) ) != 0:
+        error_exit( "base of volume '%s' is not a multiple of %d" % \
+                    ( name, SECTOR_SIZE ) )
+
+    volumeNames.append( "VOLUME_" + name )
+    volumeSizes.append( size / SECTOR_SIZE )
+    if base == "":
+        volumeOffsets.append( -1 )
+    else:
+        base = base / SECTOR_SIZE
+        volumeOffsets.append( base )
+        for i in range( size / SECTOR_SIZE ):
+            freeSectors[ i + base ] = False
+
+# allocate with first fit policy
+for i in range( len( volumeOffsets ) ):
+    size = volumeSizes[ i ]
+    if volumeOffsets[ i ] == -1:
+        for j in range( NUM_SECTORS ):
+            if freeSectors[ j ]:
+                size -= 1
+                if size == 0:
+                    volumeOffsets[ i ] = j - ( volumeSizes[ i ] - 1 )
+                    break
+            else:
+                size = volumeSizes[ i ]
+        if volumeOffsets[ i ] == -1:
+            raise "Unable to satisfy allocation request."
+        else:
+            for j in range( volumeSizes[ i ] ):
+                freeSectors[ volumeOffsets[ i ] + j ] = False
+
+# output C file
+
+print "#ifndef __STORAGE_VOLUME_H__"
+print "#define __STORAGE_VOLUME_H__"
+print ""
+print "#include \"P30.h\""
+print ""
+
+for i in range( len( volumeNames ) ):
+    print "#define %s %d" % ( volumeNames[ i ], i )
+    print "#define %s %s" % ( volumeNames[ i ] + "_UQ", "unique(\"pxa27xp30.Volume\")" )
+print "#define _V_NUMVOLS_ %d" % ( len( volumeNames ))
+print ""
+        
+print "static const p30_volume_info_t P30_VMAP[ %d ] = {" % \
+      len( volumeNames )
+for i in range( len( volumeNames ) ):
+    print "    { base : %d, size : %d }," % \
+          ( volumeOffsets[ i ], volumeSizes[ i ] )
+print "};"
+
+print ""
+print "#endif"
diff --git a/tools/tinyos/misc/tos-storage-pxa27xp30.1 b/tools/tinyos/misc/tos-storage-pxa27xp30.1
new file mode 100644 (file)
index 0000000..61f065b
--- /dev/null
@@ -0,0 +1,25 @@
+.TH tos-storage-pxa27xp30 1 "July 26, 2006"
+.LO 1
+.SH NAME
+
+tos-storage-pxa27xp30 - Generate storage volume description code
+.SH SYNOPSIS
+
+\fBtos-storage-pxa27xp30\fR
+.SH DESCRIPTION
+
+\fBtos-storage-pxa27xp30\fR reads a user specification describing the
+layout of storage volumes on an embedded P30 flash in the Intel Xscale
+PXA27X series processor, and generates code describing that layout for
+use by the TinyOS 2.0 storage subsystem.  The user specification is in
+XML and is read from standard input. The code is written to standard
+output.
+
+This program is normally invoked automatically by the TinyOS build system
+when your application directory contains a \fBvolumes-pxa27xp30.xml\fR file.
+.SH EXAMPLES
+
+  tos-storage-pxa27xp30 <volumes-pxa27xp30.xml >build/telosb/StorageVolumes.h
+.SH SEE ALSO
+
+.IR tos-storage-pxa27xp30 (1)
diff --git a/tools/tinyos/misc/tos-storage-pxa27xp30.in b/tools/tinyos/misc/tos-storage-pxa27xp30.in
new file mode 100755 (executable)
index 0000000..275b500
--- /dev/null
@@ -0,0 +1,152 @@
+#!@pythonpath@
+# -*- python -*-
+# 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
+#
+# @author Jonathan Hui <jhui@archedrock.com>
+# @author Kaisen Lin
+#
+# $Revision$
+# $Date$
+#
+                                  
+from re import match
+from sys import *
+from xml.dom import minidom
+
+NUM_SECTORS = 16
+SECTOR_SIZE = 2097152
+
+volumes = {}
+
+volumeNames = []
+volumeSizes = []
+volumeOffsets = []
+freeSectors = NUM_SECTORS*[ True ]
+
+def error_exit( s ):
+    stderr.write( "ERROR: " + s + "\n" )
+    exit( 2 )
+
+try:
+    dom = minidom.parse( stdin )
+except xml.parsers.expat.ExpatError:
+    error_exit( "input invalid" )
+
+# initialize reserved piece
+volumes [ "PXARESERVED" ] = "blah"
+volumeNames.append( "VOLUME_PXARESERVED" )
+volumeSizes.append( 1 )
+volumeOffsets.append( 0 )
+freeSectors[ 0 ] = False
+
+# extract information
+for volume in dom.documentElement.getElementsByTagName( "volume" ):
+    name = volume.getAttribute( "name" )
+    size = volume.getAttribute( "size" )
+    base = volume.getAttribute( "base" )
+    if name == "":
+        error_exit( "volume has no name" )
+    elif not match( "^[a-zA-Z0-9_]+$", name ):
+        error_exit( "volume has invalid name '%s'" % name )
+    elif volumes.has_key( name ):
+        error_exit( "duplicate volume definition '%s'" % name )
+    else:
+        volumes[ name ] = "blah"
+    
+    if size == "":
+        error_exit( "volume '%s' has no size" % name )
+    try:
+        size = int( size )
+    except ValueError:
+        error_exit( "volume '%s' has invalid size" % name )
+    if base != "":
+        try:
+            base = int( base )
+        except ValueError:
+            error_exit( "volume '%s' has invalid base" % name )
+
+    if ( size & ( SECTOR_SIZE - 1 ) ) != 0:
+        error_exit( "size of volume '%s' is not a multiple of %d" % \
+                    ( name, SECTOR_SIZE ) )
+    if base != "" and ( base & ( SECTOR_SIZE - 1 ) ) != 0:
+        error_exit( "base of volume '%s' is not a multiple of %d" % \
+                    ( name, SECTOR_SIZE ) )
+
+    volumeNames.append( "VOLUME_" + name )
+    volumeSizes.append( size / SECTOR_SIZE )
+    if base == "":
+        volumeOffsets.append( -1 )
+    else:
+        base = base / SECTOR_SIZE
+        volumeOffsets.append( base )
+        for i in range( size / SECTOR_SIZE ):
+            freeSectors[ i + base ] = False
+
+# allocate with first fit policy
+for i in range( len( volumeOffsets ) ):
+    size = volumeSizes[ i ]
+    if volumeOffsets[ i ] == -1:
+        for j in range( NUM_SECTORS ):
+            if freeSectors[ j ]:
+                size -= 1
+                if size == 0:
+                    volumeOffsets[ i ] = j - ( volumeSizes[ i ] - 1 )
+                    break
+            else:
+                size = volumeSizes[ i ]
+        if volumeOffsets[ i ] == -1:
+            raise "Unable to satisfy allocation request."
+        else:
+            for j in range( volumeSizes[ i ] ):
+                freeSectors[ volumeOffsets[ i ] + j ] = False
+
+# output C file
+
+print "#ifndef __STORAGE_VOLUME_H__"
+print "#define __STORAGE_VOLUME_H__"
+print ""
+print "#include \"P30.h\""
+print ""
+
+for i in range( len( volumeNames ) ):
+    print "#define %s %d" % ( volumeNames[ i ], i )
+    print "#define %s %s" % ( volumeNames[ i ] + "_UQ", "unique(\"pxa27xp30.Volume\")" )
+print "#define _V_NUMVOLS_ %d" % ( len( volumeNames ))
+print ""
+        
+print "static const p30_volume_info_t P30_VMAP[ %d ] = {" % \
+      len( volumeNames )
+for i in range( len( volumeNames ) ):
+    print "    { base : %d, size : %d }," % \
+          ( volumeOffsets[ i ], volumeSizes[ i ] )
+print "};"
+
+print ""
+print "#endif"
diff --git a/tos/chips/atm128/Atm128Uart0C.nc b/tos/chips/atm128/Atm128Uart0C.nc
new file mode 100644 (file)
index 0000000..1767680
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 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
+ * ARCH 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
+ */
+
+/**
+ * @author Alec Woo <awoo@archrock.com>
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+configuration Atm128Uart0C {
+  
+  provides interface StdControl;
+  provides interface UartByte;
+  provides interface UartStream;
+  uses interface Counter<TMicro, uint32_t>;
+  
+}
+
+implementation{
+  
+  components new Atm128UartP() as UartP;
+  StdControl = UartP;
+  UartByte = UartP;
+  UartStream = UartP;
+  UartP.Counter = Counter;
+  
+  components HplAtm128UartC as HplUartC;
+  UartP.HplUartTxControl -> HplUartC.Uart0TxControl;
+  UartP.HplUartRxControl -> HplUartC.Uart0RxControl;
+  UartP.HplUart -> HplUartC.HplUart0;
+  
+  components MainC;
+  MainC.SoftwareInit -> UartP;
+  
+}
diff --git a/tos/chips/atm128/Atm128UartP.nc b/tos/chips/atm128/Atm128UartP.nc
new file mode 100644 (file)
index 0000000..4891e73
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 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
+ * ARCH 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
+ */
+
+/**
+ * @author Alec Woo <awoo@archrock.com>
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#include <Timer.h>
+
+generic module Atm128UartP(){
+  
+  provides interface Init;
+  provides interface StdControl;
+  provides interface UartByte;
+  provides interface UartStream;
+  
+  uses interface StdControl as HplUartTxControl;
+  uses interface StdControl as HplUartRxControl;
+  uses interface HplAtm128Uart as HplUart;
+  uses interface Counter<TMicro, uint32_t>;
+  
+}
+
+implementation{
+  
+  norace uint8_t *m_tx_buf, *m_rx_buf;
+  norace uint16_t m_tx_len, m_rx_len;
+  norace uint16_t m_tx_pos, m_rx_pos;
+  norace uint16_t m_byte_time;
+  
+  command error_t Init.init() {
+    if (PLATFORM_BAUDRATE == 19200UL)
+      m_byte_time = 200; // 1 TMicor ~= 2.12 us, one byte = 417us ~= 200
+    else if (PLATFORM_BAUDRATE == 57600UL)
+      m_byte_time = 68;  // 1 TMicor ~= 2.12 us, one byte = 138us ~= 65
+    return SUCCESS;
+  }
+  
+  command error_t StdControl.start(){
+    call HplUartTxControl.start();
+    call HplUartRxControl.start();
+    return SUCCESS;
+  }
+
+  command error_t StdControl.stop(){
+    call HplUartTxControl.stop();
+    call HplUartRxControl.stop();
+    return SUCCESS;
+  }
+
+  async command error_t UartStream.enableReceiveInterrupt(){
+    call HplUartRxControl.start();
+    return SUCCESS;
+  }
+
+  async command error_t UartStream.disableReceiveInterrupt(){
+    call HplUartRxControl.stop();
+    return SUCCESS;
+  }
+
+  async command error_t UartStream.receive( uint8_t* buf, uint16_t len ){
+    
+    if ( len == 0 )
+      return FAIL;
+    atomic {
+      if ( m_rx_buf )
+       return EBUSY;
+      m_rx_buf = buf;
+      m_rx_len = len;
+      m_rx_pos = 0;
+    }
+    
+    return SUCCESS;
+    
+  }
+
+  async event void HplUart.rxDone( uint8_t data ) {
+
+    if ( m_rx_buf ) {
+      m_rx_buf[ m_rx_pos++ ] = data;
+      if ( m_rx_pos >= m_rx_len ) {
+       uint8_t* buf = m_rx_buf;
+       m_rx_buf = NULL;
+       signal UartStream.receiveDone( buf, m_rx_len, SUCCESS );
+      }
+    }
+    else {
+      signal UartStream.receivedByte( data );
+    }
+    
+  }
+
+  async command error_t UartStream.send( uint8_t *buf, uint16_t len){
+    
+    if ( len == 0 )
+      return FAIL;
+    else if ( m_tx_buf )
+      return EBUSY;
+    
+    m_tx_buf = buf;
+    m_tx_len = len;
+    m_tx_pos = 0;
+    call HplUart.tx( buf[ m_tx_pos++ ] );
+    
+    return SUCCESS;
+    
+  }
+
+  async event void HplUart.txDone() {
+    
+    if ( m_tx_pos < m_tx_len ) {
+      call HplUart.tx( m_tx_buf[ m_tx_pos++ ] );
+    }
+    else {
+      uint8_t* buf = m_tx_buf;
+      m_tx_buf = NULL;
+      signal UartStream.sendDone( buf, m_tx_len, SUCCESS );
+    }
+    
+  }
+
+  async command error_t UartByte.send( uint8_t byte ){
+    call HplUart.tx( byte );
+    while ( !call HplUart.isTxEmpty() );
+    return SUCCESS;
+  }
+  
+  async command error_t UartByte.receive( uint8_t * byte, uint8_t timeout){
+    
+    uint16_t timeout_micro = m_byte_time * timeout + 1;
+    uint16_t start;
+    
+    start = call Counter.get();
+    while ( call HplUart.isRxEmpty() ) {
+      if ( ( (uint16_t)call Counter.get() - start ) >= timeout_micro )
+       return FAIL;
+    }
+    *byte = call HplUart.rx();
+    
+    return SUCCESS;
+    
+  }
+  
+  async event void Counter.overflow() {}
+
+  default async event void UartStream.sendDone( uint8_t* buf, uint16_t len, error_t error ){}
+  default async event void UartStream.receivedByte( uint8_t byte ){}
+  default  async event void UartStream.receiveDone( uint8_t* buf, uint16_t len, error_t error ){}
+
+}
diff --git a/tos/chips/atm128/HplAtm128Uart.nc b/tos/chips/atm128/HplAtm128Uart.nc
new file mode 100644 (file)
index 0000000..fc46b30
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 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
+ * ARCH 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
+ */
+
+/**
+ * @author Alec Woo <awoo@archrock.com>
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+interface HplAtm128Uart {
+  
+  async command error_t enableTxIntr();
+  async command error_t disableTxIntr();
+  async command error_t enableRxIntr();
+  async command error_t disableRxIntr();
+  async command bool isTxEmpty();
+  async command bool isRxEmpty();
+  async command void tx( uint8_t data );
+  async event void txDone();
+  async command uint8_t rx();
+  async event void rxDone( uint8_t data );
+
+}
diff --git a/tos/chips/cc1000_lpl/ByteRadio.nc b/tos/chips/cc1000_lpl/ByteRadio.nc
new file mode 100644 (file)
index 0000000..468507a
--- /dev/null
@@ -0,0 +1,96 @@
+/* $Id$\r
+ * Copyright (c) 2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+/**\r
+ * Radio logic is split between Csma (media-access control, low-power\r
+ * listening and general control) and SendReceive (packet reception and\r
+ * transmission). This interface specifies the interaction between these\r
+ * two components.\r
+ *\r
+ * @author David Gay\r
+ */\r
+  \r
+interface ByteRadio\r
+{\r
+  /**\r
+   * SendReceive wants to send a packet.\r
+   * @param msg Message to be sent.\r
+   */\r
+  event void rts(message_t *msg);\r
+\r
+  /**\r
+   * Access to the media granted. Start sending. SendReceive must signal\r
+   * sendDone when transmission is complete. Note: the media-access-contro\r
+   * layer must have enabled listening before calling cts().\r
+   */\r
+  async command void cts();\r
+\r
+  /**\r
+   * Between the rts() and sendDone() events, this must return the\r
+   * message under transmission.\r
+   * @return Message being transmitted.\r
+   */\r
+  async command message_t *getTxMessage();\r
+\r
+  /**\r
+   * Transmission complete.\r
+   */\r
+  async event void sendDone();\r
+\r
+  /**\r
+   * Set message preamble length.\r
+   * @param bytes Preamble length in bytes\r
+   */\r
+  async command void setPreambleLength(uint16_t bytes);\r
+\r
+  /**\r
+   * Get message preamble length.\r
+   * @return Preamble length in bytes\r
+   */\r
+  async command uint16_t getPreambleLength();\r
+\r
+  /**\r
+   * Enable listening for incoming packets.\r
+   */\r
+  async command void listen();\r
+\r
+  /**\r
+   * Disable listening for incoming packets.\r
+   */\r
+  async command void off();\r
+\r
+  /**\r
+   * SendReceive signals this event for every radio-byte-time while\r
+   * listening is enabled and a message isn't being received or\r
+   * transmitted.\r
+   * @param preamble TRUE if a message preamble byte has been received\r
+   */\r
+  async event void idleByte(bool preamble);\r
+\r
+  /**\r
+   * Detect if SendReceive is attempting to sync with an incoming packet.\r
+   * During sync, idleByte events are not signaled. If sync is successful,\r
+   * an rx() event will be signaled, if it fails, idleByte events will\r
+   * resume. If syncing() returns TRUE, the last idleByte() event must\r
+   * have had preamble = TRUE.\r
+   *\r
+   * @return TRUE if a sync attempt is in progress, FALSE if not.\r
+   */\r
+  async command bool syncing();\r
+\r
+  /**\r
+   * A message is being received\r
+   */\r
+  async event void rx();\r
+\r
+  /**\r
+   * Message reception is complete.\r
+   */\r
+  async event void rxDone();\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CC1000ActiveMessageC.nc b/tos/chips/cc1000_lpl/CC1000ActiveMessageC.nc
new file mode 100644 (file)
index 0000000..c4ed2b0
--- /dev/null
@@ -0,0 +1,76 @@
+// $Id$\r
+\r
+/*                                                                     tab:4\r
+ * "Copyright (c) 2004-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2004-2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+\r
+/**\r
+ *\r
+ * The Active Message layer for the CC1000 radio. This configuration\r
+ * just layers the AM dispatch (CC1000ActiveMessageM) on top of the\r
+ * underlying CC1000 radio packet (CC1000CsmaRadioC), which is\r
+ * inherently an AM packet (acknowledgements based on AM destination\r
+ * addr and group).\r
+ * \r
+ * @author Philip Levis\r
+ * @date June 19 2005\r
+ */\r
+\r
+configuration CC1000ActiveMessageC {\r
+  provides {\r
+    interface SplitControl;\r
+    interface AMSend[am_id_t id];\r
+    interface Receive[am_id_t id];\r
+    interface Receive as Snoop[am_id_t id];\r
+    interface AMPacket;\r
+    interface Packet;\r
+    interface PacketAcknowledgements;\r
+    interface LowPowerListening;\r
+  }\r
+}\r
+implementation {\r
+\r
+  components CC1000ActiveMessageP as AM, CC1000CsmaRadioC as Radio;\r
+  components ActiveMessageAddressC as Address;\r
+  components CC1000LowPowerListeningC as Lpl;\r
+  \r
+  SplitControl = Radio;\r
+  Packet       = Radio;\r
+  PacketAcknowledgements = Radio;\r
+  LowPowerListening = Radio;\r
+\r
+  AMSend   = AM;\r
+  Receive  = AM.Receive;\r
+  Snoop    = AM.Snoop;\r
+  AMPacket = AM;\r
+\r
+  AM.SubSend    -> Lpl.Send;\r
+  AM.SubReceive -> Lpl.Receive;\r
+  AM.amAddress -> Address;\r
+  AM.Packet     -> Radio;\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CC1000ActiveMessageP.nc b/tos/chips/cc1000_lpl/CC1000ActiveMessageP.nc
new file mode 100644 (file)
index 0000000..734d562
--- /dev/null
@@ -0,0 +1,169 @@
+// $Id$\r
+\r
+/*                                                                     tab:4\r
+ * "Copyright (c) 2004-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2004-2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+/**\r
+ * Implementation component for CC1000ActiveMessageC.\r
+ *\r
+ * @author Philip Levis\r
+ * @date June 19 2006\r
+ */\r
+\r
+module CC1000ActiveMessageP {\r
+  provides {\r
+    interface AMSend[am_id_t id];\r
+    interface Receive[am_id_t id];\r
+    interface Receive as Snoop[am_id_t id];\r
+    interface AMPacket;\r
+  }\r
+  uses {\r
+    interface Send as SubSend;\r
+    interface Receive as SubReceive;\r
+    interface Packet as Packet;\r
+    command am_addr_t amAddress();\r
+  }\r
+}\r
+implementation {\r
+\r
+  cc1000_header_t* getHeader(message_t* amsg) {\r
+    return (cc1000_header_t*)(amsg->data - sizeof(cc1000_header_t));\r
+  }\r
+  \r
+  command error_t AMSend.send[am_id_t id](am_addr_t addr,\r
+                                         message_t* amsg,\r
+                                         uint8_t len) {\r
+    cc1000_header_t* header = getHeader(amsg);\r
+    header->type = id;\r
+    header->dest = addr;\r
+    header->source = call AMPacket.address();\r
+    header->group = TOS_AM_GROUP;\r
+    return call SubSend.send(amsg, len);\r
+  }\r
+\r
+  command error_t AMSend.cancel[am_id_t id](message_t* msg) {\r
+    return call SubSend.cancel(msg);\r
+  }\r
+\r
+  event void SubSend.sendDone(message_t* msg, error_t result) {\r
+    signal AMSend.sendDone[call AMPacket.type(msg)](msg, result);\r
+  }\r
+\r
+  command uint8_t AMSend.maxPayloadLength[am_id_t id]() {\r
+    return call Packet.maxPayloadLength();\r
+  }\r
+\r
+  command void* AMSend.getPayload[am_id_t id](message_t* m) {\r
+    return call Packet.getPayload(m, NULL);\r
+  }\r
+\r
+  /* Receiving a packet */\r
+\r
+  event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) {\r
+    if (call AMPacket.isForMe(msg)) {\r
+      return signal Receive.receive[call AMPacket.type(msg)](msg, payload, len);\r
+    }\r
+    else {\r
+      return signal Snoop.receive[call AMPacket.type(msg)](msg, payload, len);\r
+    }\r
+  }\r
+  \r
+  command void* Receive.getPayload[am_id_t id](message_t* m, uint8_t* len) {\r
+    return call Packet.getPayload(m, len);\r
+  }\r
+\r
+  command uint8_t Receive.payloadLength[am_id_t id](message_t* m) {\r
+    return call Packet.payloadLength(m);\r
+  }\r
+  \r
+  command void* Snoop.getPayload[am_id_t id](message_t* m, uint8_t* len) {\r
+    return call Packet.getPayload(m, len);\r
+  }\r
+\r
+  command uint8_t Snoop.payloadLength[am_id_t id](message_t* m) {\r
+    return call Packet.payloadLength(m);\r
+  }\r
+\r
+  command am_addr_t AMPacket.address() {\r
+    return call amAddress();\r
+  }\r
\r
+  command am_addr_t AMPacket.destination(message_t* amsg) {\r
+    cc1000_header_t* header = getHeader(amsg);\r
+    return header->dest;\r
+  }\r
+\r
+  command am_addr_t AMPacket.source(message_t* amsg) {\r
+    cc1000_header_t* header = getHeader(amsg);\r
+    return header->source;\r
+  }\r
+\r
+  command void AMPacket.setDestination(message_t* amsg, am_addr_t addr) {\r
+    cc1000_header_t* header = getHeader(amsg);\r
+    header->dest = addr;\r
+  }\r
+\r
+  command void AMPacket.setSource(message_t* amsg, am_addr_t addr) {\r
+    cc1000_header_t* header = getHeader(amsg);\r
+    header->source = addr;\r
+  }\r
+  \r
+  command bool AMPacket.isForMe(message_t* amsg) {\r
+    return (call AMPacket.destination(amsg) == call AMPacket.address() ||\r
+           call AMPacket.destination(amsg) == AM_BROADCAST_ADDR);\r
+  }\r
+\r
+  command am_id_t AMPacket.type(message_t* amsg) {\r
+    cc1000_header_t* header = getHeader(amsg);\r
+    return header->type;\r
+  }\r
+\r
+  command void AMPacket.setType(message_t* amsg, am_id_t type) {\r
+    cc1000_header_t* header = getHeader(amsg);\r
+    header->type = type;\r
+  }\r
+  \r
+  //command am_group_t AMPacket.group(message_t* amsg) {\r
+  //  return amsg->header.group;\r
+  //}\r
+  \r
+ default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {\r
+    return msg;\r
+  }\r
+  \r
+  default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {\r
+    return msg;\r
+  }\r
+\r
+ default event void AMSend.sendDone[uint8_t id](message_t* msg, error_t err) {\r
+   return;\r
+ }\r
+\r
+  \r
+\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CC1000Const.h b/tos/chips/cc1000_lpl/CC1000Const.h
new file mode 100644 (file)
index 0000000..9543c89
--- /dev/null
@@ -0,0 +1,469 @@
+// $Id$\r
+\r
+/* -*- Mode: C; c-basic-indent: 2; indent-tabs-mode: nil -*- */ \r
+/*                                                                     tab:4\r
+ *  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.  By\r
+ *  downloading, copying, installing or using the software you agree to\r
+ *  this license.  If you do not agree to this license, do not download,\r
+ *  install, copy or use the software.\r
+ *\r
+ *  Intel Open Source License \r
+ *\r
+ *  Copyright (c) 2002 Intel Corporation \r
+ *  All rights reserved. \r
+ *  Redistribution and use in source and binary forms, with or without\r
+ *  modification, are permitted provided that the following conditions are\r
+ *  met:\r
+ * \r
+ *     Redistributions of source code must retain the above copyright\r
+ *  notice, this list of conditions and the following disclaimer.\r
+ *     Redistributions in binary form must reproduce the above copyright\r
+ *  notice, this list of conditions and the following disclaimer in the\r
+ *  documentation and/or other materials provided with the distribution.\r
+ *      Neither the name of the Intel Corporation nor the names of its\r
+ *  contributors may be used to endorse or promote products derived from\r
+ *  this software without specific prior written permission.\r
+ *  \r
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
+ *  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE INTEL OR ITS\r
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * \r
+ */\r
+\r
+/*\r
+ * Constants for CC1000 radio\r
+ *\r
+ * @author Phil Buonadonna\r
+ */\r
+\r
+#ifndef CC1000CONST_H\r
+#define CC1000CONST_H\r
+\r
+/* Constants defined for CC1K */\r
+/* Register addresses */\r
+\r
+enum {\r
+  CC1K_MAIN =           0x00,\r
+  CC1K_FREQ_2A =        0x01,\r
+  CC1K_FREQ_1A =        0x02,\r
+  CC1K_FREQ_0A =        0x03,\r
+  CC1K_FREQ_2B =        0x04,\r
+  CC1K_FREQ_1B =        0x05,\r
+  CC1K_FREQ_0B =        0x06,\r
+  CC1K_FSEP1 =          0x07,\r
+  CC1K_FSEP0 =          0x08,\r
+  CC1K_CURRENT =        0x09,\r
+  CC1K_FRONT_END =      0x0A, //10\r
+  CC1K_PA_POW =         0x0B, //11\r
+  CC1K_PLL =            0x0C, //12\r
+  CC1K_LOCK =           0x0D, //13\r
+  CC1K_CAL =            0x0E, //14\r
+  CC1K_MODEM2 =         0x0F, //15\r
+  CC1K_MODEM1 =         0x10, //16\r
+  CC1K_MODEM0 =         0x11, //17\r
+  CC1K_MATCH =          0x12, //18\r
+  CC1K_FSCTRL =         0x13, //19\r
+  CC1K_FSHAPE7 =        0x14, //20\r
+  CC1K_FSHAPE6 =        0x15, //21\r
+  CC1K_FSHAPE5 =        0x16, //22\r
+  CC1K_FSHAPE4 =        0x17, //23\r
+  CC1K_FSHAPE3 =        0x18, //24\r
+  CC1K_FSHAPE2 =        0x19, //25\r
+  CC1K_FSHAPE1 =        0x1A, //26\r
+  CC1K_FSDELAY =        0x1B, //27\r
+  CC1K_PRESCALER =      0x1C, //28\r
+  CC1K_TEST6 =          0x40, //64\r
+  CC1K_TEST5 =          0x41, //66\r
+  CC1K_TEST4 =          0x42, //67\r
+  CC1K_TEST3 =          0x43, //68\r
+  CC1K_TEST2 =          0x44, //69\r
+  CC1K_TEST1 =          0x45, //70\r
+  CC1K_TEST0 =          0x46, //71\r
+\r
+  // MAIN Register Bit Posititions\r
+  CC1K_RXTX =          7,\r
+  CC1K_F_REG =         6,\r
+  CC1K_RX_PD =         5,\r
+  CC1K_TX_PD =         4,\r
+  CC1K_FS_PD =         3,\r
+  CC1K_CORE_PD =       2,\r
+  CC1K_BIAS_PD =       1,\r
+  CC1K_RESET_N =       0,\r
+\r
+  // CURRENT Register Bit Positions\r
+  CC1K_VCO_CURRENT =   4,\r
+  CC1K_LO_DRIVE =      2,\r
+  CC1K_PA_DRIVE =      0,\r
+\r
+  // FRONT_END Register Bit Positions\r
+  CC1K_BUF_CURRENT =   5,\r
+  CC1K_LNA_CURRENT =   3,\r
+  CC1K_IF_RSSI =       1,\r
+  CC1K_XOSC_BYPASS =   0,\r
+\r
+  // PA_POW Register Bit Positions\r
+  CC1K_PA_HIGHPOWER =  4,\r
+  CC1K_PA_LOWPOWER =   0,\r
+\r
+  // PLL Register Bit Positions\r
+  CC1K_EXT_FILTER =    7,\r
+  CC1K_REFDIV =                3,\r
+  CC1K_ALARM_DISABLE = 2,\r
+  CC1K_ALARM_H =       1,\r
+  CC1K_ALARM_L =       0,\r
+\r
+  // LOCK Register Bit Positions\r
+  CC1K_LOCK_SELECT =           4,\r
+  CC1K_PLL_LOCK_ACCURACY =     3,\r
+  CC1K_PLL_LOCK_LENGTH =       2,\r
+  CC1K_LOCK_INSTANT =          1,\r
+  CC1K_LOCK_CONTINUOUS =       0,\r
+\r
+  // CAL Register Bit Positions\r
+  CC1K_CAL_START =     7,\r
+  CC1K_CAL_DUAL =      6,\r
+  CC1K_CAL_WAIT =      5,\r
+  CC1K_CAL_CURRENT =   4,\r
+  CC1K_CAL_COMPLETE =  3,\r
+  CC1K_CAL_ITERATE =   0,\r
+\r
+  // MODEM2 Register Bit Positions\r
+  CC1K_PEAKDETECT =            7,\r
+  CC1K_PEAK_LEVEL_OFFSET =     0,\r
+\r
+  // MODEM1 Register Bit Positions\r
+  CC1K_MLIMIT =                5,\r
+  CC1K_LOCK_AVG_IN =   4,\r
+  CC1K_LOCK_AVG_MODE = 3,\r
+  CC1K_SETTLING =      1,\r
+  CC1K_MODEM_RESET_N = 0,\r
+\r
+  // MODEM0 Register Bit Positions\r
+  CC1K_BAUDRATE =      4,\r
+  CC1K_DATA_FORMAT =   2,\r
+  CC1K_XOSC_FREQ =     0,\r
+\r
+  // MATCH Register Bit Positions\r
+  CC1K_RX_MATCH =      4,\r
+  CC1K_TX_MATCH =      0,\r
+\r
+  // FSCTLR Register Bit Positions\r
+  CC1K_DITHER1 =       3,\r
+  CC1K_DITHER0 =       2,\r
+  CC1K_SHAPE =         1,\r
+  CC1K_FS_RESET_N =    0,\r
+\r
+  // PRESCALER Register Bit Positions\r
+  CC1K_PRE_SWING =     6,\r
+  CC1K_PRE_CURRENT =   4,\r
+  CC1K_IF_INPUT =      3,\r
+  CC1K_IF_FRONT =      2,\r
+\r
+  // TEST6 Register Bit Positions\r
+  CC1K_LOOPFILTER_TP1 =        7,\r
+  CC1K_LOOPFILTER_TP2 =        6,\r
+  CC1K_CHP_OVERRIDE =  5,\r
+  CC1K_CHP_CO =                0,\r
+\r
+  // TEST5 Register Bit Positions\r
+  CC1K_CHP_DISABLE =   5,\r
+  CC1K_VCO_OVERRIDE =  4,\r
+  CC1K_VCO_AO =                0,\r
+\r
+  // TEST3 Register Bit Positions\r
+  CC1K_BREAK_LOOP =    4,\r
+  CC1K_CAL_DAC_OPEN =  0,\r
+\r
+\r
+  /* \r
+   * CC1K Register Parameters Table\r
+   *\r
+   * This table follows the same format order as the CC1K register \r
+   * set EXCEPT for the last entry in the table which is the \r
+   * CURRENT register value for TX mode.\r
+   *  \r
+   * NOTE: To save RAM space, this table resides in program memory (flash). \r
+   * This has two important implications:\r
+   *   1) You can't write to it (duh!)\r
+   *   2) You must read it using the PRG_RDB(addr) macro. IT CANNOT BE ACCESSED AS AN ORDINARY C ARRAY.  \r
+   * \r
+   * Add/remove individual entries below to suit your RF tastes.\r
+   * \r
+   */\r
+  CC1K_433_002_MHZ =   0x00,\r
+  CC1K_915_998_MHZ =   0x01,\r
+  CC1K_434_845_MHZ =    0x02,\r
+  CC1K_914_077_MHZ =    0x03,\r
+  CC1K_315_178_MHZ =    0x04,\r
+\r
+  //#define CC1K_SquelchInit        0x02F8 // 0.90V using the bandgap reference\r
+  CC1K_SquelchInit =        0x120,\r
+  CC1K_SquelchTableSize =   9,\r
+  CC1K_MaxRSSISamples =     5,\r
+  CC1K_Settling =           1,\r
+  CC1K_ValidPrecursor =     2,\r
+  CC1K_SquelchIntervalFast = 128,\r
+  CC1K_SquelchIntervalSlow = 2560,\r
+  CC1K_SquelchCount =       30,\r
+  CC1K_SquelchBuffer =      12,\r
+\r
+  CC1K_LPL_PACKET_TIME =    16,\r
+\r
+  CC1K_LPL_CHECK_TIME =     16, /* In tenth's of milliseconds, this should\r
+                                 be an approximation of the on-time for\r
+                                 a LPL check rather than the total check\r
+                                 time. */\r
+  CC1K_LPL_MIN_INTERVAL =    5, /* In milliseconds, the minimum interval\r
+                                  between low-power-listening checks */\r
+  CC1K_LPL_MAX_INTERVAL =    10000,  /* In milliseconds, the maximum interval\r
+                                      between low-power-listening checks.\r
+                                      Arbitrary value, but must be at\r
+                                      most 32767 because of the way\r
+                                      sleep interval is stored in outgoing\r
+                                      messages */\r
+                                      \r
+       CC1000_MIN_BACKOFF = 2,\r
+       CC1000_BACKOFF_PERIOD = 2,\r
+};\r
+\r
+#ifdef CC1K_DEFAULT_FREQ\r
+#define CC1K_DEF_PRESET (CC1K_DEFAULT_FREQ)\r
+#endif\r
+#ifdef CC1K_MANUAL_FREQ\r
+#define CC1K_DEF_FREQ (CC1K_MANUAL_FREQ)\r
+#endif\r
+\r
+#ifndef CC1K_DEF_PRESET\r
+#define CC1K_DEF_PRESET        (CC1K_914_077_MHZ)\r
+#endif \r
+\r
+static const_uint8_t CC1K_Params[6][20] = {\r
+  // (0) 433.002 MHz channel, 19.2 Kbps data, Manchester Encoding, High Side LO\r
+  { // MAIN   0x00\r
+    0x31,\r
+    // FREQ2A,FREQ1A,FREQ0A  0x01-0x03\r
+    0x58,0x00,0x00,                                    \r
+    // FREQ2B,FREQ1B,FREQ0B  0x04-0x06\r
+    0x57,0xf6,0x85,    //XBOW\r
+    // FSEP1, FSEP0     0x07-0x08\r
+    0X03,0x55,\r
+    // CURRENT RX MODE VALUE   0x09 also see below\r
+    4 << CC1K_VCO_CURRENT | 1 << CC1K_LO_DRIVE,        \r
+    // FRONT_END  0x0a\r
+    1 << CC1K_IF_RSSI,\r
+    // PA_POW  0x0b\r
+    0x0 << CC1K_PA_HIGHPOWER | 0xf << CC1K_PA_LOWPOWER, \r
+    // PLL  0x0c\r
+    12 << CC1K_REFDIV,         \r
+    // LOCK  0x0d\r
+    0xe << CC1K_LOCK_SELECT,\r
+    // CAL  0x0e\r
+    1 << CC1K_CAL_WAIT | 6 << CC1K_CAL_ITERATE,        \r
+    // MODEM2  0x0f\r
+    0 << CC1K_PEAKDETECT | 28 << CC1K_PEAK_LEVEL_OFFSET,\r
+    // MODEM1  0x10\r
+    3 << CC1K_MLIMIT | 1 << CC1K_LOCK_AVG_MODE | CC1K_Settling << CC1K_SETTLING | 1 << CC1K_MODEM_RESET_N, \r
+    // MODEM0  0x11\r
+    5 << CC1K_BAUDRATE | 1 << CC1K_DATA_FORMAT | 1 << CC1K_XOSC_FREQ,\r
+    // MATCH  0x12\r
+    0x7 << CC1K_RX_MATCH | 0x0 << CC1K_TX_MATCH,\r
+    // tx current (extra)\r
+    8 << CC1K_VCO_CURRENT | 1 << CC1K_PA_DRIVE,\r
+  },\r
+\r
+  // 1 915.9988 MHz channel, 19.2 Kbps data, Manchester Encoding, High Side LO\r
+  { // MAIN   0x00 \r
+    0x31,\r
+    // FREQ2A,FREQ1A,FREQ0A  0x01-0x03\r
+    0x7c,0x00,0x00,                                    \r
+    // FREQ2B,FREQ1B,FREQ0B  0x04-0x06\r
+    0x7b,0xf9,0xae,                                    \r
+    // FSEP1, FSEP0     0x07-0x8\r
+    0x02,0x38,\r
+    // CURRENT RX MODE VALUE   0x09 also see below\r
+    8 << CC1K_VCO_CURRENT | 3 << CC1K_LO_DRIVE,\r
+    //0x8C,    \r
+    // FRONT_END  0x0a\r
+    1 << CC1K_BUF_CURRENT | 2 << CC1K_LNA_CURRENT | 1 << CC1K_IF_RSSI,\r
+    //0x32,\r
+    // PA_POW  0x0b\r
+    0x8 << CC1K_PA_HIGHPOWER | 0x0 << CC1K_PA_LOWPOWER, \r
+    //0xff,\r
+    // PLL  0xc\r
+    8 << CC1K_REFDIV,          \r
+    //0x40,\r
+    // LOCK  0xd\r
+    0x1 << CC1K_LOCK_SELECT,\r
+    //0x10,\r
+    // CAL  0xe\r
+    1 << CC1K_CAL_WAIT | 6 << CC1K_CAL_ITERATE,        \r
+    //0x26,\r
+    // MODEM2  0xf\r
+    1 << CC1K_PEAKDETECT | 33 << CC1K_PEAK_LEVEL_OFFSET,\r
+    //0xA1,\r
+    // MODEM1  0x10\r
+    3 << CC1K_MLIMIT | 1 << CC1K_LOCK_AVG_MODE | CC1K_Settling << CC1K_SETTLING | 1 << CC1K_MODEM_RESET_N, \r
+    //0x6f, \r
+    // MODEM0  0x11\r
+    5 << CC1K_BAUDRATE | 1 << CC1K_DATA_FORMAT | 1 << CC1K_XOSC_FREQ,\r
+    //0x55,\r
+    // MATCH 0x12\r
+    0x1 << CC1K_RX_MATCH | 0x0 << CC1K_TX_MATCH,\r
+    // tx current (extra)\r
+    15 << CC1K_VCO_CURRENT | 3 << CC1K_PA_DRIVE,\r
+  },\r
+\r
+  // 2 434.845200 MHz channel, 19.2 Kbps data, Manchester Encoding, High Side LO\r
+  { // MAIN   0x00\r
+    0x31,\r
+    // FREQ2A,FREQ1A,FREQ0A  0x01-0x03\r
+    0x51,0x00,0x00,                                    \r
+    // FREQ2B,FREQ1B,FREQ0B  0x04-0x06\r
+    0x50,0xf7,0x4F,    //XBOW\r
+    // FSEP1, FSEP0     0x07-0x08\r
+    0X03,0x0E,\r
+    // CURRENT RX MODE VALUE   0x09 also see below\r
+    4 << CC1K_VCO_CURRENT | 1 << CC1K_LO_DRIVE,        \r
+    // FRONT_END  0x0a\r
+    1 << CC1K_IF_RSSI,\r
+    // PA_POW  0x0b\r
+    0x0 << CC1K_PA_HIGHPOWER | 0xf << CC1K_PA_LOWPOWER, \r
+    // PLL  0x0c\r
+    11 << CC1K_REFDIV,         \r
+    // LOCK  0x0d\r
+    0xe << CC1K_LOCK_SELECT,\r
+    // CAL  0x0e\r
+    1 << CC1K_CAL_WAIT | 6 << CC1K_CAL_ITERATE,        \r
+    // MODEM2  0x0f\r
+    1 << CC1K_PEAKDETECT | 33 << CC1K_PEAK_LEVEL_OFFSET,\r
+    // MODEM1  0x10\r
+    3 << CC1K_MLIMIT | 1 << CC1K_LOCK_AVG_MODE | CC1K_Settling << CC1K_SETTLING | 1 << CC1K_MODEM_RESET_N, \r
+    // MODEM0  0x11\r
+    5 << CC1K_BAUDRATE | 1 << CC1K_DATA_FORMAT | 1 << CC1K_XOSC_FREQ,\r
+    // MATCH  0x12\r
+    0x7 << CC1K_RX_MATCH | 0x0 << CC1K_TX_MATCH,\r
+    // tx current (extra)\r
+    8 << CC1K_VCO_CURRENT | 1 << CC1K_PA_DRIVE,\r
+  },\r
+\r
\r
+  // 3 914.077 MHz channel, 19.2 Kbps data, Manchester Encoding, High Side LO\r
+  { // MAIN   0x00 \r
+    0x31,\r
+    // FREQ2A,FREQ1A,FREQ0A  0x01-0x03\r
+    0x5c,0xe0,0x00,                                    \r
+    // FREQ2B,FREQ1B,FREQ0B  0x04-0x06\r
+    0x5c,0xdb,0x42,                                    \r
+    // FSEP1, FSEP0     0x07-0x8\r
+    0x01,0xAA,\r
+    // CURRENT RX MODE VALUE   0x09 also see below\r
+    8 << CC1K_VCO_CURRENT | 3 << CC1K_LO_DRIVE,\r
+    //0x8C,    \r
+    // FRONT_END  0x0a\r
+    1 << CC1K_BUF_CURRENT | 2 << CC1K_LNA_CURRENT | 1 << CC1K_IF_RSSI,\r
+    //0x32,\r
+    // PA_POW  0x0b\r
+    0x8 << CC1K_PA_HIGHPOWER | 0x0 << CC1K_PA_LOWPOWER, \r
+    //0xff,\r
+    // PLL  0xc\r
+    6 << CC1K_REFDIV,          \r
+    //0x40,\r
+    // LOCK  0xd\r
+    0x1 << CC1K_LOCK_SELECT,\r
+    //0x10,\r
+    // CAL  0xe\r
+    1 << CC1K_CAL_WAIT | 6 << CC1K_CAL_ITERATE,        \r
+    //0x26,\r
+    // MODEM2  0xf\r
+    1 << CC1K_PEAKDETECT | 33 << CC1K_PEAK_LEVEL_OFFSET,\r
+    //0xA1,\r
+    // MODEM1  0x10\r
+    3 << CC1K_MLIMIT | 1 << CC1K_LOCK_AVG_MODE | CC1K_Settling << CC1K_SETTLING | 1 << CC1K_MODEM_RESET_N, \r
+    //0x6f, \r
+    // MODEM0  0x11\r
+    5 << CC1K_BAUDRATE | 1 << CC1K_DATA_FORMAT | 1 << CC1K_XOSC_FREQ,\r
+    //0x55,\r
+    // MATCH 0x12\r
+    0x1 << CC1K_RX_MATCH | 0x0 << CC1K_TX_MATCH,\r
+    // tx current (extra)\r
+    15 << CC1K_VCO_CURRENT | 3 << CC1K_PA_DRIVE,\r
+  },\r
+\r
+  // 4 315.178985 MHz channel, 38.4 Kbps data, Manchester Encoding, High Side LO\r
+  { // MAIN   0x00\r
+    0x31,\r
+    // FREQ2A,FREQ1A,FREQ0A  0x01-0x03\r
+    0x45,0x60,0x00,                                    \r
+    // FREQ2B,FREQ1B,FREQ0B  0x04-0x06\r
+    0x45,0x55,0xBB,\r
+    // FSEP1, FSEP0     0x07-0x08\r
+    0X03,0x9C,\r
+    // CURRENT RX MODE VALUE   0x09 also see below\r
+    8 << CC1K_VCO_CURRENT | 0 << CC1K_LO_DRIVE,        \r
+    // FRONT_END  0x0a\r
+    1 << CC1K_IF_RSSI,\r
+    // PA_POW  0x0b\r
+    0x0 << CC1K_PA_HIGHPOWER | 0xf << CC1K_PA_LOWPOWER, \r
+    // PLL  0x0c\r
+    13 << CC1K_REFDIV,         \r
+    // LOCK  0x0d\r
+    0xe << CC1K_LOCK_SELECT,\r
+    // CAL  0x0e\r
+    1 << CC1K_CAL_WAIT | 6 << CC1K_CAL_ITERATE,        \r
+    // MODEM2  0x0f\r
+    1 << CC1K_PEAKDETECT | 33 << CC1K_PEAK_LEVEL_OFFSET,\r
+    // MODEM1  0x10\r
+    3 << CC1K_MLIMIT | 1 << CC1K_LOCK_AVG_MODE | CC1K_Settling << CC1K_SETTLING | 1 << CC1K_MODEM_RESET_N, \r
+    // MODEM0  0x11\r
+    5 << CC1K_BAUDRATE | 1 << CC1K_DATA_FORMAT | 0 << CC1K_XOSC_FREQ,\r
+    // MATCH  0x12\r
+    0x7 << CC1K_RX_MATCH | 0x0 << CC1K_TX_MATCH,\r
+    // tx current (extra)\r
+    8 << CC1K_VCO_CURRENT | 1 << CC1K_PA_DRIVE,\r
+  },\r
+\r
+  // 5 Spare\r
+  { // MAIN   0x00\r
+    0x31,\r
+    // FREQ2A,FREQ1A,FREQ0A  0x01-0x03\r
+    0x58,0x00,0x00,                                    \r
+    // FREQ2B,FREQ1B,FREQ0B  0x04-0x06\r
+    0x57,0xf6,0x85,    //XBOW\r
+    // FSEP1, FSEP0     0x07-0x08\r
+    0X03,0x55,\r
+    // CURRENT RX MODE VALUE   0x09 also see below\r
+    8 << CC1K_VCO_CURRENT | 4 << CC1K_LO_DRIVE,        \r
+    // FRONT_END  0x0a\r
+    1 << CC1K_IF_RSSI,\r
+    // PA_POW  0x0b\r
+    0x0 << CC1K_PA_HIGHPOWER | 0xf << CC1K_PA_LOWPOWER, \r
+    // PLL  0x0c\r
+    12 << CC1K_REFDIV,         \r
+    // LOCK  0x0d\r
+    0xe << CC1K_LOCK_SELECT,\r
+    // CAL  0x0e\r
+    1 << CC1K_CAL_WAIT | 6 << CC1K_CAL_ITERATE,        \r
+    // MODEM2  0x0f\r
+    1 << CC1K_PEAKDETECT | 33 << CC1K_PEAK_LEVEL_OFFSET,\r
+    // MODEM1  0x10\r
+    3 << CC1K_MLIMIT | 1 << CC1K_LOCK_AVG_MODE | CC1K_Settling << CC1K_SETTLING | 1 << CC1K_MODEM_RESET_N,    // MODEM0  0x11\r
+    5 << CC1K_BAUDRATE | 1 << CC1K_DATA_FORMAT | 1 << CC1K_XOSC_FREQ,\r
+    // MATCH  0x12\r
+    0x7 << CC1K_RX_MATCH | 0x0 << CC1K_TX_MATCH,\r
+    // tx current (extra)\r
+    8 << CC1K_VCO_CURRENT | 1 << CC1K_PA_DRIVE,\r
+  },\r
+};\r
+\r
+#define UQ_CC1000_RSSI "CC1000RssiP.Rssi"\r
+\r
+#endif /* CC1000CONST_H */\r
diff --git a/tos/chips/cc1000_lpl/CC1000Control.nc b/tos/chips/cc1000_lpl/CC1000Control.nc
new file mode 100644 (file)
index 0000000..b653e94
--- /dev/null
@@ -0,0 +1,137 @@
+/* $Id$\r
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2002-2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+/**\r
+ * CC1000 internal radio control interface.\r
+ * @author Philip Buonadonna\r
+ * @aythor Jaein Jeong\r
+ */\r
+interface CC1000Control\r
+{\r
+  /**\r
+   * Initialise the radio to its default state.\r
+   */\r
+  command void init();\r
+\r
+  /**\r
+   * Tune the radio to one of the frequencies available in the CC1K_Params\r
+   * table.  Calling Tune will allso reset the rfpower and LockVal\r
+   * selections to the table values.\r
+   * \r
+   * @param freq The index into the CC1K_Params table that holds the\r
+   * desired preset frequency parameters.\r
+   */\r
+  command void tunePreset(uint8_t freq); \r
+\r
+  /**\r
+   * Tune the radio to a given frequency. Since the CC1000 uses a digital\r
+   * frequency synthesizer, it cannot tune to just an arbitrary frequency.\r
+   * This routine will determine the closest achievable channel, compute\r
+   * the necessary parameters and tune the radio.\r
+   * \r
+   * @param The desired channel frequency, in Hz.\r
+   * \r
+   * @return The actual computed channel frequency, in Hz.  A return value\r
+   * of '0' indicates that no frequency was computed and the radio was not\r
+   * tuned.\r
+   */\r
+  command uint32_t tuneManual(uint32_t DesiredFreq);\r
+\r
+  /**\r
+   * Turn the CC1000 off\r
+   */\r
+  async command void off();\r
+\r
+  /**\r
+   * Shift the CC1000 Radio into transmit mode.\r
+   */\r
+  async command void txMode();\r
+\r
+  /**\r
+   * Shift the CC1000 Radio in receive mode.\r
+   */\r
+  async command void rxMode();\r
+\r
+  /**\r
+   * Turn off the bias power on the CC1000 radio, but leave the core and\r
+   * crystal oscillator powered.  This will result in approximately a 750\r
+   * uA power savings.\r
+   */\r
+  async command void coreOn();                 \r
+\r
+  /**\r
+   * Turn the bias power on. This function must be followed by a call to\r
+   * either rxMode() or txMode() to place the radio in a recieve/transmit\r
+   * state respectively. There is approximately a 200us delay when\r
+   * restoring bias power.\r
+   */\r
+  async command void biasOn();\r
+\r
+  /**\r
+   * Set the transmit RF power value.  The input value is simply an\r
+   * arbitrary index that is programmed into the CC1000 registers.  Consult\r
+   * the CC1000 datasheet for the resulting power output/current\r
+   * consumption values.\r
+   *\r
+   * @param power A power index between 1 and 255.\r
+   */\r
+  command void setRFPower(uint8_t power);      \r
+\r
+  /**\r
+   * Get the present RF power index.\r
+   *\r
+   * @return The power index value.\r
+   */\r
+  command uint8_t getRFPower();                \r
+\r
+  /** \r
+   * Select the signal to monitor at the CHP_OUT pin of the CC1000.  See\r
+   * the CC1000 data sheet for the available signals.\r
+   * \r
+   * @param LockVal The index of the signal to monitor at the CHP_OUT pin\r
+   */\r
+  command void selectLock(uint8_t LockVal); \r
+\r
+  /**\r
+   * Get the binary value from the CHP_OUT pin.  Analog signals cannot be\r
+   * read using function.\r
+   *\r
+   * @return 1 - Pin is high or 0 - Pin is low\r
+   */\r
+  command uint8_t getLock();\r
+\r
+  /**\r
+   * Returns whether the present frequency set is using high-side LO\r
+   * injection or not.  This information is used to determine if the data\r
+   * from the CC1000 needs to be inverted or not.\r
+   *\r
+   * @return TRUE if high-side LO injection is being used (i.e. data does NOT need to be inverted\r
+   * at the receiver.\r
+   */\r
+  command bool getLOStatus();\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CC1000ControlP.nc b/tos/chips/cc1000_lpl/CC1000ControlP.nc
new file mode 100644 (file)
index 0000000..cff7a95
--- /dev/null
@@ -0,0 +1,385 @@
+/* $Id$\r
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2002-2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+#include "CC1000Const.h"\r
+#include "Timer.h"\r
+\r
+/**\r
+ * This module provides the CONTROL functionality for the Chipcon1000\r
+ * series radio.  It exports a custom interface to control CC1000\r
+ * operation.\r
+ *\r
+ * @author Philip Buonadonna\r
+ * @author Jaein Jeong\r
+ * @author David Gay\r
+ */\r
+module CC1000ControlP {\r
+  provides {\r
+    interface CC1000Control;\r
+  }\r
+  uses {\r
+    interface HplCC1000 as CC;\r
+    interface BusyWait<TMicro, uint16_t>;\r
+  }\r
+}\r
+implementation\r
+{\r
+  uint8_t txCurrent, rxCurrent, power;\r
+\r
+  enum {\r
+    IF = 150000,\r
+    FREQ_MIN = 4194304,\r
+    FREQ_MAX = 16751615\r
+  };\r
+\r
+  const_uint32_t fRefTbl[9] = {2457600,\r
+                              2106514,\r
+                              1843200,\r
+                              1638400,\r
+                              1474560,\r
+                              1340509,\r
+                              1228800,\r
+                              1134277,\r
+                              1053257};\r
+  \r
+  const_uint16_t corTbl[9] = {1213,\r
+                             1416,\r
+                             1618,\r
+                             1820,\r
+                             2022,\r
+                             2224,\r
+                             2427,\r
+                             2629,\r
+                             2831};\r
+  \r
+  const_uint16_t fSepTbl[9] = {0x1AA,\r
+                              0x1F1,\r
+                              0x238,\r
+                              0x280,\r
+                              0x2C7,\r
+                              0x30E,\r
+                              0x355,\r
+                              0x39C,\r
+                              0x3E3};\r
+  \r
+  void calibrateNow() {\r
+    // start cal\r
+    call CC.write(CC1K_CAL,\r
+                 1 << CC1K_CAL_START |\r
+                 1 << CC1K_CAL_WAIT |\r
+                 6 << CC1K_CAL_ITERATE);\r
+    while ((call CC.read(CC1K_CAL) & 1 << CC1K_CAL_COMPLETE) == 0)\r
+      ;\r
+\r
+    //exit cal mode\r
+    call CC.write(CC1K_CAL, 1 << CC1K_CAL_WAIT | 6 << CC1K_CAL_ITERATE);\r
+  }\r
+\r
+  void calibrate() {\r
+    call CC.write(CC1K_PA_POW, 0x00);  // turn off rf amp\r
+    call CC.write(CC1K_TEST4, 0x3f);   // chip rate >= 38.4kb\r
+\r
+    // RX - configure main freq A\r
+    call CC.write(CC1K_MAIN, 1 << CC1K_TX_PD | 1 << CC1K_RESET_N);\r
+\r
+    calibrateNow();\r
+\r
+    // TX - configure main freq B\r
+    call CC.write(CC1K_MAIN,\r
+                 1 << CC1K_RXTX |\r
+                 1 << CC1K_F_REG |\r
+                 1 << CC1K_RX_PD | \r
+                 1 << CC1K_RESET_N);\r
+    // Set TX current\r
+    call CC.write(CC1K_CURRENT, txCurrent);\r
+    call CC.write(CC1K_PA_POW, 0);\r
+\r
+    calibrateNow();\r
+  }\r
+\r
+  /*\r
+   * cc1000ComputeFreq(uint32_t desiredFreq);\r
+   *\r
+   * Compute an achievable frequency and the necessary CC1K parameters from\r
+   * a given desired frequency (Hz). The function returns the actual achieved\r
+   * channel frequency in Hz.\r
+   *\r
+   * This routine assumes the following:\r
+   *  - Crystal Freq: 14.7456 MHz\r
+   *  - LO Injection: High\r
+   *  - Separation: 64 KHz\r
+   *  - IF: 150 KHz\r
+   * \r
+   * Approximate costs for this function:\r
+   *  - ~870 bytes FLASH\r
+   *  - ~32 bytes RAM\r
+   *  - 9400 cycles\r
+   */\r
+  uint32_t cc1000SetFrequency(uint32_t desiredFreq) {\r
+    uint32_t ActualChannel = 0;\r
+    uint32_t RXFreq = 0, TXFreq = 0;\r
+    int32_t Offset = 0x7fffffff;\r
+    uint16_t FSep = 0;\r
+    uint8_t RefDiv = 0;\r
+    uint8_t i, match, frontend;\r
+\r
+    for (i = 0; i < 9; i++)\r
+      {\r
+       uint32_t NRef = desiredFreq + IF;\r
+       uint32_t FRef = read_uint32_t(&fRefTbl[i]);\r
+       uint32_t Channel = 0;\r
+       uint32_t RXCalc = 0, TXCalc = 0;\r
+       int32_t  diff;\r
+\r
+       NRef = ((desiredFreq + IF)  <<  2) / FRef;\r
+       if (NRef & 0x1)\r
+         NRef++;\r
+\r
+       if (NRef & 0x2)\r
+         {\r
+           RXCalc = 16384 >> 1;\r
+           Channel = FRef >> 1;\r
+         }\r
+\r
+       NRef >>= 2;\r
+\r
+       RXCalc += (NRef * 16384) - 8192;\r
+       if ((RXCalc < FREQ_MIN) || (RXCalc > FREQ_MAX)) \r
+         continue;\r
+    \r
+       TXCalc = RXCalc - read_uint16_t(&corTbl[i]);\r
+       if (TXCalc < FREQ_MIN || TXCalc > FREQ_MAX)\r
+         continue;\r
+\r
+       Channel += NRef * FRef;\r
+       Channel -= IF;\r
+\r
+       diff = Channel - desiredFreq;\r
+       if (diff < 0)\r
+         diff = -diff;\r
+\r
+       if (diff < Offset)\r
+         {\r
+           RXFreq = RXCalc;\r
+           TXFreq = TXCalc;\r
+           ActualChannel = Channel;\r
+           FSep = read_uint16_t(&fSepTbl[i]);\r
+           RefDiv = i + 6;\r
+           Offset = diff;\r
+         }\r
+      }\r
+\r
+    if (RefDiv != 0)\r
+      {\r
+       call CC.write(CC1K_FREQ_0A, RXFreq);\r
+       call CC.write(CC1K_FREQ_1A, RXFreq >> 8);\r
+       call CC.write(CC1K_FREQ_2A, RXFreq >> 16);\r
+\r
+       call CC.write(CC1K_FREQ_0B, TXFreq);\r
+       call CC.write(CC1K_FREQ_1B, TXFreq >> 8);\r
+       call CC.write(CC1K_FREQ_2B, TXFreq >> 16);\r
+\r
+       call CC.write(CC1K_FSEP0, FSep);\r
+       call CC.write(CC1K_FSEP1, FSep >> 8);\r
+\r
+       if (ActualChannel < 500000000)\r
+         {\r
+           if (ActualChannel < 400000000)\r
+             {\r
+               rxCurrent = 8 << CC1K_VCO_CURRENT | 1 << CC1K_LO_DRIVE;\r
+               txCurrent = 9 << CC1K_VCO_CURRENT | 1 << CC1K_PA_DRIVE;\r
+             }\r
+           else\r
+             {\r
+               rxCurrent = 4 << CC1K_VCO_CURRENT | 1 << CC1K_LO_DRIVE;\r
+               txCurrent = 8 << CC1K_VCO_CURRENT | 1 << CC1K_PA_DRIVE;\r
+             }\r
+           frontend = 1 << CC1K_IF_RSSI;\r
+           match = 7 << CC1K_RX_MATCH;\r
+         }\r
+       else\r
+         {\r
+           rxCurrent = 8 << CC1K_VCO_CURRENT | 3 << CC1K_LO_DRIVE;\r
+           txCurrent = 15 << CC1K_VCO_CURRENT | 3 << CC1K_PA_DRIVE;\r
+\r
+           frontend =\r
+             1 << CC1K_BUF_CURRENT | 2 << CC1K_LNA_CURRENT | \r
+             1 << CC1K_IF_RSSI;\r
+           match = 2 << CC1K_RX_MATCH; // datasheet says to use 1...\r
+         }\r
+       call CC.write(CC1K_CURRENT, rxCurrent);\r
+       call CC.write(CC1K_MATCH, match);\r
+       call CC.write(CC1K_FRONT_END, frontend);\r
+       call CC.write(CC1K_PLL, RefDiv << CC1K_REFDIV);\r
+      }\r
+\r
+    return ActualChannel;\r
+  }\r
+\r
+  command void CC1000Control.init() {\r
+    call CC.init();\r
+\r
+    // wake up xtal and reset unit\r
+    call CC.write(CC1K_MAIN,\r
+                 1 << CC1K_RX_PD | 1 << CC1K_TX_PD | \r
+                 1 << CC1K_FS_PD | 1 << CC1K_BIAS_PD); \r
+    // clear reset.\r
+    call CC1000Control.coreOn();\r
+    call BusyWait.wait(2000);\r
+\r
+    // Set default parameter values\r
+    // POWER: 0dbm (~900MHz), 6dbm (~430MHz)\r
+    power = 8 << CC1K_PA_HIGHPOWER | 0 << CC1K_PA_LOWPOWER;\r
+    call CC.write(CC1K_PA_POW, power);\r
+\r
+    // select Manchester Violation for CHP_OUT\r
+    call CC.write(CC1K_LOCK_SELECT, 9 << CC1K_LOCK_SELECT);\r
+\r
+    // Default modem values = 19.2 Kbps (38.4 kBaud), Manchester encoded\r
+    call CC.write(CC1K_MODEM2, 0);\r
+    call CC.write(CC1K_MODEM1, \r
+                 3 << CC1K_MLIMIT |\r
+                 1 << CC1K_LOCK_AVG_MODE | \r
+                 3 << CC1K_SETTLING |\r
+                 1 << CC1K_MODEM_RESET_N);\r
+    call CC.write(CC1K_MODEM0, \r
+                 5 << CC1K_BAUDRATE |\r
+                 1 << CC1K_DATA_FORMAT | \r
+                 1 << CC1K_XOSC_FREQ);\r
+\r
+    call CC.write(CC1K_FSCTRL, 1 << CC1K_FS_RESET_N);\r
+\r
+#ifdef CC1K_DEF_FREQ\r
+    call CC1000Control.tuneManual(CC1K_DEF_FREQ);\r
+#else\r
+    call CC1000Control.tunePreset(CC1K_DEF_PRESET);\r
+#endif\r
+    call CC1000Control.off();\r
+  }\r
+\r
+  command void CC1000Control.tunePreset(uint8_t freq) {\r
+    int i;\r
+\r
+    // FREQA, FREQB, FSEP, CURRENT(RX), FRONT_END, POWER, PLL\r
+    for (i = CC1K_FREQ_2A; i <= CC1K_PLL; i++)\r
+      call CC.write(i, read_uint8_t(&CC1K_Params[freq][i]));\r
+    call CC.write(CC1K_MATCH, read_uint8_t(&CC1K_Params[freq][CC1K_MATCH]));\r
+    rxCurrent = read_uint8_t(&CC1K_Params[freq][CC1K_CURRENT]);\r
+    txCurrent = read_uint8_t(&CC1K_Params[freq][CC1K_MATCH + 1]);\r
+    power = read_uint8_t(&CC1K_Params[freq][CC1K_PA_POW]);\r
+\r
+    calibrate();\r
+  }\r
+\r
+  command uint32_t CC1000Control.tuneManual(uint32_t DesiredFreq) {\r
+    uint32_t actualFreq;\r
+\r
+    actualFreq = cc1000SetFrequency(DesiredFreq);\r
+\r
+    calibrate();\r
+\r
+    return actualFreq;\r
+  }\r
+\r
+  async command void CC1000Control.txMode() {\r
+    // MAIN register to TX mode\r
+    call CC.write(CC1K_MAIN,\r
+                 1 << CC1K_RXTX |\r
+                 1 << CC1K_F_REG |\r
+                 1 << CC1K_RX_PD | \r
+                 1 << CC1K_RESET_N);\r
+    // Set the TX mode VCO Current\r
+    call CC.write(CC1K_CURRENT, txCurrent);\r
+    call BusyWait.wait(250);\r
+    call CC.write(CC1K_PA_POW, power);\r
+    call BusyWait.wait(20);\r
+  }\r
+\r
+  async command void CC1000Control.rxMode() {\r
+    // MAIN register to RX mode\r
+    // Powerup Freqency Synthesizer and Receiver\r
+    call CC.write(CC1K_CURRENT, rxCurrent);\r
+    call CC.write(CC1K_PA_POW, 0); // turn off power amp\r
+    call CC.write(CC1K_MAIN, 1 << CC1K_TX_PD | 1 << CC1K_RESET_N);\r
+    call BusyWait.wait(125);\r
+  }\r
+\r
+  async command void CC1000Control.coreOn() {\r
+    // MAIN register to SLEEP mode\r
+    call CC.write(CC1K_MAIN,\r
+                 1 << CC1K_RX_PD |\r
+                 1 << CC1K_TX_PD | \r
+                 1 << CC1K_FS_PD |\r
+                 1 << CC1K_BIAS_PD |\r
+                 1 << CC1K_RESET_N);\r
+  }\r
+\r
+  async command void CC1000Control.biasOn() {\r
+    call CC.write(CC1K_MAIN,\r
+                 1 << CC1K_RX_PD |\r
+                 1 << CC1K_TX_PD | \r
+                 1 << CC1K_FS_PD | \r
+                 1 << CC1K_RESET_N);\r
+  }\r
+\r
+\r
+  async command void CC1000Control.off() {\r
+    // MAIN register to power down mode. Shut everything off\r
+    call CC.write(CC1K_MAIN,\r
+                 1 << CC1K_RX_PD |\r
+                 1 << CC1K_TX_PD | \r
+                 1 << CC1K_FS_PD |\r
+                 1 << CC1K_CORE_PD |\r
+                 1 << CC1K_BIAS_PD |\r
+                 1 << CC1K_RESET_N);\r
+    call CC.write(CC1K_PA_POW, 0);  // turn off rf amp\r
+  }\r
+\r
+  command void CC1000Control.setRFPower(uint8_t newPower) {\r
+    power = newPower;\r
+  }\r
+\r
+  command uint8_t CC1000Control.getRFPower() {\r
+    return power;\r
+  }\r
+\r
+  command void CC1000Control.selectLock(uint8_t fn) {\r
+    // Select function of CHP_OUT pin (readable via getLock)\r
+    call CC.write(CC1K_LOCK, fn << CC1K_LOCK_SELECT);\r
+  }\r
+\r
+  command uint8_t CC1000Control.getLock() {\r
+    return call CC.getLOCK(); \r
+  }\r
+\r
+  command bool CC1000Control.getLOStatus() {\r
+    // We use a high-side LO (local oscillator) frequency -> data will be\r
+    // inverted. See cc1000ComputeFreq and CC1000 datasheet p.23.\r
+    return TRUE;\r
+  }\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CC1000CsmaP.nc b/tos/chips/cc1000_lpl/CC1000CsmaP.nc
new file mode 100644 (file)
index 0000000..6cb8716
--- /dev/null
@@ -0,0 +1,579 @@
+// $Id$\r
+\r
+/*                                                                        tab:4\r
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2002-2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+\r
+#include "message.h"\r
+#include "crc.h"\r
+#include "CC1000Const.h"\r
+#include "Timer.h"\r
+\r
+/**\r
+ * A rewrite of the low-power-listening CC1000 radio stack.\r
+ * This file contains the CSMA and low-power listening logic. Actual\r
+ * packet transmission and reception is in SendReceive.\r
+ * <p>\r
+ * This code has some degree of platform-independence, via the\r
+ * CC1000Control, RSSIADC and SpiByteFifo interfaces which must be provided\r
+ * by the platform. However, these interfaces may still reflect some\r
+ * particularities of the mica2 hardware implementation.\r
+ *\r
+ * @author Philip Buonadonna\r
+ * @author Jaein Jeong\r
+ * @author Joe Polastre\r
+ * @author David Gay\r
+ */\r
+  \r
+module CC1000CsmaP {\r
+  provides {\r
+    interface Init;\r
+    interface SplitControl;\r
+    interface CsmaControl;\r
+    interface CsmaBackoff;\r
+    interface LowPowerListening;\r
+  }\r
+  uses {\r
+    interface Init as ByteRadioInit;\r
+    interface StdControl as ByteRadioControl;\r
+    interface ByteRadio;\r
+\r
+    //interface PowerManagement;\r
+    interface CC1000Control;\r
+    interface CC1000Squelch;\r
+    interface Random;\r
+    interface Timer<TMilli> as WakeupTimer;\r
+    interface BusyWait<TMicro, uint16_t>;\r
+\r
+    interface ReadNow<uint16_t> as RssiNoiseFloor;\r
+    interface ReadNow<uint16_t> as RssiCheckChannel;\r
+    interface ReadNow<uint16_t> as RssiPulseCheck;\r
+    async command void cancelRssi();\r
+  }\r
+}\r
+implementation \r
+{\r
+  enum {\r
+    DISABLED_STATE,\r
+    IDLE_STATE,\r
+    RX_STATE,\r
+    TX_STATE,\r
+    POWERDOWN_STATE,\r
+    PULSECHECK_STATE\r
+  };\r
+\r
+  enum {\r
+    TIME_AFTER_CHECK =  30,\r
+  };\r
+\r
+  uint8_t radioState = DISABLED_STATE;\r
+  struct {\r
+    uint8_t ccaOff : 1;\r
+    uint8_t txPending : 1;\r
+  } f; // f for flags\r
+  uint8_t count;\r
+  uint8_t clearCount;\r
+\r
+  int16_t macDelay;\r
+\r
+  uint16_t sleepTime;\r
+\r
+  uint16_t rssiForSquelch;\r
+\r
+  task void setWakeupTask();\r
+\r
+  cc1000_metadata_t *getMetadata(message_t *amsg) {\r
+    return (cc1000_metadata_t *)((uint8_t *)amsg->footer + sizeof(cc1000_footer_t));\r
+  }\r
+  \r
+  void enterIdleState() {\r
+    call cancelRssi();\r
+    radioState = IDLE_STATE;\r
+  }\r
+\r
+  void enterIdleStateSetWakeup() {\r
+    enterIdleState();\r
+    post setWakeupTask();\r
+  }\r
+\r
+  void enterDisabledState() {\r
+    call cancelRssi();\r
+    radioState = DISABLED_STATE;\r
+  }\r
+\r
+  void enterPowerDownState() {\r
+    call cancelRssi();\r
+    radioState = POWERDOWN_STATE;\r
+  }\r
+\r
+  void enterPulseCheckState() {\r
+    radioState = PULSECHECK_STATE;\r
+    count = 0;\r
+  }\r
+\r
+  void enterRxState() {\r
+    call cancelRssi();\r
+    radioState = RX_STATE;\r
+  }\r
+\r
+  void enterTxState() {\r
+    radioState = TX_STATE;\r
+  }\r
+\r
+  /* Basic radio power control */\r
+\r
+  void radioOn() {\r
+    call CC1000Control.coreOn();\r
+    call BusyWait.wait(2000);\r
+    call CC1000Control.biasOn();\r
+    call BusyWait.wait(200);\r
+    atomic call ByteRadio.listen();\r
+  }\r
+\r
+  void radioOff() {\r
+    call CC1000Control.off();\r
+    call ByteRadio.off();\r
+  }\r
+\r
+  void setPreambleLength(message_t *msg);\r
+\r
+  /* Initialisation, startup and stopping */\r
+  /*--------------------------------------*/\r
+\r
+  command error_t Init.init() {\r
+    call ByteRadioInit.init();\r
+    call CC1000Control.init();\r
+\r
+    return SUCCESS;\r
+  }\r
+\r
+  task void startStopDone() {\r
+    uint8_t s;\r
+\r
+    // Save a byte of RAM by sharing start/stopDone task\r
+    atomic s = radioState;\r
+    if (s == DISABLED_STATE)\r
+      signal SplitControl.stopDone(SUCCESS);\r
+    else\r
+      signal SplitControl.startDone(SUCCESS);\r
+  }\r
+\r
+  command error_t SplitControl.start() {\r
+    atomic \r
+      if (radioState == DISABLED_STATE)\r
+        {\r
+          call ByteRadioControl.start();\r
+          enterIdleStateSetWakeup();\r
+          f.txPending = FALSE;\r
+        }\r
+      else\r
+        return SUCCESS;\r
+\r
+    radioOn();\r
+\r
+    post startStopDone();\r
+\r
+    return SUCCESS;\r
+  }\r
+\r
+  command error_t SplitControl.stop() {\r
+    atomic \r
+      {\r
+        call ByteRadioControl.stop();\r
+        enterDisabledState();\r
+        radioOff();\r
+      }\r
+    call WakeupTimer.stop();\r
+    post startStopDone();\r
+    return SUCCESS;\r
+  }\r
+\r
+  /* Wakeup timer */\r
+  /*-------------*/\r
+\r
+  /* All timer setting code is placed in setWakeup, for consistency. */\r
+  void setWakeup() {\r
+    switch (radioState)\r
+      {\r
+      case IDLE_STATE:\r
+        /* Timer already running means that we have a noise floor\r
+           measurement scheduled. If we just set a new alarm here, we\r
+           might indefinitely delay noise floor measurements if we're,\r
+           e,g, transmitting frequently. */\r
+        if (!call WakeupTimer.isRunning())\r
+          if (call CC1000Squelch.settled())\r
+            {\r
+              if (sleepTime == 0)\r
+                call WakeupTimer.startOneShot(CC1K_SquelchIntervalSlow);\r
+              else\r
+                // timeout for receiving a message after an lpl check\r
+                // indicates channel activity.\r
+                call WakeupTimer.startOneShot(TIME_AFTER_CHECK);\r
+            }\r
+          else\r
+            call WakeupTimer.startOneShot(CC1K_SquelchIntervalFast);\r
+        break;\r
+      case PULSECHECK_STATE:\r
+        // Radio warm-up time.\r
+        call WakeupTimer.startOneShot(1);\r
+        break;\r
+      case POWERDOWN_STATE:\r
+        // low-power listening check interval\r
+        call WakeupTimer.startOneShot(sleepTime);\r
+        break;\r
+      }\r
+  }\r
+\r
+  task void setWakeupTask() {\r
+    atomic setWakeup();\r
+  }\r
+\r
+  event void WakeupTimer.fired() {\r
+    atomic \r
+      {\r
+        switch (radioState)\r
+          {\r
+          case IDLE_STATE:\r
+            /* If we appear to be receiving a packet we don't check the\r
+               noise floor. For LPL, this means that going to sleep will\r
+               be delayed by another TIME_AFTER_CHECK ms. */\r
+            if (!call ByteRadio.syncing())\r
+              {\r
+                call cancelRssi();\r
+                call RssiNoiseFloor.read();\r
+              }\r
+            break;\r
+\r
+          case POWERDOWN_STATE:\r
+            // Turn radio on, wait for 1ms\r
+            enterPulseCheckState();\r
+            call CC1000Control.biasOn();\r
+            break;\r
+\r
+          case PULSECHECK_STATE:\r
+            // Switch to RX mode and get RSSI output\r
+            call CC1000Control.rxMode();\r
+            call RssiPulseCheck.read();\r
+            call BusyWait.wait(80);\r
+            return; // don't set wakeup timer\r
+          }\r
+        setWakeup();\r
+      }\r
+  }\r
+\r
+  /* Low-power listening stuff */\r
+  /*---------------------------*/\r
+\r
+  /* Should we go to sleep, or turn the radio fully on? */\r
+  task void sleepCheck() {\r
+    bool turnOn = FALSE;\r
+\r
+    atomic\r
+      if (f.txPending || !sleepTime)\r
+        {\r
+          if (radioState == PULSECHECK_STATE || radioState == POWERDOWN_STATE)\r
+            {\r
+              enterIdleStateSetWakeup();\r
+              turnOn = TRUE;\r
+            }\r
+        }\r
+      else if (call CC1000Squelch.settled() && !call ByteRadio.syncing())\r
+        {\r
+          radioOff();\r
+          enterPowerDownState();\r
+          setWakeup();\r
+        }\r
+\r
+    if (turnOn)\r
+      radioOn();\r
+  }\r
+\r
+  task void adjustSquelch();\r
+\r
+  async event void RssiPulseCheck.readDone(error_t result, uint16_t data) {\r
+    if (result != SUCCESS)\r
+      {\r
+        /* Just give up on this interval. */\r
+        post sleepCheck();\r
+        return;\r
+      }\r
+\r
+    /* We got some RSSI data for our LPL check. Decide whether to:\r
+       - go back to sleep (quiet)\r
+       - wake up (channel active)\r
+       - get more RSSI data\r
+    */\r
+    if (data > call CC1000Squelch.get() - (call CC1000Squelch.get() >> 2))\r
+      {\r
+        post sleepCheck();\r
+        // don't be too agressive (ignore really quiet thresholds).\r
+        if (data < call CC1000Squelch.get() + (call CC1000Squelch.get() >> 3))\r
+          {\r
+            // adjust the noise floor level, go back to sleep.\r
+            rssiForSquelch = data;\r
+            post adjustSquelch();\r
+          }\r
+      }\r
+    else if (count++ > 5)\r
+      {\r
+        //go to the idle state since no outliers were found\r
+        enterIdleStateSetWakeup();\r
+        call ByteRadio.listen();\r
+      }\r
+    else\r
+      {\r
+        call RssiPulseCheck.read();\r
+        call BusyWait.wait(80);\r
+      }\r
+  }\r
+\r
+  /* CSMA */\r
+  /*------*/\r
+\r
+  event void ByteRadio.rts(message_t *msg) {\r
+    atomic\r
+      {\r
+        f.txPending = TRUE;\r
+\r
+        if (radioState == POWERDOWN_STATE)\r
+          post sleepCheck();\r
+        if (!f.ccaOff)\r
+          macDelay = signal CsmaBackoff.initial(call ByteRadio.getTxMessage());\r
+        else\r
+          macDelay = 1;\r
+\r
+        setPreambleLength(msg);\r
+      }\r
+  }\r
+\r
+  async event void ByteRadio.sendDone() {\r
+    f.txPending = FALSE;\r
+    enterIdleStateSetWakeup();\r
+  }\r
+\r
+  void congestion() {\r
+    macDelay = signal CsmaBackoff.congestion(call ByteRadio.getTxMessage());\r
+  }\r
+\r
+  async event void ByteRadio.idleByte(bool preamble) {\r
+    if (f.txPending)\r
+      {\r
+        if (!f.ccaOff && preamble)\r
+          congestion();\r
+        else if (macDelay && !--macDelay)\r
+          {\r
+            call cancelRssi();\r
+            count = 0;\r
+            call RssiCheckChannel.read();\r
+          }\r
+      }\r
+  }\r
+\r
+  async event void RssiCheckChannel.readDone(error_t result, uint16_t data) {\r
+    if (result != SUCCESS)\r
+      {\r
+        /* We'll retry the transmission at the next SPI event. */\r
+        atomic macDelay = 1;\r
+        return;\r
+      }\r
+\r
+    count++;\r
+    if (data > call CC1000Squelch.get() + CC1K_SquelchBuffer)\r
+      clearCount++;\r
+    else\r
+      clearCount = 0;\r
+\r
+    // if the channel is clear or CCA is disabled, GO GO GO!\r
+    if (clearCount >= 1 || f.ccaOff)\r
+      {\r
+        enterTxState();\r
+        call ByteRadio.cts();\r
+      }\r
+    else if (count == CC1K_MaxRSSISamples)\r
+      congestion();\r
+    else \r
+      call RssiCheckChannel.read();\r
+  }\r
+\r
+  /* Message being received. We basically just go inactive. */\r
+  /*--------------------------------------------------------*/\r
+\r
+  async event void ByteRadio.rx() {\r
+    enterRxState();\r
+  }\r
+\r
+  async event void ByteRadio.rxDone() {\r
+    if (radioState == RX_STATE)\r
+      enterIdleStateSetWakeup();\r
+  }\r
+\r
+  /* Noise floor */\r
+  /*-------------*/\r
+\r
+  task void adjustSquelch() {\r
+    uint16_t squelchData;\r
+\r
+    atomic squelchData = rssiForSquelch;\r
+    call CC1000Squelch.adjust(squelchData);\r
+  }\r
+\r
+  async event void RssiNoiseFloor.readDone(error_t result, uint16_t data) {\r
+    if (result != SUCCESS)\r
+      {\r
+        /* We just ignore failed noise floor measurements */\r
+        post sleepCheck();\r
+        return;\r
+      }\r
+\r
+    rssiForSquelch = data;\r
+    post adjustSquelch();\r
+    post sleepCheck();\r
+  }\r
+\r
+  /* Options */\r
+  /*---------*/\r
+\r
+  async command error_t CsmaControl.enableCca() {\r
+    atomic f.ccaOff = FALSE;\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command error_t CsmaControl.disableCca() {\r
+    atomic f.ccaOff = TRUE;\r
+    return SUCCESS;\r
+  }\r
+\r
+  /* Default MAC backoff parameters */\r
+  /*--------------------------------*/\r
+\r
+  default async event uint16_t CsmaBackoff.initial(message_t *m) { \r
+    // initially back off [1,32] bytes (approx 2/3 packet)\r
+    return (call Random.rand16() & 0x1F) + 1;\r
+  }\r
+\r
+  default async event uint16_t CsmaBackoff.congestion(message_t *m) { \r
+    return (call Random.rand16() & 0xF) + 1;\r
+  }\r
+\r
+  /* LowPowerListening setup */\r
+  /* ----------------------- */\r
+\r
+  uint16_t validateSleepInterval(uint16_t sleepIntervalMs) {\r
+    if (sleepIntervalMs < CC1K_LPL_MIN_INTERVAL)\r
+      return 0;\r
+    else if (sleepIntervalMs > CC1K_LPL_MAX_INTERVAL)\r
+      return CC1K_LPL_MAX_INTERVAL;\r
+    else\r
+      return sleepIntervalMs;\r
+  }\r
+\r
+  uint16_t dutyToSleep(uint16_t dutyCycle) {\r
+    /* Scaling factors on CC1K_LPL_CHECK_TIME and dutyCycle are identical */\r
+    uint16_t interval = (1000 * CC1K_LPL_CHECK_TIME) / dutyCycle;\r
+\r
+    return interval < CC1K_LPL_MIN_INTERVAL ? 0 : interval;\r
+  }\r
+\r
+  uint16_t sleepToDuty(uint16_t sleepInterval) {\r
+    if (sleepInterval < CC1K_LPL_MIN_INTERVAL)\r
+      return 10000;\r
+\r
+    /* Scaling factors on CC1K_LPL_CHECK_TIME and dutyCycle are identical */\r
+    return (1000 * CC1K_LPL_CHECK_TIME) / sleepInterval;\r
+  }\r
+\r
+  command void LowPowerListening.setLocalSleepInterval(uint16_t s) {\r
+    sleepTime = validateSleepInterval(s);\r
+  }\r
+\r
+  command uint16_t LowPowerListening.getLocalSleepInterval() {\r
+    return sleepTime;\r
+  }\r
+\r
+  command void LowPowerListening.setLocalDutyCycle(uint16_t d) {\r
+    return call LowPowerListening.setLocalSleepInterval(dutyToSleep(d));\r
+  }\r
+\r
+  command uint16_t LowPowerListening.getLocalDutyCycle() {\r
+    return sleepToDuty(call LowPowerListening.getLocalSleepInterval());\r
+  }\r
+\r
+  command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) {\r
+    cc1000_metadata_t *meta = getMetadata(msg);\r
+\r
+    meta->strength_or_preamble = -(int16_t)validateSleepInterval(sleepIntervalMs) - 1;\r
+  }\r
+\r
+  command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) {\r
+    cc1000_metadata_t *meta = getMetadata(msg);\r
+\r
+    if (meta->strength_or_preamble >= 0)\r
+      return sleepTime;\r
+    else\r
+      return -(meta->strength_or_preamble + 1);\r
+  }\r
+\r
+  command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t d) {\r
+    return call LowPowerListening.setRxSleepInterval(msg, dutyToSleep(d));\r
+  }\r
+\r
+  command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) {\r
+    return sleepToDuty(call LowPowerListening.getRxSleepInterval(msg));\r
+  }\r
+\r
+  command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t d) {\r
+    return dutyToSleep(d);\r
+  }\r
+\r
+  command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t s) {\r
+    return sleepToDuty(s);\r
+  }\r
+\r
+  void setPreambleLength(message_t *msg) {\r
+    cc1000_metadata_t *meta = getMetadata(msg);\r
+    uint16_t s;\r
+    uint32_t plen;\r
+\r
+    if (meta->strength_or_preamble >= 0)\r
+      s = sleepTime;\r
+    else\r
+      s = -(meta->strength_or_preamble + 1);\r
+    meta->strength_or_preamble = 0; /* Destroy setting */\r
+\r
+    if (s == 0)\r
+      plen = 6;\r
+    else\r
+      plen = (((s * 614UL) >> 8) / 6) + 22; \r
+    // ~ (s * 2.4)/6 + 22\r
+    // TODO remove the divide.  It's there so we still have a long preamble, but\r
+    // 6 times shorter than the regular preamble. This will increase\r
+    // delivery time while modulating the channel long enough to get detected.\r
+    \r
+    call ByteRadio.setPreambleLength(plen);\r
+  }\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CC1000CsmaRadioC.nc b/tos/chips/cc1000_lpl/CC1000CsmaRadioC.nc
new file mode 100644 (file)
index 0000000..cadfe49
--- /dev/null
@@ -0,0 +1,115 @@
+/* $Id$\r
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2002-2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+\r
+/**\r
+ * A low-power-listening CC1000 radio stack.\r
+ *\r
+ * Radio logic is split between Csma (media-access control, low-power\r
+ * listening and general control) and SendReceive (packet reception and\r
+ * transmission). \r
+ *\r
+ * CC1000RssiP (RSSI sharing), CC1000SquelchP (noise-floor estimation)\r
+ * and CC1000ControlP (radio configuration) provide supporting roles.\r
+ *\r
+ * This code has some degree of platform-independence, via the HplCC1000,\r
+ * RssiAdc and HplCC1000Spi interfaces which must be provided by the\r
+ * platform. However, these interfaces may still reflect some\r
+ * particularities of the mica2 hardware implementation.\r
+ *\r
+ * @author Joe Polastre\r
+ * @author David Gay\r
+ */\r
+\r
+#include "CC1000Const.h"\r
+#include "message.h"\r
+\r
+configuration CC1000CsmaRadioC {\r
+  provides {\r
+    interface SplitControl;\r
+    interface Send;\r
+    interface Receive;\r
+\r
+    interface Packet;    \r
+    interface CsmaControl;\r
+    interface CsmaBackoff;\r
+    interface RadioTimeStamping;\r
+    interface PacketAcknowledgements;\r
+\r
+    interface LowPowerListening;\r
+  }\r
+}\r
+implementation {\r
+  components CC1000CsmaP as Csma;\r
+  components CC1000SendReceiveP as SendReceive;\r
+  components CC1000RssiP as Rssi;\r
+  components CC1000SquelchP as Squelch;\r
+  components CC1000ControlP as Control;\r
+  components HplCC1000C as Hpl;\r
+  components CC1000LowPowerListeningC;\r
+\r
+  components MainC, RandomC, new TimerMilliC(), ActiveMessageAddressC, BusyWaitMicroC;\r
+\r
+  MainC.SoftwareInit -> Csma;\r
+  MainC.SoftwareInit -> Squelch;\r
+\r
+  SplitControl = Csma;\r
+  Send = SendReceive;\r
+  Receive = SendReceive;\r
+  Packet = SendReceive;\r
+\r
+  CsmaControl = Csma;\r
+  CsmaBackoff = Csma;\r
+  LowPowerListening = Csma;\r
+  RadioTimeStamping = SendReceive;\r
+  PacketAcknowledgements = SendReceive;\r
+\r
+  Csma.CC1000Control -> Control;\r
+  Csma.Random -> RandomC;\r
+  Csma.CC1000Squelch -> Squelch;\r
+  Csma.WakeupTimer -> TimerMilliC;\r
+  Csma.ByteRadio -> SendReceive;\r
+  Csma.ByteRadioInit -> SendReceive;\r
+  Csma.ByteRadioControl -> SendReceive;\r
+  \r
+  SendReceive.CC1000Control -> Control;\r
+  SendReceive.HplCC1000Spi -> Hpl;\r
+  SendReceive.amAddress -> ActiveMessageAddressC;\r
+  SendReceive.RssiRx -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];\r
+  \r
+  Csma.RssiNoiseFloor -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];\r
+  Csma.RssiCheckChannel -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];\r
+  Csma.RssiPulseCheck -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];\r
+  Csma.cancelRssi -> Rssi;\r
+  Csma.BusyWait -> BusyWaitMicroC;\r
+\r
+  Rssi.ActualRssi -> Hpl;\r
+  Rssi.Resource -> Hpl;\r
+  Control.CC -> Hpl;\r
+  Control.BusyWait -> BusyWaitMicroC;\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CC1000LowPowerListening.h b/tos/chips/cc1000_lpl/CC1000LowPowerListening.h
new file mode 100644 (file)
index 0000000..6883ce8
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
\r
+ /**\r
+  * @author David Moss\r
+  */\r
+#ifndef CC1000LOWPOWERLISTENING_H\r
+#define CC1000LOWPOWERLISTENING_H\r
+\r
+/**\r
+ * The default duty period is usually 0, which is the equivalent of\r
+ * ONE_MESSAGE (below), which tells the node to transmit the message\r
+ * one time without expecting receiver duty cycling.\r
+ */\r
+#ifndef DEFAULT_TRANSMIT_PERIOD\r
+#define DEFAULT_TRANSMIT_PERIOD 0\r
+#endif\r
+\r
+/**\r
+ * Value used to indicate the message being sent should be transmitted\r
+ * one time\r
+ */\r
+#ifndef ONE_MESSAGE\r
+#define ONE_MESSAGE 0\r
+#endif\r
+\r
+#endif\r
+\r
diff --git a/tos/chips/cc1000_lpl/CC1000LowPowerListeningC.nc b/tos/chips/cc1000_lpl/CC1000LowPowerListeningC.nc
new file mode 100644 (file)
index 0000000..f6e296c
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Low Power Listening for the CC1000\r
+ * @author David Moss\r
+ */\r
\r
+#include "CC1000LowPowerListening.h"\r
+\r
+configuration CC1000LowPowerListeningC {\r
+  provides {\r
+    interface Send;\r
+    interface Receive;\r
+    interface CsmaBackoff[am_id_t amId];\r
+  }\r
+}\r
+\r
+implementation {\r
+  components MainC,\r
+      CC1000ActiveMessageC,\r
+      CC1000LowPowerListeningP,\r
+      CC1000CsmaRadioC,\r
+      RandomC,\r
+      new StateC() as SendStateC,\r
+      new StateC() as RadioPowerStateC,\r
+      new TimerMilliC() as SendDoneTimerC;\r
+  \r
+  Send = CC1000LowPowerListeningP;\r
+  Receive = CC1000LowPowerListeningP;\r
+  CsmaBackoff = CC1000LowPowerListeningP;\r
+  \r
+  MainC.SoftwareInit -> CC1000LowPowerListeningP;\r
+   \r
+  CC1000LowPowerListeningP.AMPacket -> CC1000ActiveMessageC;\r
+  CC1000LowPowerListeningP.Random -> RandomC;\r
+  CC1000LowPowerListeningP.SendState -> SendStateC;\r
+  CC1000LowPowerListeningP.RadioPowerState -> RadioPowerStateC;\r
+  CC1000LowPowerListeningP.SendDoneTimer -> SendDoneTimerC;\r
+  CC1000LowPowerListeningP.SubSend -> CC1000CsmaRadioC;\r
+  CC1000LowPowerListeningP.SubReceive -> CC1000CsmaRadioC;\r
+  CC1000LowPowerListeningP.SubControl -> CC1000CsmaRadioC;\r
+  CC1000LowPowerListeningP.PacketAcknowledgements -> CC1000CsmaRadioC;\r
+  CC1000LowPowerListeningP.SubBackoff -> CC1000CsmaRadioC;\r
+  CC1000LowPowerListeningP.CsmaControl -> CC1000CsmaRadioC;\r
+  CC1000LowPowerListeningP.LowPowerListening -> CC1000CsmaRadioC;\r
+  \r
+}\r
+\r
diff --git a/tos/chips/cc1000_lpl/CC1000LowPowerListeningP.nc b/tos/chips/cc1000_lpl/CC1000LowPowerListeningP.nc
new file mode 100644 (file)
index 0000000..8622da4
--- /dev/null
@@ -0,0 +1,338 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Low Power Listening for the CC1000\r
+ *\r
+ * @author David Moss\r
+ */\r
+\r
+#include "CC1000LowPowerListening.h"\r
+\r
+module CC1000LowPowerListeningP {\r
+  provides {\r
+    interface Init;\r
+    interface Send;\r
+    interface Receive;\r
+    interface CsmaBackoff[am_id_t amId];\r
+  }\r
+  \r
+  uses {\r
+    interface LowPowerListening;\r
+    interface CsmaBackoff as SubBackoff;\r
+    interface CsmaControl;\r
+    interface Leds;\r
+    interface Send as SubSend;\r
+    interface Receive as SubReceive;\r
+    interface AMPacket;\r
+    interface SplitControl as SubControl;\r
+    interface PacketAcknowledgements;\r
+    interface State as SendState;\r
+    interface State as RadioPowerState;\r
+    interface Random;\r
+    interface Timer<TMilli> as SendDoneTimer;\r
+  }\r
+}\r
+\r
+implementation {\r
+  \r
+  /** The message currently being sent */\r
+  message_t *currentSendMsg;\r
+  \r
+  /** The length of the current send message */\r
+  uint8_t currentSendLen;\r
\r
+  /** Tx DSN to ensure multiple transmitted messages get across only once */ \r
+  uint8_t txDsn;\r
+  \r
+  /** The last received broadcast DSN. TODO is this the best way? */\r
+  uint8_t lastRxDsn;\r
+\r
+  /** TRUE if the first message of the current LPL delivery has been sent */\r
+  norace bool firstMessageSent;\r
+  \r
+  /**\r
+   * Radio State\r
+   */\r
+  enum {\r
+    S_OFF,\r
+    S_ON,\r
+  };\r
+  \r
+  /**\r
+   * Send States\r
+   */\r
+  enum {\r
+    S_IDLE,\r
+    S_SENDING,\r
+  };\r
+  \r
+  \r
+  /***************** Prototypes ***************/\r
+  task void send();\r
+  task void startRadio();\r
+  task void stopRadio();\r
+  \r
+  cc1000_header_t *getHeader(message_t *msg);\r
+  cc1000_metadata_t *getMetadata(message_t* msg);\r
+  uint16_t getActualDutyCycle(uint16_t dutyCycle);\r
+  void signalDone(error_t error);\r
+  \r
+  /***************** Init Commands ***************/\r
+  command error_t Init.init() {\r
+    txDsn = call Random.rand16();\r
+    return SUCCESS;\r
+  }\r
+  \r
+  \r
+  /***************** SubBackoff Events ****************/\r
+  async event uint16_t SubBackoff.initial(message_t* m) {\r
+    if(call SendState.getState() == S_SENDING\r
+        && getMetadata(m)->strength_or_preamble > ONE_MESSAGE\r
+        && firstMessageSent) {\r
+      call CsmaControl.disableCca();\r
+      return 1;\r
+      \r
+    } else {\r
+      return signal CsmaBackoff.initial[getHeader(m)->type](m);\r
+    }\r
+  }\r
+\r
+  async event uint16_t SubBackoff.congestion(message_t* m) {\r
+    if(call SendState.getState() == S_SENDING\r
+        && getMetadata(m)->strength_or_preamble > ONE_MESSAGE\r
+        && firstMessageSent) {\r
+      call CsmaControl.disableCca();\r
+      return 1;\r
+      \r
+    } else {\r
+      return signal CsmaBackoff.congestion[getHeader(m)->type](m);\r
+    }\r
+  }\r
+  \r
+  /***************** Send Commands ***************/\r
+  /**\r
+   * Each call to this send command gives the message a single\r
+   * DSN that does not change for every copy of the message\r
+   * sent out.  For messages that are not acknowledged, such as\r
+   * a broadcast address message, the receiving end does not\r
+   * signal receive() more than once for that message.\r
+   */\r
+  command error_t Send.send(message_t *msg, uint8_t len) {\r
+    if(call RadioPowerState.getState() == S_OFF) {\r
+      // Everything is off right now, start SplitControl and try again\r
+      return EOFF;\r
+    }\r
+    \r
+    if(call SendState.requestState(S_SENDING) == SUCCESS) {\r
+      currentSendMsg = msg;\r
+      currentSendLen = len;\r
+      (getHeader(msg))->dsn = ++txDsn;\r
+      \r
+      firstMessageSent = FALSE;\r
+      if(call LowPowerListening.getRxSleepInterval(currentSendMsg) \r
+          > ONE_MESSAGE) {\r
+          \r
+        // Send it repetitively within our transmit window\r
+        call PacketAcknowledgements.requestAck(currentSendMsg);\r
+        call SendDoneTimer.startOneShot(\r
+            call LowPowerListening.getRxSleepInterval(currentSendMsg) * 2);\r
+      }\r
+      \r
+      // If the radio is off, the CC1000Csma will automatically turn it on\r
+      post send();\r
+      return SUCCESS;\r
+    }\r
+    \r
+    return FAIL;\r
+  }\r
+\r
+  command error_t Send.cancel(message_t *msg) {\r
+    if(currentSendMsg == msg) {\r
+      call SendState.toIdle();\r
+      return SUCCESS;\r
+    }\r
+    \r
+    return FAIL;\r
+  }\r
+  \r
+  \r
+  command uint8_t Send.maxPayloadLength() {\r
+    return call SubSend.maxPayloadLength();\r
+  }\r
+\r
+  command void *Send.getPayload(message_t* msg) {\r
+    return call SubSend.getPayload(msg);\r
+  }\r
+  \r
+  /***************** Receive Commands ***************/\r
+  command void *Receive.getPayload(message_t* msg, uint8_t* len) {\r
+    return call SubReceive.getPayload(msg, len);\r
+  }\r
+\r
+  command uint8_t Receive.payloadLength(message_t* msg) {\r
+    return call SubReceive.payloadLength(msg);\r
+  }\r
+\r
+  \r
+  /***************** SubControl Events ***************/\r
+  event void SubControl.startDone(error_t error) {\r
+    if(!error) {\r
+      call RadioPowerState.forceState(S_ON);\r
+    }\r
+  }\r
+    \r
+  event void SubControl.stopDone(error_t error) {\r
+    if(!error) {\r
+      call RadioPowerState.forceState(S_OFF);\r
+    }\r
+  }\r
+  \r
+  /***************** SubSend Events ***************/\r
+  event void SubSend.sendDone(message_t* msg, error_t error) {\r
+    if(call SendState.getState() == S_SENDING  \r
+        && call SendDoneTimer.isRunning()) {\r
+      if(call PacketAcknowledgements.wasAcked(msg)) {\r
+        signalDone(error);\r
+        \r
+      } else {\r
+        post send();\r
+      }\r
+      \r
+      return;\r
+    }\r
+    \r
+    signalDone(error);\r
+  }\r
+  \r
+  /***************** SubReceive Events ***************/\r
+  /**\r
+   * If the received message is new, we signal the receive event and\r
+   * start the off timer.  If the last message we received had the same\r
+   * DSN as this message, then the chances are pretty good\r
+   * that this message should be ignored, especially if the destination address\r
+   * as the broadcast address\r
+   *\r
+   * TODO\r
+   * What happens if a unicast Tx doesn't get Rx's ack, and resends that\r
+   * message?\r
+   */\r
+  event message_t *SubReceive.receive(message_t* msg, void* payload, \r
+      uint8_t len) {\r
+    \r
+    if((getHeader(msg))->dsn == lastRxDsn \r
+        && call AMPacket.destination(msg) == AM_BROADCAST_ADDR) {\r
+      // Already got this broadcast message.\r
+      // TODO should we do something similar with unicast messages?\r
+      return msg;\r
+\r
+    } else {\r
+      lastRxDsn = (getHeader(msg))->dsn;\r
+      return signal Receive.receive(msg, payload, len);\r
+    }\r
+  }\r
+  \r
+  /***************** Timer Events ****************/  \r
+  /**\r
+   * When this timer is running, that means we're sending repeating messages\r
+   * to a node that is receive check duty cycling.\r
+   */\r
+  event void SendDoneTimer.fired() {\r
+    if(call SendState.getState() == S_SENDING) {\r
+      // The next time SubSend.sendDone is signaled, send is complete.\r
+      call SendState.toIdle();\r
+    }\r
+  }\r
+  \r
+  /***************** Tasks ***************/\r
+  task void send() {\r
+    if(call SubSend.send(currentSendMsg, currentSendLen) != SUCCESS) {\r
+      post send();\r
+    }\r
+  }\r
+  \r
+  task void startRadio() {\r
+    if(call SubControl.start() != SUCCESS) {\r
+      post startRadio();\r
+    }\r
+  }\r
+  \r
+  task void stopRadio() {\r
+    if(call SubControl.stop() != SUCCESS) {\r
+      post stopRadio();\r
+    }\r
+  }\r
+  \r
+  /***************** Functions ***************/  \r
+  /**\r
+   * Check the bounds on a given duty cycle\r
+   * We're never over 100%, and we're never at 0%\r
+   */\r
+  uint16_t getActualDutyCycle(uint16_t dutyCycle) {\r
+    if(dutyCycle > 10000) {\r
+      return 10000;\r
+    } else if(dutyCycle == 0) {\r
+      return 1;\r
+    }\r
+    \r
+    return dutyCycle;\r
+  }\r
+  \r
+  cc1000_header_t *getHeader(message_t *msg) {\r
+    return (cc1000_header_t *)(msg->data - sizeof( cc1000_header_t ));\r
+  }\r
+  \r
+  cc1000_metadata_t *getMetadata(message_t* msg) {\r
+    return (cc1000_metadata_t*)msg->metadata;\r
+  }\r
+  \r
+  void signalDone(error_t error) {\r
+    call CsmaControl.enableCca();\r
+    call SendState.toIdle();\r
+    // TODO check for broadcast destination\r
+    signal Send.sendDone(currentSendMsg, error);\r
+    currentSendMsg = NULL;\r
+  }\r
+  \r
+  \r
+    \r
+  /***************** Defaults ****************/\r
+  default async event uint16_t CsmaBackoff.initial[am_id_t amId](message_t *m) {\r
+    return ( call Random.rand16() % (0x1F * CC1000_BACKOFF_PERIOD) \r
+        + CC1000_MIN_BACKOFF);\r
+  }\r
+\r
+  default async event uint16_t CsmaBackoff.congestion[am_id_t amId](message_t *m) {\r
+    return ( call Random.rand16() % (0x7 * CC1000_BACKOFF_PERIOD) \r
+        + CC1000_MIN_BACKOFF);\r
+  }\r
+}\r
+\r
diff --git a/tos/chips/cc1000_lpl/CC1000Msg.h b/tos/chips/cc1000_lpl/CC1000Msg.h
new file mode 100644 (file)
index 0000000..b8061d0
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef CC1K_RADIO_MSG_H\r
+#define CC1K_RADIO_MSG_H\r
+\r
+#include "AM.h"\r
+\r
+typedef nx_struct CC1KHeader {\r
+  nx_am_addr_t dest;\r
+  nx_am_addr_t source;\r
+  nx_uint8_t length;\r
+  nx_am_group_t group;\r
+  nx_uint8_t dsn;\r
+  nx_am_id_t type;\r
+} cc1000_header_t;\r
+\r
+typedef nx_struct CC1KFooter {\r
+  nxle_uint16_t crc;  \r
+} cc1000_footer_t;\r
+\r
+typedef nx_struct CC1KMetadata {\r
+  nx_int16_t strength_or_preamble; /* negative when used for preamble length */\r
+  nx_uint8_t ack;\r
+  nx_uint16_t time;\r
+  nx_uint8_t sendSecurityMode;\r
+  nx_uint8_t receiveSecurityMode;  \r
+} cc1000_metadata_t;\r
+\r
+#endif\r
diff --git a/tos/chips/cc1000_lpl/CC1000RssiP.nc b/tos/chips/cc1000_lpl/CC1000RssiP.nc
new file mode 100644 (file)
index 0000000..01126ab
--- /dev/null
@@ -0,0 +1,111 @@
+/* $Id$\r
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2002-2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+\r
+/**\r
+ *   RSSI fun. It's used for lots of things, and a request to read it\r
+ *   for one purpose may have to be discarded if conditions change. For\r
+ *   example, if we've initiated a noise-floor measure, but start \r
+ *   receiving a packet, we have to:<ul>\r
+ *   <li>cancel the noise-floor measure (we don't know if the value will\r
+ *     reflect the received packet or the previous idle state)\r
+ *   <li>start an RSSI measurement so that we can report signal strength\r
+ *     to the application\r
+ *   </ul><p>\r
+ *   This module hides the complexities of cancellation from the rest of\r
+ *   the stack.\r
+ */\r
+\r
+module CC1000RssiP\r
+{\r
+  provides {\r
+    interface ReadNow<uint16_t> as Rssi[uint8_t reason];\r
+    async command void cancel();\r
+  }\r
+  uses {\r
+    interface Resource;\r
+    interface ReadNow<uint16_t> as ActualRssi;\r
+  }\r
+}\r
+implementation\r
+{\r
+  enum {\r
+    IDLE = unique(UQ_CC1000_RSSI),\r
+    CANCELLED = unique(UQ_CC1000_RSSI)\r
+  };\r
+\r
+  /* All commands are called within atomic sections */\r
+  uint8_t currentOp = IDLE;\r
+  uint8_t nextOp;\r
+\r
+  async command void cancel() {\r
+    if (currentOp != IDLE)\r
+      currentOp = CANCELLED;\r
+  }\r
+\r
+  event void Resource.granted() {\r
+    call ActualRssi.read();\r
+  }\r
+\r
+  async command error_t Rssi.read[uint8_t reason]() {\r
+    if (currentOp == IDLE)\r
+      {\r
+       currentOp = reason;\r
+       if (call Resource.immediateRequest() == SUCCESS)\r
+         call ActualRssi.read();\r
+       else\r
+         call Resource.request();\r
+      }\r
+    else\r
+      nextOp = reason;\r
+    return SUCCESS;\r
+  }\r
+\r
+  void startNextOp() {\r
+    currentOp = nextOp;\r
+    if (nextOp != IDLE)\r
+      {\r
+       nextOp = IDLE;\r
+       call ActualRssi.read();\r
+      }\r
+    else\r
+      call Resource.release();\r
+  }\r
+\r
+  async event void ActualRssi.readDone(error_t result, uint16_t data) {\r
+    atomic\r
+      {\r
+       /* The code assumes that RSSI measurements are 10-bits \r
+          (legacy effect) */\r
+       signal Rssi.readDone[currentOp](result, data >> 6);\r
+       startNextOp();\r
+      }\r
+  }\r
+\r
+  default async event void Rssi.readDone[uint8_t reason](error_t result, uint16_t data) { }\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CC1000SendReceiveP.nc b/tos/chips/cc1000_lpl/CC1000SendReceiveP.nc
new file mode 100644 (file)
index 0000000..a45ae18
--- /dev/null
@@ -0,0 +1,675 @@
+// $Id$\r
+\r
+/*                                                                     tab:4\r
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2002-2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+#include "message.h"\r
+#include "crc.h"\r
+#include "CC1000Const.h"\r
+#include "Timer.h"\r
+\r
+/**\r
+ * A rewrite of the low-power-listening CC1000 radio stack.\r
+ * This file contains the send and receive logic for the CC1000 radio.\r
+ * It does not do any media-access control. It requests the channel\r
+ * via the ready-to-send event (rts) and starts transmission on reception\r
+ * of the clear-to-send command (cts). It listens for packets if the\r
+ * listen() command is called, and stops listening when off() is called.\r
+ * <p>\r
+ * This code has some degree of platform-independence, via the\r
+ * CC1000Control, RSSIADC and SpiByteFifo interfaces which must be provided\r
+ * by the platform. However, these interfaces may still reflect some\r
+ * particularities of the mica2 hardware implementation.\r
+ *\r
+ * @author Philip Buonadonna\r
+ * @author Jaein Jeong\r
+ * @author Joe Polastre\r
+ * @author David Gay\r
+ */\r
+  \r
+module CC1000SendReceiveP {\r
+  provides {\r
+    interface Init;\r
+    interface StdControl;\r
+    interface Send;\r
+    interface Receive;\r
+    interface RadioTimeStamping;\r
+    interface Packet;\r
+    interface ByteRadio;\r
+    interface PacketAcknowledgements;\r
+  }\r
+  uses {\r
+    //interface PowerManagement;\r
+    interface CC1000Control;\r
+    interface HplCC1000Spi;\r
+\r
+    interface ReadNow<uint16_t> as RssiRx;\r
+    async command am_addr_t amAddress();\r
+  }\r
+}\r
+implementation \r
+{\r
+  enum {\r
+    OFF_STATE,\r
+\r
+    INACTIVE_STATE,            /* Not listening, but will accept sends */\r
+\r
+    LISTEN_STATE,              /* Listening for packets */\r
+\r
+    /* Reception states */\r
+    SYNC_STATE,\r
+    RX_STATE,\r
+    RECEIVED_STATE,\r
+    SENDING_ACK,\r
+\r
+    /* Transmission states */\r
+    TXPREAMBLE_STATE,\r
+    TXSYNC_STATE,\r
+    TXDATA_STATE,\r
+    TXCRC_STATE,\r
+    TXFLUSH_STATE,\r
+    TXWAITFORACK_STATE,\r
+    TXREADACK_STATE,\r
+    TXDONE_STATE,\r
+  };\r
+\r
+  enum {\r
+    SYNC_BYTE1 =       0x33,\r
+    SYNC_BYTE2 =       0xcc,\r
+    SYNC_WORD =                SYNC_BYTE1 << 8 | SYNC_BYTE2,\r
+    ACK_BYTE1 =                0xba,\r
+    ACK_BYTE2 =                0x83,\r
+    ACK_WORD =                 ACK_BYTE1 << 8 | ACK_BYTE2,\r
+    ACK_LENGTH =       16,\r
+    MAX_ACK_WAIT =     18\r
+  };\r
+\r
+  uint8_t radioState;\r
+  struct {\r
+    uint8_t ack : 1;           /* acks enabled? */\r
+    uint8_t txBusy : 1;                /* send pending? */\r
+    uint8_t invert : 1;                /* data inverted? (see cc1000 datasheet) */\r
+    uint8_t rxBitOffset : 3;   /* bit-offset of received bytes */\r
+  } f; // f for flags\r
+  uint16_t count;\r
+  uint16_t runningCrc;\r
+\r
+  uint16_t rxShiftBuf;\r
+  message_t rxBuf;\r
+  message_t *rxBufPtr = &rxBuf;\r
+\r
+  uint16_t preambleLength;\r
+  message_t *txBufPtr;\r
+  uint8_t nextTxByte;\r
+\r
+  const_uint8_t ackCode[5] = { 0xab, ACK_BYTE1, ACK_BYTE2, 0xaa, 0xaa };\r
+\r
+  /* Packet structure accessor functions. Note that everything is\r
+   * relative to the data field. */\r
+  cc1000_header_t *getHeader(message_t *amsg) {\r
+    return (cc1000_header_t *)(amsg->data - sizeof(cc1000_header_t));\r
+  }\r
+\r
+  cc1000_footer_t *getFooter(message_t *amsg) {\r
+    return (cc1000_footer_t *)(amsg->footer);\r
+  }\r
+  \r
+  cc1000_metadata_t *getMetadata(message_t *amsg) {\r
+    return (cc1000_metadata_t *)((uint8_t *)amsg->footer + sizeof(cc1000_footer_t));\r
+  }\r
+  \r
+  /* State transition functions */\r
+  /*----------------------------*/\r
+\r
+  void enterOffState() {\r
+    radioState = OFF_STATE;\r
+  }\r
+\r
+  void enterInactiveState() {\r
+    radioState = INACTIVE_STATE;\r
+  }\r
+\r
+  void enterListenState() {\r
+    radioState = LISTEN_STATE;\r
+    count = 0;\r
+  }\r
+\r
+  void enterSyncState() {\r
+    radioState = SYNC_STATE;\r
+    count = 0;\r
+    rxShiftBuf = 0;\r
+  }\r
+\r
+  void enterRxState() {\r
+    cc1000_header_t *header = getHeader(rxBufPtr);\r
+    radioState = RX_STATE;\r
+    header->length = sizeof rxBufPtr->data;\r
+    count = sizeof(message_header_t) - sizeof(cc1000_header_t);\r
+    runningCrc = 0;\r
+  }\r
+\r
+  void enterReceivedState() {\r
+    radioState = RECEIVED_STATE;\r
+  }\r
+\r
+  void enterAckState() {\r
+    radioState = SENDING_ACK;\r
+    count = 0;\r
+  }\r
+\r
+  void enterTxPreambleState() {\r
+    radioState = TXPREAMBLE_STATE;\r
+    count = 0;\r
+    runningCrc = 0;\r
+    nextTxByte = 0xaa;\r
+  }\r
+\r
+  void enterTxSyncState() {\r
+    radioState = TXSYNC_STATE;\r
+  }\r
+\r
+  void enterTxDataState() {\r
+    radioState = TXDATA_STATE;\r
+    // The count increment happens before the first byte is read from the\r
+    // packet, so we subtract one from the real packet start point to\r
+    // compensate.\r
+    count = (sizeof(message_header_t) - sizeof(cc1000_header_t)) -1; \r
+  }\r
+\r
+  void enterTxCrcState() {\r
+    radioState = TXCRC_STATE;\r
+  }\r
+    \r
+  void enterTxFlushState() {\r
+    radioState = TXFLUSH_STATE;\r
+    count = 0;\r
+  }\r
+    \r
+  void enterTxWaitForAckState() {\r
+    radioState = TXWAITFORACK_STATE;\r
+    count = 0;\r
+  }\r
+    \r
+  void enterTxReadAckState() {\r
+    radioState = TXREADACK_STATE;\r
+    rxShiftBuf = 0;\r
+    count = 0;\r
+  }\r
+    \r
+  void enterTxDoneState() {\r
+    radioState = TXDONE_STATE;\r
+  }\r
+\r
+  command error_t Init.init() {\r
+    f.ack = TRUE; /* We always ack, for now at least */\r
+    call HplCC1000Spi.initSlave();\r
+    return SUCCESS;\r
+  }\r
+\r
+  command error_t StdControl.start() {\r
+    atomic \r
+      {\r
+       enterInactiveState();\r
+       f.txBusy = FALSE;\r
+       f.invert = call CC1000Control.getLOStatus();\r
+      }\r
+    return SUCCESS;\r
+  }\r
+\r
+  command error_t StdControl.stop() {\r
+    atomic enterOffState();\r
+    return SUCCESS;\r
+  }\r
+\r
+  /* Send side. Outside requests, SPI handlers for each state */\r
+  /*----------------------------------------------------------*/\r
+\r
+  command error_t Send.send(message_t *msg, uint8_t len) {\r
+    atomic\r
+      {\r
+       if (f.txBusy || radioState == OFF_STATE)\r
+         return FAIL;\r
+       else {\r
+         cc1000_header_t *header = getHeader(msg);\r
+\r
+         f.txBusy = TRUE;\r
+         header->length = len;\r
+         txBufPtr = msg;\r
+       }\r
+      }\r
+    signal ByteRadio.rts(msg);\r
+\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command void ByteRadio.cts() {\r
+    /* We're set to go! Start with our exciting preamble... */\r
+    enterTxPreambleState();\r
+    call HplCC1000Spi.writeByte(0xaa);\r
+    call CC1000Control.txMode();\r
+    call HplCC1000Spi.txMode();\r
+  }\r
+\r
+  command error_t Send.cancel(message_t *msg) {\r
+    /* We simply ignore cancellations. */\r
+    return FAIL;\r
+  }\r
+\r
+  void sendNextByte() {\r
+    call HplCC1000Spi.writeByte(nextTxByte);\r
+    count++;\r
+  }\r
+\r
+  void txPreamble() {\r
+    sendNextByte();\r
+    if (count >= preambleLength)\r
+      {\r
+       nextTxByte = SYNC_BYTE1;\r
+       enterTxSyncState();\r
+      }\r
+  }\r
+\r
+  void txSync() {\r
+    sendNextByte();\r
+    nextTxByte = SYNC_BYTE2;\r
+    enterTxDataState();\r
+    signal RadioTimeStamping.transmittedSFD(0, txBufPtr); \r
+  }\r
+\r
+  void txData() {\r
+    cc1000_header_t *txHeader = getHeader(txBufPtr);\r
+    sendNextByte();\r
+    \r
+    if (count < txHeader->length + sizeof(message_header_t))\r
+      {\r
+       nextTxByte = ((uint8_t *)txBufPtr)[count];\r
+       runningCrc = crcByte(runningCrc, nextTxByte);\r
+      }\r
+    else\r
+      {\r
+       nextTxByte = runningCrc;\r
+       enterTxCrcState();\r
+      }\r
+  }\r
+\r
+  void txCrc() {\r
+    sendNextByte();\r
+    nextTxByte = runningCrc >> 8;\r
+    enterTxFlushState();\r
+  }\r
+\r
+  void txFlush() {\r
+    sendNextByte();\r
+    if (count > 3)\r
+      if (f.ack)\r
+       enterTxWaitForAckState();\r
+      else\r
+       {\r
+         call HplCC1000Spi.rxMode();\r
+         call CC1000Control.rxMode();\r
+         enterTxDoneState();\r
+       }\r
+  }\r
+\r
+  void txWaitForAck() {\r
+    sendNextByte();\r
+    if (count == 1)\r
+      {\r
+       call HplCC1000Spi.rxMode();\r
+       call CC1000Control.rxMode();\r
+      }\r
+    else if (count > 3)\r
+      enterTxReadAckState();\r
+  }\r
+\r
+  void txReadAck(uint8_t in) {\r
+    uint8_t i;\r
+\r
+    sendNextByte();\r
+\r
+    for (i = 0; i < 8; i ++)\r
+      {\r
+       rxShiftBuf <<= 1;\r
+       if (in & 0x80)\r
+         rxShiftBuf |=  0x1;\r
+       in <<= 1;\r
+\r
+       if (rxShiftBuf == ACK_WORD)\r
+         {\r
+           getMetadata(txBufPtr)->ack = 1;\r
+           enterTxDoneState();\r
+           return;\r
+         }\r
+      }\r
+    if (count >= MAX_ACK_WAIT)\r
+      {\r
+       getMetadata(txBufPtr)->ack = 0;\r
+       enterTxDoneState();\r
+      }\r
+  }\r
+\r
+  task void signalPacketSent() {\r
+    message_t *pBuf;\r
+\r
+    atomic\r
+      {\r
+       pBuf = txBufPtr;\r
+       f.txBusy = FALSE;\r
+       enterListenState();\r
+      }\r
+    signal Send.sendDone(pBuf, SUCCESS);\r
+  }\r
+\r
+  void txDone() {\r
+    post signalPacketSent();\r
+    signal ByteRadio.sendDone();\r
+  }\r
+\r
+  /* Receive */\r
+  /*---------*/\r
+\r
+  void packetReceived();\r
+  void packetReceiveDone();\r
+\r
+  async command void ByteRadio.listen() {\r
+    enterListenState();\r
+    call CC1000Control.rxMode();\r
+    call HplCC1000Spi.rxMode();\r
+    call HplCC1000Spi.enableIntr();\r
+  }\r
+\r
+  async command void ByteRadio.off() {\r
+    enterInactiveState();\r
+    call HplCC1000Spi.disableIntr();\r
+  }\r
+\r
+  void listenData(uint8_t in) {\r
+    bool preamble = in == 0xaa || in == 0x55;\r
+\r
+    // Look for enough preamble bytes\r
+    if (preamble)\r
+      {\r
+       count++;\r
+       if (count > CC1K_ValidPrecursor)\r
+         enterSyncState();\r
+      }\r
+    else\r
+      count = 0;\r
+\r
+    signal ByteRadio.idleByte(preamble);\r
+  }\r
+\r
+  void syncData(uint8_t in) {\r
+    // draw in the preamble bytes and look for a sync byte\r
+    // save the data in a short with last byte received as msbyte\r
+    //    and current byte received as the lsbyte.\r
+    // use a bit shift compare to find the byte boundary for the sync byte\r
+    // retain the shift value and use it to collect all of the packet data\r
+    // check for data inversion, and restore proper polarity \r
+    // XXX-PB: Don't do this.\r
+\r
+    if (in == 0xaa || in == 0x55)\r
+      // It is actually possible to have the LAST BIT of the incoming\r
+      // data be part of the Sync Byte.  SO, we need to store that\r
+      // However, the next byte should definitely not have this pattern.\r
+      // XXX-PB: Do we need to check for excessive preamble?\r
+      rxShiftBuf = in << 8;\r
+    else if (count++ == 0)\r
+      rxShiftBuf |= in;\r
+    else if (count <= 6)\r
+      {\r
+       // TODO: Modify to be tolerant of bad bits in the preamble...\r
+       uint16_t tmp;\r
+       uint8_t i;\r
+\r
+       // bit shift the data in with previous sample to find sync\r
+       tmp = rxShiftBuf;\r
+       rxShiftBuf = rxShiftBuf << 8 | in;\r
+\r
+       for(i = 0; i < 8; i++)\r
+         {\r
+           tmp <<= 1;\r
+           if (in & 0x80)\r
+             tmp  |=  0x1;\r
+           in <<= 1;\r
+           // check for sync bytes\r
+           if (tmp == SYNC_WORD)\r
+             {\r
+               enterRxState();\r
+               signal ByteRadio.rx();\r
+               f.rxBitOffset = 7 - i;\r
+               signal RadioTimeStamping.receivedSFD(0);\r
+               call RssiRx.read();\r
+             }\r
+         }\r
+      }\r
+    else // We didn't find it after a reasonable number of tries, so....\r
+      enterListenState();\r
+  }\r
+  \r
+  async event void RssiRx.readDone(error_t result, uint16_t data) {\r
+    cc1000_metadata_t *rxMetadata = getMetadata(rxBufPtr);\r
+\r
+    if (result != SUCCESS)\r
+      rxMetadata->strength_or_preamble = 0;\r
+    else\r
+      rxMetadata->strength_or_preamble = data;\r
+  }\r
+\r
+  void rxData(uint8_t in) {\r
+    uint8_t nextByte;\r
+    cc1000_header_t *rxHeader = getHeader(rxBufPtr);\r
+    uint8_t rxLength = rxHeader->length;\r
+\r
+    // Reject invalid length packets\r
+    if (rxLength > TOSH_DATA_LENGTH)\r
+      {\r
+       // The packet's screwed up, so just dump it\r
+       enterListenState();\r
+       signal ByteRadio.rxDone();\r
+       return;\r
+      }\r
+\r
+    rxShiftBuf = rxShiftBuf << 8 | in;\r
+    nextByte = rxShiftBuf >> f.rxBitOffset;\r
+    ((uint8_t *)rxBufPtr)[count++] = nextByte;\r
+\r
+    // Adjust rxLength to correspond to the corresponding offset in message_t\r
+    rxLength += offsetof(message_t, data);\r
+    if (count <= rxLength)\r
+      runningCrc = crcByte(runningCrc, nextByte);\r
+\r
+    // Jump to CRC when we reach the end of data\r
+    if (count == rxLength) {\r
+      count = offsetof(message_t, footer) + offsetof(cc1000_footer_t, crc);\r
+    }\r
+\r
+    if (count == (offsetof(message_t, footer) + sizeof(cc1000_footer_t)))\r
+      packetReceived();\r
+  }\r
+\r
+  void packetReceived() {\r
+    cc1000_footer_t *rxFooter = getFooter(rxBufPtr);\r
+    cc1000_header_t *rxHeader = getHeader(rxBufPtr);\r
+    // Packet filtering based on bad CRC's is done at higher layers.\r
+    // So sayeth the TOS weenies.\r
+    rxFooter->crc = (rxFooter->crc == runningCrc);\r
+\r
+    if (f.ack &&\r
+       rxFooter->crc &&\r
+       rxHeader->dest == call amAddress())\r
+      {\r
+       enterAckState();\r
+       call CC1000Control.txMode();\r
+       call HplCC1000Spi.txMode();\r
+       call HplCC1000Spi.writeByte(0xaa);\r
+      }\r
+    else\r
+      packetReceiveDone();\r
+  }\r
+\r
+  void ackData(uint8_t in) {\r
+    if (++count >= ACK_LENGTH)\r
+      { \r
+       call CC1000Control.rxMode();\r
+       call HplCC1000Spi.rxMode();\r
+       packetReceiveDone();\r
+      }\r
+    else if (count >= ACK_LENGTH - sizeof ackCode)\r
+      call HplCC1000Spi.writeByte(read_uint8_t(&ackCode[count + sizeof ackCode - ACK_LENGTH]));\r
+  }\r
+\r
+  task void signalPacketReceived() {\r
+    message_t *pBuf;\r
+    cc1000_header_t *pHeader;\r
+    atomic\r
+      {\r
+       if (radioState != RECEIVED_STATE)\r
+         return;\r
+\r
+       pBuf = rxBufPtr;\r
+      }\r
+    pHeader = getHeader(pBuf);\r
+    pBuf = signal Receive.receive(pBuf, pBuf->data, pHeader->length);\r
+    atomic\r
+      {\r
+       if (pBuf) \r
+         rxBufPtr = pBuf;\r
+       if (radioState == RECEIVED_STATE) // receiver might've done something\r
+         enterListenState();\r
+       signal ByteRadio.rxDone();\r
+      }\r
+  }\r
+\r
+  void packetReceiveDone() {\r
+    post signalPacketReceived();\r
+    enterReceivedState();\r
+  }\r
+\r
+  async event void HplCC1000Spi.dataReady(uint8_t data) {\r
+    if (f.invert)\r
+      data = ~data;\r
+\r
+    switch (radioState)\r
+      {\r
+      default: break;\r
+      case TXPREAMBLE_STATE: txPreamble(); break;\r
+      case TXSYNC_STATE: txSync(); break;\r
+      case TXDATA_STATE: txData(); break;\r
+      case TXCRC_STATE: txCrc(); break;\r
+      case TXFLUSH_STATE: txFlush(); break;\r
+      case TXWAITFORACK_STATE: txWaitForAck(); break;\r
+      case TXREADACK_STATE: txReadAck(data); break;\r
+      case TXDONE_STATE: txDone(); break;\r
+\r
+      case LISTEN_STATE: listenData(data); break;\r
+      case SYNC_STATE: syncData(data); break;\r
+      case RX_STATE: rxData(data); break;\r
+      case SENDING_ACK: ackData(data); break;\r
+      }\r
+  }\r
+\r
+  /* Interaction with rest of stack */\r
+  /*--------------------------------*/\r
+\r
+  async command void ByteRadio.setPreambleLength(uint16_t bytes) {\r
+    atomic preambleLength = bytes;\r
+  }\r
+\r
+  async command uint16_t ByteRadio.getPreambleLength() {\r
+    atomic return preambleLength;\r
+  }\r
+\r
+  async command message_t *ByteRadio.getTxMessage() {\r
+    return txBufPtr;\r
+  }\r
+\r
+  async command bool ByteRadio.syncing() {\r
+    return radioState == SYNC_STATE;\r
+  }\r
+\r
+  /* Abstract packet layout */\r
+\r
+  command void Packet.clear(message_t *msg) {\r
+    memset(msg, 0, sizeof(message_t));\r
+  }\r
+\r
+  command uint8_t Packet.payloadLength(message_t *msg) {\r
+    cc1000_header_t *header = getHeader(msg);\r
+    return header->length;\r
+  }\r
\r
+  command void Packet.setPayloadLength(message_t *msg, uint8_t len) {\r
+    getHeader(msg)->length  = len;\r
+  }\r
+  \r
+  command uint8_t Packet.maxPayloadLength() {\r
+    return TOSH_DATA_LENGTH;\r
+  }\r
+\r
+  command void* Packet.getPayload(message_t *msg, uint8_t *len) {\r
+    if (len != NULL) {\r
+      cc1000_header_t *header = getHeader(msg);\r
+\r
+      *len = header->length;\r
+    }\r
+    return (void*)msg->data;\r
+  }\r
+\r
+  async command error_t PacketAcknowledgements.requestAck(message_t *msg) {\r
+    return SUCCESS;            /* We always ack. */\r
+  }\r
+\r
+  async command error_t PacketAcknowledgements.noAck(message_t *msg) {\r
+    return FAIL;               /* We always ack */\r
+  }\r
+\r
+  command void* Receive.getPayload(message_t *m, uint8_t *len) {\r
+    return call Packet.getPayload(m, len);\r
+  }\r
+\r
+  command uint8_t Receive.payloadLength(message_t *m) {\r
+    return call Packet.payloadLength(m);\r
+  }\r
+\r
+  command uint8_t Send.maxPayloadLength() {\r
+    return call Packet.maxPayloadLength();\r
+  }\r
+\r
+  command void* Send.getPayload(message_t *m) {\r
+    return call Packet.getPayload(m, NULL);\r
+  }\r
+\r
+  async command bool PacketAcknowledgements.wasAcked(message_t *msg) {\r
+    return getMetadata(msg)->ack;\r
+  }\r
+  // Default events for radio send/receive coordinators do nothing.\r
+  // Be very careful using these, or you'll break the stack.\r
+  default async event void RadioTimeStamping.transmittedSFD(uint16_t time, message_t *msgBuff) { }\r
+  default async event void RadioTimeStamping.receivedSFD(uint16_t time) { }\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CC1000Squelch.nc b/tos/chips/cc1000_lpl/CC1000Squelch.nc
new file mode 100644 (file)
index 0000000..97e4838
--- /dev/null
@@ -0,0 +1,54 @@
+/* $Id$\r
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2002-2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+\r
+/**\r
+ * CC1000 internal noise floor (aka squelch value) interface\r
+ * @author David Gay\r
+ */\r
+interface CC1000Squelch\r
+{\r
+  /**\r
+   * Adjust noise floor based on new noise measurement\r
+   * @param data noise measurement\r
+   */\r
+  command void adjust(uint16_t data);\r
+\r
+  /**\r
+   * Return current estimated noise floor\r
+   * @return Noise floor value\r
+   */\r
+  async command uint16_t get();\r
+\r
+  /**\r
+   * Check if noise floor estimate is considered stable (typically after\r
+   * some number of measurements)\r
+   * @return TRUE if noise floor estimate considered stable, FALSE otherwise\r
+   */\r
+  command bool settled();\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CC1000SquelchP.nc b/tos/chips/cc1000_lpl/CC1000SquelchP.nc
new file mode 100644 (file)
index 0000000..8b8ec02
--- /dev/null
@@ -0,0 +1,98 @@
+/* $Id$\r
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2002-2005 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+#include "CC1000Const.h"\r
+\r
+/**\r
+ * Clear threshold estimation based on RSSI measurements.\r
+ *\r
+ * @author Philip Buonadonna\r
+ * @author Jaein Jeong\r
+ * @author Joe Polastre\r
+ * @author David Gay\r
+ */\r
+  \r
+module CC1000SquelchP\r
+{\r
+  provides {\r
+    interface Init;\r
+    interface CC1000Squelch;\r
+  }\r
+}\r
+implementation\r
+{\r
+  uint16_t clearThreshold = CC1K_SquelchInit;\r
+  uint16_t squelchTable[CC1K_SquelchTableSize];\r
+  uint8_t squelchIndex, squelchCount;\r
+\r
+  command error_t Init.init() {\r
+    uint8_t i;\r
+\r
+    for (i = 0; i < CC1K_SquelchTableSize; i++)\r
+      squelchTable[i] = CC1K_SquelchInit;\r
+\r
+    return SUCCESS;\r
+  }\r
+\r
+  command void CC1000Squelch.adjust(uint16_t data) {\r
+    uint16_t squelchTab[CC1K_SquelchTableSize];\r
+    uint8_t i, j, min; \r
+    uint32_t newThreshold;\r
+\r
+    squelchTable[squelchIndex++] = data;\r
+    if (squelchIndex >= CC1K_SquelchTableSize)\r
+      squelchIndex = 0;\r
+    if (squelchCount <= CC1K_SquelchCount)\r
+      squelchCount++;  \r
+\r
+    // Find 3rd highest (aka lowest signal strength) value\r
+    memcpy(squelchTab, squelchTable, sizeof squelchTable);\r
+    for (j = 0; ; j++)\r
+      {\r
+       min = 0;\r
+       for (i = 1; i < CC1K_SquelchTableSize; i++)\r
+         if (squelchTab[i] > squelchTab[min])\r
+           min = i;\r
+       if (j == 3)\r
+         break;\r
+       squelchTab[min] = 0;\r
+      }\r
+\r
+    newThreshold = ((uint32_t)clearThreshold << 5) +\r
+      ((uint32_t)squelchTab[min] << 1);\r
+    atomic clearThreshold = newThreshold / 34;\r
+  }\r
+\r
+  async command uint16_t CC1000Squelch.get() {\r
+    return clearThreshold;\r
+  }\r
+\r
+  command bool CC1000Squelch.settled() {\r
+    return squelchCount > CC1K_SquelchCount;\r
+  }\r
+}\r
diff --git a/tos/chips/cc1000_lpl/CsmaControl.nc b/tos/chips/cc1000_lpl/CsmaControl.nc
new file mode 100644 (file)
index 0000000..75c7134
--- /dev/null
@@ -0,0 +1,41 @@
+/*                                                                     tab:4\r
+ * "Copyright (c) 2000-2005 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ */\r
+/**\r
+ * Interface for activating/deactivating congestion control.\r
+ *\r
+ * @author Philip Levis\r
+ * @author Joe Polastre\r
+ * @date   August 31 2005\r
+ */\r
+interface CsmaControl {\r
+  /**\r
+   * Enable congestion control.\r
+   * @return SUCCESS if congestion control enabled, FAIL otherwise.\r
+   */\r
+  async command error_t enableCca();\r
+\r
+  /**\r
+   * Disable congestion control.\r
+   * @return SUCCESS if congestion control disabled, FAIL otherwise.\r
+   */\r
+  async command error_t disableCca();\r
+}\r
diff --git a/tos/chips/cc1000_lpl/HplCC1000.nc b/tos/chips/cc1000_lpl/HplCC1000.nc
new file mode 100644 (file)
index 0000000..390d723
--- /dev/null
@@ -0,0 +1,73 @@
+// $Id$\r
+\r
+/*                                                                     tab:4\r
+ * "Copyright (c) 2000-2003 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2002-2003 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+/*\r
+ * Authors:            Jason Hill, David Gay, Philip Levis\r
+ * Date last modified:  6/25/02\r
+ *\r
+ *\r
+ */\r
+\r
+/**\r
+ * Low-level CC1000 radio-access operations that must be provided by a\r
+ * platform wishing to use this CC1000 implementation.\r
+ *\r
+ * @author Jason Hill\r
+ * @author David Gay\r
+ * @author Philip Levis\r
+ */\r
+\r
+\r
+interface HplCC1000 {\r
+  /**\r
+   * Initialize CC1K pins\r
+   */\r
+  command void init();\r
+\r
+  /**\r
+   * Write a value to a CC1000 register.\r
+   * @param addr Which CC1000 register\r
+   * @param data Value to write\r
+   */\r
+  async command void write(uint8_t addr, uint8_t data);\r
+\r
+  /**\r
+   * Read a value from a CC1000 register.\r
+   * @param addr Which CC1000 register\r
+   * @return Value of register\r
+   */\r
+  async command uint8_t read(uint8_t addr);\r
+\r
+  /**\r
+   * Read the state of the CHP_OUT pin\r
+   * @return State of CHP_OUT as a boolean (TRUE for high)\r
+   */\r
+  async command bool getLOCK();\r
+}\r
diff --git a/tos/chips/cc1000_lpl/HplCC1000Spi.nc b/tos/chips/cc1000_lpl/HplCC1000Spi.nc
new file mode 100644 (file)
index 0000000..42abf37
--- /dev/null
@@ -0,0 +1,93 @@
+// $Id$\r
+\r
+/*                                                                     tab:4\r
+ * "Copyright (c) 2000-2003 The Regents of the University  of California.  \r
+ * All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and its\r
+ * documentation for any purpose, without fee, and without written agreement is\r
+ * hereby granted, provided that the above copyright notice, the following\r
+ * two paragraphs and the author appear in all copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\r
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF\r
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * \r
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\r
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS\r
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO\r
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ * Copyright (c) 2002-2003 Intel Corporation\r
+ * All rights reserved.\r
+ *\r
+ * This file is distributed under the terms in the attached INTEL-LICENSE     \r
+ * file. If you do not find these files, copies can be found by writing to\r
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, \r
+ * 94704.  Attention:  Intel License Inquiry.\r
+ */\r
+/**\r
+ * Interface to the CC1000 chip's serial bus. This isn't really an SPI,\r
+ * but the mica2 interface was done using the Atmega128 SPI hardware. Hence\r
+ * the name.\r
+ *\r
+ * @author Jaein Jeong\r
+ * @author Philip buonadonna\r
+ */\r
+interface HplCC1000Spi\r
+{\r
+  /**\r
+   * Write a byte to the CC1000 bus.\r
+   * @param data Byte to write.\r
+   */\r
+  async command void writeByte(uint8_t data);\r
+\r
+  /**\r
+   * Is write buffer busy with the last transmission?\r
+   * @return TRUE if the buffer is busy, FALSE otherwise.\r
+   */\r
+  async command bool isBufBusy();\r
+\r
+  /**\r
+   * Get the last byte received from the CC1000 bus.\r
+   * @return Last byte received.\r
+   */\r
+  async command uint8_t readByte();\r
+\r
+  /**\r
+   * Enable dataReady events on every byte sent or received from the CC1000\r
+   * bus. After this is called, dataReady events will be signaled every\r
+   * 8 CC1000 data clocks.\r
+   */\r
+  async command void enableIntr();\r
+\r
+  /**\r
+   * Disable CC1000 bus interrupts.\r
+   */\r
+  async command void disableIntr();\r
+\r
+  /**\r
+   * Initialise the interface to the CC1000 bus.\r
+   */\r
+  async command void initSlave();\r
+\r
+  /**\r
+   * Switch the interface to the CC1000 bus "transmit" mode.\r
+   */\r
+  async command void txMode();\r
+\r
+  /**\r
+   * Switch the interface to the CC1000 bus to "receive" mode.\r
+   */\r
+  async command void rxMode();\r
+\r
+  /**\r
+   * If enableIntr() is called, this event will be signaled every 8 CC1000\r
+   * data clocks. \r
+   * @param data In "receive" mode, the last value received from the CC1000 \r
+   *   bus.\r
+   */\r
+  async event void dataReady(uint8_t data);\r
+}\r
diff --git a/tos/chips/cc1000_lpl/LowPowerListening.nc b/tos/chips/cc1000_lpl/LowPowerListening.nc
new file mode 100644 (file)
index 0000000..8bd970f
--- /dev/null
@@ -0,0 +1,129 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
\r
+/**\r
+ * Low Power Listening interface\r
+ *\r
+ * @author David Moss\r
+ * @author Jonathan Hui\r
+ */\r
\r
+interface LowPowerListening {\r
+\r
+  /**\r
+   * Set this this node's radio sleep interval, in milliseconds.\r
+   * Once every interval, the node will sleep and perform an Rx check \r
+   * on the radio.  Setting the sleep interval to 0 will keep the radio\r
+   * always on.\r
+   *\r
+   * This is the equivalent of setting the local duty cycle rate.\r
+   *\r
+   * @param sleepIntervalMs the length of this node's Rx check interval, in [ms]\r
+   */\r
+  command void setLocalSleepInterval(uint16_t sleepIntervalMs);\r
+  \r
+  /**\r
+   * @return the local node's sleep interval, in [ms]\r
+   */\r
+  command uint16_t getLocalSleepInterval();\r
+  \r
+  /**\r
+   * Set this node's radio duty cycle rate, in units of [percentage*100].\r
+   * For example, to get a 0.05% duty cycle,\r
+   * <code>\r
+   *   call LowPowerListening.setDutyCycle(5);  // or equivalently...\r
+   *   call LowPowerListening.setDutyCycle(00005);  // for better readability?\r
+   * </code>\r
+   *\r
+   * For a 100% duty cycle (always on),\r
+   * <code>\r
+   *   call LowPowerListening.setDutyCycle(10000);\r
+   * </code>\r
+   *\r
+   * This is the equivalent of setting the local sleep interval explicitly.\r
+   * \r
+   * @param dutyCycle The duty cycle percentage, in units of [percentage*100]\r
+   */\r
+  command void setLocalDutyCycle(uint16_t dutyCycle);\r
+  \r
+  /**\r
+   * @return this node's radio duty cycle rate, in units of [percentage*100]\r
+   */\r
+  command uint16_t getLocalDutyCycle();\r
+  \r
+  \r
+  /**\r
+   * Configure this outgoing message so it can be transmitted to a neighbor mote\r
+   * with the specified Rx sleep interval.\r
+   * @param msg Pointer to the message that will be sent\r
+   * @param sleepInterval The receiving node's sleep interval, in [ms]\r
+   */\r
+  command void setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs);\r
+  \r
+  /**\r
+   * @return the destination node's sleep interval configured in this message\r
+   */\r
+  command uint16_t getRxSleepInterval(message_t *msg);\r
+  \r
+  /**\r
+   * Configure this outgoing message so it can be transmitted to a neighbor mote\r
+   * with the specified Rx duty cycle rate.\r
+   * Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25.\r
+   * \r
+   * @param msg Pointer to the message that will be sent\r
+   * @param dutyCycle The duty cycle of the receiving mote, in units of \r
+   *     [percentage*100]\r
+   */\r
+  command void setRxDutyCycle(message_t *msg, uint16_t dutyCycle);\r
+  \r
+  /**\r
+   * @return the destination node's duty cycle configured in this message\r
+   *     in units of [percentage*100]\r
+   */\r
+  command uint16_t getRxDutyCycle(message_t *msg);\r
+  \r
+  /**\r
+   * Convert a duty cycle, in units of [percentage*100], to\r
+   * the sleep interval of the mote in milliseconds\r
+   * @param dutyCycle The duty cycle in units of [percentage*100]\r
+   * @return The equivalent sleep interval, in units of [ms]\r
+   */\r
+  command uint16_t dutyCycleToSleepInterval(uint16_t dutyCycle);\r
+  \r
+  /**\r
+   * Convert a sleep interval, in units of [ms], to a duty cycle\r
+   * in units of [percentage*100]\r
+   * @param sleepInterval The sleep interval in units of [ms]\r
+   * @return The duty cycle in units of [percentage*100]\r
+   */\r
+  command uint16_t sleepIntervalToDutyCycle(uint16_t sleepInterval);\r
+  \r
+}\r
diff --git a/tos/chips/cc2420_lpl/AlarmMultiplexC.nc b/tos/chips/cc2420_lpl/AlarmMultiplexC.nc
new file mode 100644 (file)
index 0000000..38a54b2
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * A component that multiplexes the use of an alarm. The assumption is\r
+ * that its use is mutually exclusive and users check whether the\r
+ * events are for them.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#include <Timer.h>\r
+\r
+configuration AlarmMultiplexC {\r
+\r
+  provides interface Init;\r
+  provides interface Alarm<T32khz,uint32_t> as Alarm32khz32;\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  components new HplCC2420AlarmC() as Alarm;\r
+\r
+  Init = Alarm;\r
+  Alarm32khz32 = Alarm;\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420.h b/tos/chips/cc2420_lpl/CC2420.h
new file mode 100644 (file)
index 0000000..6b0847a
--- /dev/null
@@ -0,0 +1,321 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#ifndef __CC2420_H__\r
+#define __CC2420_H__\r
+\r
+//#include "message.h"\r
+\r
+typedef uint8_t cc2420_status_t;\r
+\r
+typedef nx_struct cc2420_header_t {\r
+  nxle_uint8_t length;\r
+  nxle_uint16_t fcf;\r
+  nxle_uint8_t dsn;\r
+  nxle_uint16_t destpan;\r
+  nxle_uint16_t dest;\r
+  nxle_uint16_t src;\r
+  nxle_uint8_t type;\r
+} cc2420_header_t;\r
+\r
+typedef nx_struct cc2420_footer_t {\r
+} cc2420_footer_t;\r
+\r
+typedef nx_struct cc2420_metadata_t {\r
+  nx_uint8_t tx_power;\r
+  nx_uint8_t rssi;\r
+  nx_uint8_t lqi;\r
+  nx_bool crc;\r
+  nx_bool ack;\r
+  nx_uint16_t time;\r
+  nx_uint16_t rxInterval;\r
+} cc2420_metadata_t;\r
+\r
+typedef nx_struct cc2420_packet_t {\r
+  cc2420_header_t packet;\r
+  nx_uint8_t data[];\r
+} cc2420_packet_t;\r
+\r
+#ifndef TOSH_DATA_LENGTH\r
+#define TOSH_DATA_LENGTH 28\r
+#endif\r
+\r
+#ifndef CC2420_DEF_CHANNEL\r
+#define CC2420_DEF_CHANNEL 26\r
+#endif\r
+\r
+#ifndef CC2420_DEF_RFPOWER\r
+#define CC2420_DEF_RFPOWER 31\r
+#endif\r
+\r
+enum {\r
+  // size of the header not including the length byte\r
+  MAC_HEADER_SIZE = sizeof( cc2420_header_t ) - 1,\r
+  // size of the footer (FCS field)\r
+  MAC_FOOTER_SIZE = sizeof( uint16_t ),\r
+  // MDU\r
+  MAC_PACKET_SIZE = MAC_HEADER_SIZE + TOSH_DATA_LENGTH + MAC_FOOTER_SIZE,\r
+};\r
+\r
+enum cc2420_enums {\r
+  CC2420_TIME_ACK_TURNAROUND = 7, // jiffies\r
+  CC2420_TIME_VREN = 20,          // jiffies\r
+  CC2420_TIME_SYMBOL = 2,         // 2 symbols / jiffy\r
+  CC2420_BACKOFF_PERIOD = ( 20 / CC2420_TIME_SYMBOL ), // symbols\r
+  CC2420_MIN_BACKOFF = ( 20 / CC2420_TIME_SYMBOL ),  // platform specific?\r
+  CC2420_ACK_WAIT_DELAY = 128,    // jiffies\r
+};\r
+\r
+enum cc2420_status_enums {\r
+  CC2420_STATUS_RSSI_VALID = 1 << 1,\r
+  CC2420_STATUS_LOCK = 1 << 2,\r
+  CC2420_STATUS_TX_ACTIVE = 1 << 3,\r
+  CC2420_STATUS_ENC_BUSY = 1 << 4,\r
+  CC2420_STATUS_TX_UNDERFLOW = 1 << 5,\r
+  CC2420_STATUS_XOSC16M_STABLE = 1 << 6,\r
+};\r
+\r
+enum cc2420_config_reg_enums {\r
+  CC2420_SNOP = 0x00,\r
+  CC2420_SXOSCON = 0x01,\r
+  CC2420_STXCAL = 0x02,\r
+  CC2420_SRXON = 0x03,\r
+  CC2420_STXON = 0x04,\r
+  CC2420_STXONCCA = 0x05,\r
+  CC2420_SRFOFF = 0x06,\r
+  CC2420_SXOSCOFF = 0x07,\r
+  CC2420_SFLUSHRX = 0x08,\r
+  CC2420_SFLUSHTX = 0x09,\r
+  CC2420_SACK = 0x0a,\r
+  CC2420_SACKPEND = 0x0b,\r
+  CC2420_SRXDEC = 0x0c,\r
+  CC2420_SRXENC = 0x0d,\r
+  CC2420_SAES = 0x0e,\r
+  CC2420_MAIN = 0x10,\r
+  CC2420_MDMCTRL0 = 0x11,\r
+  CC2420_MDMCTRL1 = 0x12,\r
+  CC2420_RSSI = 0x13,\r
+  CC2420_SYNCWORD = 0x14,\r
+  CC2420_TXCTRL = 0x15,\r
+  CC2420_RXCTRL0 = 0x16,\r
+  CC2420_RXCTRL1 = 0x17,\r
+  CC2420_FSCTRL = 0x18,\r
+  CC2420_SECCTRL0 = 0x19,\r
+  CC2420_SECCTRL1 = 0x1a,\r
+  CC2420_BATTMON = 0x1b,\r
+  CC2420_IOCFG0 = 0x1c,\r
+  CC2420_IOCFG1 = 0x1d,\r
+  CC2420_MANFIDL = 0x1e,\r
+  CC2420_MANFIDH = 0x1f,\r
+  CC2420_FSMTC = 0x20,\r
+  CC2420_MANAND = 0x21,\r
+  CC2420_MANOR = 0x22,\r
+  CC2420_AGCCTRL = 0x23,\r
+  CC2420_AGCTST0 = 0x24,\r
+  CC2420_AGCTST1 = 0x25,\r
+  CC2420_AGCTST2 = 0x26,\r
+  CC2420_FSTST0 = 0x27,\r
+  CC2420_FSTST1 = 0x28,\r
+  CC2420_FSTST2 = 0x29,\r
+  CC2420_FSTST3 = 0x2a,\r
+  CC2420_RXBPFTST = 0x2b,\r
+  CC2420_FMSTATE = 0x2c,\r
+  CC2420_ADCTST = 0x2d,\r
+  CC2420_DACTST = 0x2e,\r
+  CC2420_TOPTST = 0x2f,\r
+  CC2420_TXFIFO = 0x3e,\r
+  CC2420_RXFIFO = 0x3f,\r
+};\r
+\r
+enum cc2420_ram_addr_enums {\r
+  CC2420_RAM_TXFIFO = 0x000,\r
+  CC2420_RAM_RXFIFO = 0x080,\r
+  CC2420_RAM_KEY0 = 0x100,\r
+  CC2420_RAM_RXNONCE = 0x110,\r
+  CC2420_RAM_SABUF = 0x120,\r
+  CC2420_RAM_KEY1 = 0x130,\r
+  CC2420_RAM_TXNONCE = 0x140,\r
+  CC2420_RAM_CBCSTATE = 0x150,\r
+  CC2420_RAM_IEEEADR = 0x160,\r
+  CC2420_RAM_PANID = 0x168,\r
+  CC2420_RAM_SHORTADR = 0x16a,\r
+};\r
+\r
+enum cc2420_nonce_enums {\r
+  CC2420_NONCE_BLOCK_COUNTER = 0,\r
+  CC2420_NONCE_KEY_SEQ_COUNTER = 2,\r
+  CC2420_NONCE_FRAME_COUNTER = 3,\r
+  CC2420_NONCE_SOURCE_ADDRESS = 7,\r
+  CC2420_NONCE_FLAGS = 15,\r
+};\r
+\r
+enum cc2420_main_enums {\r
+  CC2420_MAIN_RESETn = 15,\r
+  CC2420_MAIN_ENC_RESETn = 14,\r
+  CC2420_MAIN_DEMOD_RESETn = 13,\r
+  CC2420_MAIN_MOD_RESETn = 12,\r
+  CC2420_MAIN_FS_RESETn = 11,\r
+  CC2420_MAIN_XOSC16M_BYPASS = 0,\r
+};\r
+\r
+enum cc2420_mdmctrl0_enums {\r
+  CC2420_MDMCTRL0_RESERVED_FRAME_MODE = 13,\r
+  CC2420_MDMCTRL0_PAN_COORDINATOR = 12,\r
+  CC2420_MDMCTRL0_ADR_DECODE = 11,\r
+  CC2420_MDMCTRL0_CCA_HYST = 8,\r
+  CC2420_MDMCTRL0_CCA_MOD = 6,\r
+  CC2420_MDMCTRL0_AUTOCRC = 5,\r
+  CC2420_MDMCTRL0_AUTOACK = 4,\r
+  CC2420_MDMCTRL0_PREAMBLE_LENGTH = 0,\r
+};\r
+\r
+enum cc2420_mdmctrl1_enums {\r
+  CC2420_MDMCTRL1_CORR_THR = 6,\r
+  CC2420_MDMCTRL1_DEMOD_AVG_MODE = 5,\r
+  CC2420_MDMCTRL1_MODULATION_MODE = 4,\r
+  CC2420_MDMCTRL1_TX_MODE = 2,\r
+  CC2420_MDMCTRL1_RX_MODE = 0,\r
+};\r
+\r
+enum cc2420_rssi_enums {\r
+  CC2420_RSSI_CCA_THR = 8,\r
+  CC2420_RSSI_RSSI_VAL = 0,\r
+};\r
+\r
+enum cc2420_syncword_enums {\r
+  CC2420_SYNCWORD_SYNCWORD = 0,\r
+};\r
+\r
+enum cc2420_txctrl_enums {\r
+  CC2420_TXCTRL_TXMIXBUF_CUR = 14,\r
+  CC2420_TXCTRL_TX_TURNAROUND = 13,\r
+  CC2420_TXCTRL_TXMIX_CAP_ARRAY = 11,\r
+  CC2420_TXCTRL_TXMIX_CURRENT = 9,\r
+  CC2420_TXCTRL_PA_CURRENT = 6,\r
+  CC2420_TXCTRL_RESERVED = 5,\r
+  CC2420_TXCTRL_PA_LEVEL = 0,\r
+};\r
+\r
+enum cc2420_rxctrl0_enums {\r
+  CC2420_RXCTRL0_RXMIXBUF_CUR = 12,\r
+  CC2420_RXCTRL0_HIGH_LNA_GAIN = 10,\r
+  CC2420_RXCTRL0_MED_LNA_GAIN = 8,\r
+  CC2420_RXCTRL0_LOW_LNA_GAIN = 6,\r
+  CC2420_RXCTRL0_HIGH_LNA_CURRENT = 4,\r
+  CC2420_RXCTRL0_MED_LNA_CURRENT = 2,\r
+  CC2420_RXCTRL0_LOW_LNA_CURRENT = 0,\r
+};\r
+\r
+enum cc2420_rxctrl1_enums {\r
+  CC2420_RXCTRL1_RXBPF_LOCUR = 13,\r
+  CC2420_RXCTRL1_RXBPF_MIDCUR = 12,\r
+  CC2420_RXCTRL1_LOW_LOWGAIN = 11,\r
+  CC2420_RXCTRL1_MED_LOWGAIN = 10,\r
+  CC2420_RXCTRL1_HIGH_HGM = 9,\r
+  CC2420_RXCTRL1_MED_HGM = 8,\r
+  CC2420_RXCTRL1_LNA_CAP_ARRAY = 6,\r
+  CC2420_RXCTRL1_RXMIX_TAIL = 4,\r
+  CC2420_RXCTRL1_RXMIX_VCM = 2,\r
+  CC2420_RXCTRL1_RXMIX_CURRENT = 0,\r
+};\r
+\r
+enum cc2420_rsctrl_enums {\r
+  CC2420_FSCTRL_LOCK_THR = 14,\r
+  CC2420_FSCTRL_CAL_DONE = 13,\r
+  CC2420_FSCTRL_CAL_RUNNING = 12,\r
+  CC2420_FSCTRL_LOCK_LENGTH = 11,\r
+  CC2420_FSCTRL_LOCK_STATUS = 10,\r
+  CC2420_FSCTRL_FREQ = 0,\r
+};\r
+\r
+enum cc2420_secctrl0_enums {\r
+  CC2420_SECCTRL0_RXFIFO_PROTECTION = 9,\r
+  CC2420_SECCTRL0_SEC_CBC_HEAD = 8,\r
+  CC2420_SECCTRL0_SEC_SAKEYSEL = 7,\r
+  CC2420_SECCTRL0_SEC_TXKEYSEL = 6,\r
+  CC2420_SECCTRL0_SEC_RXKEYSEL = 5,\r
+  CC2420_SECCTRL0_SEC_M = 2,\r
+  CC2420_SECCTRL0_SEC_MODE = 0,\r
+};\r
+\r
+enum cc2420_secctrl1_enums {\r
+  CC2420_SECCTRL1_SEC_TXL = 8,\r
+  CC2420_SECCTRL1_SEC_RXL = 0,\r
+};\r
+\r
+enum cc2420_battmon_enums {\r
+  CC2420_BATTMON_BATT_OK = 6,\r
+  CC2420_BATTMON_BATTMON_EN = 5,\r
+  CC2420_BATTMON_BATTMON_VOLTAGE = 0,\r
+};\r
+\r
+enum cc2420_iocfg0_enums {\r
+  CC2420_IOCFG0_BCN_ACCEPT = 11,\r
+  CC2420_IOCFG0_FIFO_POLARITY = 10,\r
+  CC2420_IOCFG0_FIFOP_POLARITY = 9,\r
+  CC2420_IOCFG0_SFD_POLARITY = 8,\r
+  CC2420_IOCFG0_CCA_POLARITY = 7,\r
+  CC2420_IOCFG0_FIFOP_THR = 0,\r
+};\r
+\r
+enum cc2420_iocfg1_enums {\r
+  CC2420_IOCFG1_HSSD_SRC = 10,\r
+  CC2420_IOCFG1_SFDMUX = 5,\r
+  CC2420_IOCFG1_CCAMUX = 0,\r
+};\r
+\r
+enum cc2420_manfidl_enums {\r
+  CC2420_MANFIDL_PARTNUM = 12,\r
+  CC2420_MANFIDL_MANFID = 0,\r
+};\r
+\r
+enum cc2420_manfidh_enums {\r
+  CC2420_MANFIDH_VERSION = 12,\r
+  CC2420_MANFIDH_PARTNUM = 0,\r
+};\r
+\r
+enum cc2420_fsmtc_enums {\r
+  CC2420_FSMTC_TC_RXCHAIN2RX = 13,\r
+  CC2420_FSMTC_TC_SWITCH2TX = 10,\r
+  CC2420_FSMTC_TC_PAON2TX = 6,\r
+  CC2420_FSMTC_TC_TXEND2SWITCH = 3,\r
+  CC2420_FSMTC_TC_TXEND2PAOFF = 0,\r
+};\r
+\r
+enum cc2420_sfdmux_enums {\r
+  CC2420_SFDMUX_SFD = 0,\r
+  CC2420_SFDMUX_XOSC16M_STABLE = 24,\r
+};\r
+\r
+#endif\r
diff --git a/tos/chips/cc2420_lpl/CC2420ActiveMessageC.nc b/tos/chips/cc2420_lpl/CC2420ActiveMessageC.nc
new file mode 100644 (file)
index 0000000..ec264f1
--- /dev/null
@@ -0,0 +1,88 @@
+/*                                                                     tab:4\r
+ * "Copyright (c) 2005 Stanford University. All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and\r
+ * its documentation for any purpose, without fee, and without written\r
+ * agreement is hereby granted, provided that the above copyright\r
+ * notice, the following two paragraphs and the author appear in all\r
+ * copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\r
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN\r
+ * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ * \r
+ * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE\r
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY\r
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,\r
+ * ENHANCEMENTS, OR MODIFICATIONS."\r
+ */\r
+\r
+/**\r
+ * The Active Message layer for the CC2420 radio. This configuration\r
+ * just layers the AM dispatch (CC2420ActiveMessageM) on top of the\r
+ * underlying CC2420 radio packet (CC2420CsmaRadioC), which is\r
+ * inherently an AM packet (acknowledgements based on AM destination\r
+ * addr and group). Note that snooping may not work, due to CC2420\r
+ * early packet rejection if acknowledgements are enabled.\r
+ *\r
+ * @author Philip Levis\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#include "CC2420.h"\r
+\r
+configuration CC2420ActiveMessageC {\r
+  provides {\r
+    interface SplitControl;\r
+    interface AMSend[am_id_t id];\r
+    interface Receive[am_id_t id];\r
+    interface Receive as Snoop[am_id_t id];\r
+    interface AMPacket;\r
+    interface Packet;\r
+    interface CC2420Packet;\r
+    interface PacketAcknowledgements;\r
+    interface CsmaBackoff[am_id_t amId];\r
+    interface LowPowerListening;\r
+  }\r
+}\r
+implementation {\r
+\r
+  components CC2420ActiveMessageP as AM;\r
+  components CC2420CsmaC as Radio;\r
+  components ActiveMessageAddressC as Address;\r
+  \r
+  CsmaBackoff = Radio;\r
+  Packet       = AM;\r
+  AMSend   = AM;\r
+  Receive  = AM.Receive;\r
+  Snoop    = AM.Snoop;\r
+  AMPacket = AM;\r
+  \r
+#ifdef LOW_POWER_LISTENING\r
+  components CC2420LowPowerListeningC as Lpl;\r
+  LowPowerListening = Lpl;\r
+  AM.SubSend -> Lpl.Send;\r
+  AM.SubReceive -> Lpl.Receive;\r
+  SplitControl = Lpl;\r
+  \r
+#else\r
+  components CC2420LplDummyP;\r
+  LowPowerListening = CC2420LplDummyP;\r
+  AM.SubSend    -> Radio.Send;\r
+  AM.SubReceive -> Radio.Receive;\r
+  SplitControl = Radio;\r
+#endif\r
+\r
+  AM.amAddress -> Address;\r
+  Radio.AMPacket -> AM;\r
+\r
+  components CC2420PacketC;\r
+  CC2420Packet = CC2420PacketC;\r
+  PacketAcknowledgements = CC2420PacketC;\r
+\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420ActiveMessageP.nc b/tos/chips/cc2420_lpl/CC2420ActiveMessageP.nc
new file mode 100644 (file)
index 0000000..7cae449
--- /dev/null
@@ -0,0 +1,188 @@
+/*                                                                     tab:4\r
+ * "Copyright (c) 2005 Stanford University. All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and\r
+ * its documentation for any purpose, without fee, and without written\r
+ * agreement is hereby granted, provided that the above copyright\r
+ * notice, the following two paragraphs and the author appear in all\r
+ * copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\r
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN\r
+ * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ * \r
+ * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE\r
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY\r
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,\r
+ * ENHANCEMENTS, OR MODIFICATIONS."\r
+ */\r
+\r
+\r
+/**\r
+ * Active message implementation on top of the CC2420 radio. This\r
+ * implementation uses the 16-bit addressing mode of 802.15.4: the\r
+ * only additional byte it adds is the AM id byte, as the first byte\r
+ * of the data payload.\r
+ *\r
+ * @author Philip Levis\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+module CC2420ActiveMessageP {\r
+  provides {\r
+    interface AMSend[am_id_t id];\r
+    interface Receive[am_id_t id];\r
+    interface Receive as Snoop[am_id_t id];\r
+    interface AMPacket;\r
+    interface Packet;\r
+  }\r
+  uses {\r
+    interface Send as SubSend;\r
+    interface Receive as SubReceive;\r
+    command am_addr_t amAddress();\r
+  }\r
+}\r
+implementation {\r
+\r
+  enum {\r
+    CC2420_SIZE = MAC_HEADER_SIZE + MAC_FOOTER_SIZE,\r
+  };\r
+  \r
+  cc2420_header_t* getHeader( message_t* msg ) {\r
+    return (cc2420_header_t*)( msg->data - sizeof(cc2420_header_t) );\r
+  }\r
+  \r
+  command error_t AMSend.send[am_id_t id](am_addr_t addr,\r
+                                         message_t* msg,\r
+                                         uint8_t len) {\r
+    cc2420_header_t* header = getHeader( msg );\r
+    header->type = id;\r
+    header->dest = addr;\r
+    header->destpan = TOS_AM_GROUP;\r
+\r
+    return call SubSend.send( msg, len + CC2420_SIZE );\r
+  }\r
+\r
+  command error_t AMSend.cancel[am_id_t id](message_t* msg) {\r
+    return call SubSend.cancel(msg);\r
+  }\r
+\r
+  command uint8_t AMSend.maxPayloadLength[am_id_t id]() {\r
+    return call Packet.maxPayloadLength();\r
+  }\r
+\r
+  command void* AMSend.getPayload[am_id_t id](message_t* m) {\r
+    return call Packet.getPayload(m, NULL);\r
+  }\r
+\r
+  command void* Receive.getPayload[am_id_t id](message_t* m, uint8_t* len) {\r
+    return call Packet.getPayload(m, len);\r
+  }\r
+\r
+  command uint8_t Receive.payloadLength[am_id_t id](message_t* m) {\r
+    return call Packet.payloadLength(m);\r
+  }\r
+  \r
+  command void* Snoop.getPayload[am_id_t id](message_t* m, uint8_t* len) {\r
+    return call Packet.getPayload(m, len);\r
+  }\r
+\r
+  command uint8_t Snoop.payloadLength[am_id_t id](message_t* m) {\r
+    return call Packet.payloadLength(m);\r
+  }\r
+  \r
+  event void SubSend.sendDone(message_t* msg, error_t result) {\r
+    signal AMSend.sendDone[call AMPacket.type(msg)](msg, result);\r
+  }\r
+\r
+  /* Receiving a packet */\r
+\r
+  event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) {\r
+    if (call AMPacket.isForMe(msg)) {\r
+      return signal Receive.receive[call AMPacket.type(msg)](msg, payload, len - CC2420_SIZE);\r
+    }\r
+    else {\r
+      return signal Snoop.receive[call AMPacket.type(msg)](msg, payload, len - CC2420_SIZE);\r
+    }\r
+  }\r
+  \r
+  command am_addr_t AMPacket.address() {\r
+    return call amAddress();\r
+  }\r
\r
+  command am_addr_t AMPacket.destination(message_t* amsg) {\r
+    cc2420_header_t* header = getHeader(amsg);\r
+    return header->dest;\r
+  }\r
\r
+  command am_addr_t AMPacket.source(message_t* amsg) {\r
+    cc2420_header_t* header = getHeader(amsg);\r
+    return header->src;\r
+  }\r
+\r
+  command void AMPacket.setDestination(message_t* amsg, am_addr_t addr) {\r
+    cc2420_header_t* header = getHeader(amsg);\r
+    header->dest = addr;\r
+  }\r
+\r
+  command void AMPacket.setSource(message_t* amsg, am_addr_t addr) {\r
+    cc2420_header_t* header = getHeader(amsg);\r
+    header->src = addr;\r
+  }\r
+\r
+  command bool AMPacket.isForMe(message_t* amsg) {\r
+    return (call AMPacket.destination(amsg) == call AMPacket.address() ||\r
+           call AMPacket.destination(amsg) == AM_BROADCAST_ADDR);\r
+  }\r
+\r
+  command am_id_t AMPacket.type(message_t* amsg) {\r
+    cc2420_header_t* header = getHeader(amsg);\r
+    return header->type;\r
+  }\r
+\r
+  command void AMPacket.setType(message_t* amsg, am_id_t type) {\r
+    cc2420_header_t* header = getHeader(amsg);\r
+    header->type = type;\r
+  }\r
+\r
+  default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {\r
+    return msg;\r
+  }\r
+  \r
+  default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {\r
+    return msg;\r
+  }\r
+\r
+ default event void AMSend.sendDone[uint8_t id](message_t* msg, error_t err) {\r
+   return;\r
+ }\r
+\r
\r
+ command void Packet.clear(message_t* msg) {}\r
\r
+ command uint8_t Packet.payloadLength(message_t* msg) {\r
+   return getHeader(msg)->length - CC2420_SIZE;\r
+ }\r
+\r
+\r
+ command void Packet.setPayloadLength(message_t* msg, uint8_t len) {\r
+   getHeader(msg)->length  = len + CC2420_SIZE;\r
+ }\r
+\r
+ command uint8_t Packet.maxPayloadLength() {\r
+   return TOSH_DATA_LENGTH;\r
+ }\r
\r
+ command void* Packet.getPayload(message_t* msg, uint8_t* len) {\r
+   if (len != NULL) {\r
+     *len = call Packet.payloadLength(msg);\r
+   }\r
+   return msg->data;\r
+ }\r
+\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420Cca.nc b/tos/chips/cc2420_lpl/CC2420Cca.nc
new file mode 100644 (file)
index 0000000..58e75f3
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
\r
+/**\r
+ * Interface to obtain a CCA reading from the CC2420 radio\r
+ * to determine if a neighbor is transmitting\r
+ * @author David Moss\r
+ */\r
\r
+interface CC2420Cca {\r
+  \r
+  /**\r
+   * @return TRUE if the CCA pin shows a clear channel\r
+   */\r
+  command bool isChannelClear();\r
+  \r
+}\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420Config.nc b/tos/chips/cc2420_lpl/CC2420Config.nc
new file mode 100644 (file)
index 0000000..f9bd2e7
--- /dev/null
@@ -0,0 +1,73 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * An HAL abstraction of the ChipCon CC2420 radio. This abstraction\r
+ * deals specifically with radio configurations. All get() and set()\r
+ * commands are single-phase. After setting some values, a call to\r
+ * sync() is required for the changes to propagate to the cc2420\r
+ * hardware chip. This interface allows setting multiple parameters\r
+ * before calling sync().\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+interface CC2420Config {\r
+\r
+  /**\r
+   * Sync configuration changes with the radio hardware. This only\r
+   * applies to set commands below.\r
+   *\r
+   * @return SUCCESS if the request was accepted, FAIL otherwise.\r
+   */\r
+  command error_t sync();\r
+  event void syncDone( error_t error );\r
+\r
+  /**\r
+   * Change the channel of the radio.\r
+   */\r
+  command uint8_t getChannel();\r
+  command void setChannel( uint8_t channel );\r
+\r
+  /**\r
+   * Change the short address of the radio.\r
+   */\r
+  command uint16_t getShortAddr();\r
+  command void setShortAddr( uint16_t address );\r
+\r
+  /**\r
+   * Change the PAN address of the radio.\r
+   */\r
+  command uint16_t getPanAddr();\r
+  command void setPanAddr( uint16_t address );\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420ControlC.nc b/tos/chips/cc2420_lpl/CC2420ControlC.nc
new file mode 100644 (file)
index 0000000..8457c80
--- /dev/null
@@ -0,0 +1,93 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Implementation for configuring a ChipCon CC2420 radio.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#include "CC2420.h"\r
+#include "IEEE802154.h"\r
+\r
+configuration CC2420ControlC {\r
+\r
+  provides interface Init;\r
+  provides interface Resource;\r
+  provides interface CC2420Config;\r
+  provides interface CC2420Power;\r
+\r
+  uses interface AMPacket;\r
+\r
+}\r
+\r
+implementation {\r
+  \r
+  components CC2420ControlP;\r
+  Init = CC2420ControlP;\r
+  Resource = CC2420ControlP;\r
+  CC2420Config = CC2420ControlP;\r
+  CC2420Power = CC2420ControlP;\r
+  AMPacket = CC2420ControlP;\r
+\r
+  components AlarmMultiplexC as Alarm;\r
+  CC2420ControlP.StartupTimer -> Alarm;\r
+\r
+  components HplCC2420PinsC as Pins;\r
+  CC2420ControlP.CSN -> Pins.CSN;\r
+  CC2420ControlP.RSTN -> Pins.RSTN;\r
+  CC2420ControlP.VREN -> Pins.VREN;\r
+\r
+  components HplCC2420InterruptsC as Interrupts;\r
+  CC2420ControlP.InterruptCCA -> Interrupts.InterruptCCA;\r
+\r
+  components new CC2420SpiC() as Spi;\r
+  CC2420ControlP.SpiResource -> Spi;\r
+  CC2420ControlP.SRXON -> Spi.SRXON;\r
+  CC2420ControlP.SRFOFF -> Spi.SRFOFF;\r
+  CC2420ControlP.SXOSCON -> Spi.SXOSCON;\r
+  CC2420ControlP.SXOSCOFF -> Spi.SXOSCOFF;\r
+  CC2420ControlP.FSCTRL -> Spi.FSCTRL;\r
+  CC2420ControlP.IOCFG0 -> Spi.IOCFG0;\r
+  CC2420ControlP.IOCFG1 -> Spi.IOCFG1;\r
+  CC2420ControlP.MDMCTRL0 -> Spi.MDMCTRL0;\r
+  CC2420ControlP.MDMCTRL1 -> Spi.MDMCTRL1;\r
+  CC2420ControlP.PANID -> Spi.PANID;\r
+\r
+  components new CC2420SpiC() as SyncSpiC;\r
+  CC2420ControlP.SyncResource -> SyncSpiC;\r
+\r
+  components LedsC as Leds;\r
+  CC2420ControlP.Leds -> Leds;\r
+\r
+}\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420ControlP.nc b/tos/chips/cc2420_lpl/CC2420ControlP.nc
new file mode 100644 (file)
index 0000000..ca1084a
--- /dev/null
@@ -0,0 +1,286 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#include "Timer.h"\r
+\r
+module CC2420ControlP {\r
+\r
+  provides interface Init;\r
+  provides interface Resource;\r
+  provides interface CC2420Config;\r
+  provides interface CC2420Power;\r
+\r
+  uses interface Alarm<T32khz,uint32_t> as StartupTimer;\r
+  uses interface GeneralIO as CSN;\r
+  uses interface GeneralIO as RSTN;\r
+  uses interface GeneralIO as VREN;\r
+  uses interface GpioInterrupt as InterruptCCA;\r
+\r
+  uses interface Resource as SpiResource;\r
+  uses interface CC2420Ram as PANID;\r
+  uses interface CC2420Register as FSCTRL;\r
+  uses interface CC2420Register as IOCFG0;\r
+  uses interface CC2420Register as IOCFG1;\r
+  uses interface CC2420Register as MDMCTRL0;\r
+  uses interface CC2420Register as MDMCTRL1;\r
+  uses interface CC2420Strobe as SRXON;\r
+  uses interface CC2420Strobe as SRFOFF;\r
+  uses interface CC2420Strobe as SXOSCOFF;\r
+  uses interface CC2420Strobe as SXOSCON;\r
+  uses interface AMPacket;\r
+\r
+  uses interface Resource as SyncResource;\r
+\r
+  uses interface Leds;\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  typedef enum {\r
+    S_VREG_STOPPED,\r
+    S_VREG_STARTING,\r
+    S_VREG_STARTED,\r
+    S_XOSC_STARTING,\r
+    S_XOSC_STARTED,\r
+  } cc2420_control_state_t;\r
+\r
+  uint8_t m_channel = CC2420_DEF_CHANNEL;\r
+  uint8_t m_tx_power = CC2420_DEF_RFPOWER;\r
+  uint16_t m_pan = TOS_AM_GROUP;\r
+  uint16_t m_short_addr;\r
+  bool m_sync_busy;\r
+  task void syncDone_task();\r
+\r
+  norace cc2420_control_state_t m_state = S_VREG_STOPPED;\r
+\r
+  command error_t Init.init() {\r
+    call CSN.makeOutput();\r
+    call RSTN.makeOutput();\r
+    call VREN.makeOutput();\r
+    m_short_addr = call AMPacket.address();\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command error_t Resource.immediateRequest() {\r
+    error_t error = call SpiResource.immediateRequest();\r
+    if ( error == SUCCESS )\r
+      call CSN.clr();\r
+    return error;\r
+  }\r
+\r
+  async command error_t Resource.request() {\r
+    return call SpiResource.request();\r
+  }\r
+\r
+  async command uint8_t Resource.isOwner() {\r
+    return call SpiResource.isOwner();\r
+  }\r
+\r
+  async command error_t Resource.release() {\r
+    atomic {\r
+      call CSN.set();\r
+      return call SpiResource.release();\r
+    }\r
+  }\r
+\r
+  event void SpiResource.granted() {\r
+    call CSN.clr();\r
+    signal Resource.granted();\r
+  }\r
+\r
+  async command error_t CC2420Power.startVReg() {\r
+    atomic {\r
+      if ( m_state != S_VREG_STOPPED )\r
+       return FAIL;\r
+      m_state = S_VREG_STARTING;\r
+    }\r
+    call VREN.set();\r
+    call StartupTimer.start( CC2420_TIME_VREN );\r
+    return SUCCESS;\r
+  }\r
+\r
+  async event void StartupTimer.fired() {\r
+    if ( m_state == S_VREG_STARTING ) {\r
+      m_state = S_VREG_STARTED;\r
+      call RSTN.clr();\r
+      call RSTN.set();\r
+      signal CC2420Power.startVRegDone();\r
+    }\r
+  }\r
+\r
+  async command error_t CC2420Power.stopVReg() {\r
+    m_state = S_VREG_STOPPED;\r
+    call RSTN.clr();\r
+    call VREN.clr();\r
+    call RSTN.set();\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command error_t CC2420Power.startOscillator() {\r
+    atomic {\r
+      if ( m_state != S_VREG_STARTED )\r
+       return FAIL;\r
+       \r
+      m_state = S_XOSC_STARTING;\r
+      call IOCFG1.write( CC2420_SFDMUX_XOSC16M_STABLE << \r
+                        CC2420_IOCFG1_CCAMUX );\r
+      call InterruptCCA.enableRisingEdge();\r
+      call SXOSCON.strobe();\r
+      call IOCFG0.write( ( 1 << CC2420_IOCFG0_FIFOP_POLARITY ) |\r
+                        ( 127 << CC2420_IOCFG0_FIFOP_THR ) );\r
+      call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |\r
+                        ( ( (m_channel - 11)*5+357 ) \r
+                          << CC2420_FSCTRL_FREQ ) );\r
+      call MDMCTRL0.write( ( 1 << CC2420_MDMCTRL0_RESERVED_FRAME_MODE ) |\r
+                          ( 1 << CC2420_MDMCTRL0_ADR_DECODE ) |\r
+                          ( 2 << CC2420_MDMCTRL0_CCA_HYST ) |\r
+                          ( 3 << CC2420_MDMCTRL0_CCA_MOD ) |\r
+                          ( 1 << CC2420_MDMCTRL0_AUTOCRC ) |\r
+                          ( 1 << CC2420_MDMCTRL0_AUTOACK ) |\r
+                          ( 2 << CC2420_MDMCTRL0_PREAMBLE_LENGTH ) );\r
+    }\r
+    return SUCCESS;\r
+  }\r
+\r
+  async event void InterruptCCA.fired() {\r
+    nxle_uint16_t id[ 2 ];\r
+    m_state = S_XOSC_STARTED;\r
+    id[ 0 ] = m_pan;\r
+    id[ 1 ] = m_short_addr;\r
+    call InterruptCCA.disable();\r
+    call IOCFG1.write( 0 );\r
+    call PANID.write( 0, (uint8_t*)&id, 4 );\r
+    call CSN.set();\r
+    call CSN.clr();\r
+    signal CC2420Power.startOscillatorDone();\r
+  }\r
+\r
+  async command error_t CC2420Power.stopOscillator() {\r
+    atomic {\r
+      if ( m_state != S_XOSC_STARTED )\r
+       return FAIL;\r
+      m_state = S_VREG_STARTED;\r
+      call SXOSCOFF.strobe();\r
+    }\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command error_t CC2420Power.rxOn() {\r
+    atomic {\r
+      if ( m_state != S_XOSC_STARTED )\r
+       return FAIL;\r
+      call SRXON.strobe();\r
+    }\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command error_t CC2420Power.rfOff() {\r
+    atomic {  \r
+      if ( m_state != S_XOSC_STARTED )\r
+       return FAIL;\r
+      call SRFOFF.strobe();\r
+    }\r
+    return SUCCESS;\r
+  }\r
+\r
+  command uint8_t CC2420Config.getChannel() {\r
+    atomic return m_channel;\r
+  }\r
+\r
+  command void CC2420Config.setChannel( uint8_t channel ) {\r
+    atomic m_channel = channel;\r
+  }\r
+\r
+  command uint16_t CC2420Config.getShortAddr() {\r
+    atomic return m_short_addr;\r
+  }\r
+\r
+  command void CC2420Config.setShortAddr( uint16_t addr ) {\r
+    atomic m_short_addr = addr;\r
+  }\r
+\r
+  command uint16_t CC2420Config.getPanAddr() {\r
+    return m_pan;\r
+  }\r
+\r
+  command void CC2420Config.setPanAddr( uint16_t pan ) {\r
+    atomic m_pan = pan;\r
+  }\r
+\r
+  command error_t CC2420Config.sync() {\r
+    atomic {\r
+      if ( m_sync_busy )\r
+        return FAIL;\r
+      m_sync_busy = TRUE;\r
+      if ( m_state == S_XOSC_STARTED )\r
+        call SyncResource.request();\r
+      else\r
+        post syncDone_task();\r
+    }\r
+    return SUCCESS;\r
+  }\r
+\r
+  event void SyncResource.granted() {\r
+\r
+    nxle_uint16_t id[ 2 ];\r
+    uint8_t channel;\r
+\r
+    atomic {\r
+      channel = m_channel;\r
+      id[ 0 ] = m_pan;\r
+      id[ 1 ] = m_short_addr;\r
+    }\r
+\r
+    call CSN.clr();\r
+    call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |\r
+                      ( ( (channel - 11)*5+357 ) << CC2420_FSCTRL_FREQ ) );\r
+    call PANID.write( 0, (uint8_t*)id, sizeof( id ) );\r
+    call CSN.set();\r
+    call SyncResource.release();\r
+    \r
+    post syncDone_task();\r
+    \r
+  }\r
+\r
+  task void syncDone_task() {\r
+    atomic m_sync_busy = FALSE;\r
+    signal CC2420Config.syncDone( SUCCESS );\r
+  }\r
+\r
+  default event void CC2420Config.syncDone( error_t error ) {}\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420CsmaC.nc b/tos/chips/cc2420_lpl/CC2420CsmaC.nc
new file mode 100644 (file)
index 0000000..8743b4c
--- /dev/null
@@ -0,0 +1,88 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Basic implementation of a CSMA MAC for the ChipCon CC2420 radio.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#include "CC2420.h"\r
+#include "IEEE802154.h"\r
+\r
+configuration CC2420CsmaC {\r
+\r
+  provides interface SplitControl;\r
+  provides interface Send;\r
+  provides interface Receive;\r
+  provides interface CsmaBackoff[am_id_t amId];\r
+\r
+  uses interface AMPacket;\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  components CC2420CsmaP as CsmaP;\r
+\r
+  CsmaBackoff = CsmaP;\r
+  SplitControl = CsmaP;\r
+  Send = CsmaP;\r
+  AMPacket = CsmaP;\r
+\r
+  components CC2420ControlC;\r
+  AMPacket = CC2420ControlC;\r
+  CsmaP.Resource -> CC2420ControlC;\r
+  CsmaP.CC2420Power -> CC2420ControlC;\r
+\r
+  components CC2420TransmitC;\r
+\r
+  CsmaP.SubControl -> CC2420TransmitC;\r
+  CsmaP.CC2420Transmit -> CC2420TransmitC;\r
+  CsmaP.SubBackoff -> CC2420TransmitC;\r
+\r
+  components CC2420ReceiveC;\r
+  Receive = CC2420ReceiveC;\r
+  CsmaP.SubControl -> CC2420ReceiveC;\r
+\r
+  components RandomC;\r
+  CsmaP.Random -> RandomC;\r
+\r
+  components LedsC as Leds;\r
+  CsmaP.Leds -> Leds;\r
+\r
+  components MainC;\r
+  MainC.SoftwareInit -> CsmaP;\r
+  MainC.SoftwareInit -> CC2420ControlC;\r
+  MainC.SoftwareInit -> CC2420TransmitC;\r
+  MainC.SoftwareInit -> CC2420ReceiveC;\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420CsmaP.nc b/tos/chips/cc2420_lpl/CC2420CsmaP.nc
new file mode 100644 (file)
index 0000000..9911f5a
--- /dev/null
@@ -0,0 +1,233 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+module CC2420CsmaP {\r
+\r
+  provides interface Init;\r
+  provides interface SplitControl;\r
+  provides interface Send;\r
+  provides interface CsmaBackoff[am_id_t amId];\r
+\r
+  uses interface Resource;\r
+  uses interface CC2420Power;\r
+  uses interface AsyncStdControl as SubControl;\r
+  uses interface CC2420Transmit;\r
+  uses interface CsmaBackoff as SubBackoff;\r
+  uses interface Random;\r
+  uses interface AMPacket;\r
+  uses interface Leds;\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  enum {\r
+    S_PREINIT,\r
+    S_STOPPED,\r
+    S_STARTING,\r
+    S_STARTED,\r
+    S_STOPPING,\r
+    S_TRANSMIT,\r
+  };\r
+\r
+  message_t* m_msg;\r
+  uint8_t m_state = S_PREINIT;\r
+  uint8_t m_dsn;\r
+  error_t sendErr = SUCCESS;\r
+  \r
+  task void startDone_task();\r
+  task void stopDone_task();\r
+  task void sendDone_task();\r
+\r
+  cc2420_header_t* getHeader( message_t* msg ) {\r
+    return (cc2420_header_t*)( msg->data - sizeof( cc2420_header_t ) );\r
+  }\r
+\r
+  cc2420_metadata_t* getMetadata( message_t* msg ) {\r
+    return (cc2420_metadata_t*)msg->metadata;\r
+  }\r
+\r
+  command error_t Init.init() {\r
+    \r
+    if ( m_state != S_PREINIT )\r
+      return FAIL;\r
+\r
+    m_state = S_STOPPED;\r
+\r
+    return SUCCESS;\r
+\r
+  }\r
+\r
+  command error_t SplitControl.start() {\r
+\r
+    if ( m_state != S_STOPPED ) \r
+      return FAIL;\r
+\r
+    m_state = S_STARTING;\r
+\r
+    m_dsn = call Random.rand16();\r
+    call CC2420Power.startVReg();\r
+\r
+    return SUCCESS;\r
+\r
+  }\r
+\r
+  async event void CC2420Power.startVRegDone() {\r
+    call Resource.request();\r
+  }\r
+\r
+  event void Resource.granted() {\r
+    call CC2420Power.startOscillator();\r
+  }\r
+\r
+  async event void CC2420Power.startOscillatorDone() {\r
+    call SubControl.start();\r
+    call CC2420Power.rxOn();\r
+    call Resource.release();\r
+    post startDone_task();\r
+  }\r
+\r
+  task void startDone_task() {\r
+    m_state = S_STARTED;\r
+    signal SplitControl.startDone( SUCCESS );\r
+  }\r
+\r
+  command error_t SplitControl.stop() {\r
+\r
+    if ( m_state != S_STARTED )\r
+      return FAIL;\r
+\r
+    m_state = S_STOPPING;\r
+\r
+    call SubControl.stop();\r
+    call CC2420Power.stopVReg();\r
+    post stopDone_task();\r
+\r
+    return SUCCESS;\r
+\r
+  }\r
+\r
+  task void stopDone_task() {\r
+    m_state = S_STOPPED;\r
+    signal SplitControl.stopDone( SUCCESS );\r
+  }\r
+\r
+  command error_t Send.cancel( message_t* p_msg ) {\r
+    return FAIL;\r
+  }\r
+\r
+  command error_t Send.send( message_t* p_msg, uint8_t len ) {\r
+    \r
+    cc2420_header_t* header = getHeader( p_msg );\r
+    cc2420_metadata_t* metadata = getMetadata( p_msg );\r
+\r
+    atomic {\r
+      if ( m_state != S_STARTED )\r
+        return FAIL;\r
+      m_state = S_TRANSMIT;\r
+      m_msg = p_msg;\r
+      header->dsn = ++m_dsn;\r
+    }\r
+\r
+    header->length = len;\r
+    header->fcf &= 1 << IEEE154_FCF_ACK_REQ;\r
+    header->fcf |= ( ( IEEE154_TYPE_DATA << IEEE154_FCF_FRAME_TYPE ) |\r
+                    ( 1 << IEEE154_FCF_INTRAPAN ) |\r
+                    ( IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE ) |\r
+                    ( IEEE154_ADDR_SHORT << IEEE154_FCF_SRC_ADDR_MODE ) );\r
+    header->src = call AMPacket.address();\r
+    metadata->ack = FALSE;\r
+    metadata->rssi = 0;\r
+    metadata->lqi = 0;\r
+    metadata->time = 0;\r
+\r
+    call CC2420Transmit.sendCCA( m_msg );\r
+\r
+    return SUCCESS;\r
+\r
+  }\r
+\r
+  command void* Send.getPayload(message_t* m) {\r
+    return m->data;\r
+  }\r
+\r
+  command uint8_t Send.maxPayloadLength() {\r
+    return TOSH_DATA_LENGTH;\r
+  }\r
+\r
+  async event uint16_t SubBackoff.initial( message_t* msg ) {\r
+    return signal CsmaBackoff.initial[((cc2420_header_t*)(msg->data - \r
+        sizeof(cc2420_header_t)))->type](msg);\r
+  }\r
+\r
+  async event uint16_t SubBackoff.congestion( message_t* msg ) {\r
+    return signal CsmaBackoff.congestion[((cc2420_header_t*)(msg->data - \r
+        sizeof(cc2420_header_t)))->type](msg);\r
+  }\r
+\r
+  async event void CC2420Transmit.sendDone( message_t* p_msg, error_t err ) {\r
+    atomic sendErr = err;\r
+    post sendDone_task();\r
+  }\r
+\r
+  task void sendDone_task() {\r
+    error_t packetErr;\r
+    atomic packetErr = sendErr;\r
+    m_state = S_STARTED;\r
+    signal Send.sendDone( m_msg, packetErr );\r
+  }\r
+\r
+\r
+  /***************** Defaults ***************/\r
+  default async event uint16_t CsmaBackoff.initial[am_id_t amId](\r
+      message_t *m) {\r
+    return ( call Random.rand16() % (0x1F * CC2420_BACKOFF_PERIOD) \r
+        + CC2420_MIN_BACKOFF);\r
+  }\r
+\r
+  default async event uint16_t CsmaBackoff.congestion[am_id_t amId](\r
+      message_t *m) {\r
+    return ( call Random.rand16() % (0x7 * CC2420_BACKOFF_PERIOD) \r
+        + CC2420_MIN_BACKOFF);\r
+  }\r
+  \r
+  default event void SplitControl.startDone(error_t error) {\r
+  }\r
+  \r
+  default event void SplitControl.stopDone(error_t error) {\r
+  }\r
+}\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420DutyCycle.h b/tos/chips/cc2420_lpl/CC2420DutyCycle.h
new file mode 100644 (file)
index 0000000..4d38e4a
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * @author David Moss\r
+ */\r
\r
+#ifndef CC2420DUTYCYCLE_H\r
+#define CC2420DUTYCYCLE_H\r
+\r
+/**\r
+ * Default duty period is 0, which is "always on"\r
+ */\r
+#ifndef DEFAULT_DUTY_PERIOD\r
+#define DEFAULT_DUTY_PERIOD 0\r
+#endif\r
+\r
+/**\r
+ * This is a measured value of the time the radio is actually on (5.8 ms)\r
+ * We round this up to 6 ms for erring on the side of better performance ratios\r
+ */\r
+#ifndef DUTY_ON_TIME\r
+#define DUTY_ON_TIME 6         // TODO re-measure\r
+#endif\r
+\r
+/**\r
+ * The maximum number of CCA checks performed on each wakeup.\r
+ * If there are too few, the receiver may wake up between messages\r
+ * and not detect the transmitter.\r
+ */\r
+#ifndef MAX_LPL_CCA_CHECKS\r
+#define MAX_LPL_CCA_CHECKS 100\r
+#endif\r
+\r
+#endif\r
diff --git a/tos/chips/cc2420_lpl/CC2420DutyCycle.nc b/tos/chips/cc2420_lpl/CC2420DutyCycle.nc
new file mode 100644 (file)
index 0000000..785cf6d
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
\r
+/**\r
+ * Manage the CC2420's duty cycle and power\r
+ * @author David Moss\r
+ */\r
\r
+interface CC2420DutyCycle {\r
+  \r
+  /**\r
+   * Set the sleep interval, in binary milliseconds\r
+   * @param sleepIntervalMs the sleep interval in [ms]\r
+   */\r
+  command void setSleepInterval(uint16_t sleepIntervalMs);\r
+  \r
+  /**\r
+   * @return the sleep interval in [ms]\r
+   */\r
+  command uint16_t getSleepInterval();\r
+  \r
+  /**\r
+   * A transmitter was detected.  You must now take action to\r
+   * turn the radio off when the transaction is complete.\r
+   */\r
+  event void detected();\r
+\r
+}\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420DutyCycleC.nc b/tos/chips/cc2420_lpl/CC2420DutyCycleC.nc
new file mode 100644 (file)
index 0000000..c118bcd
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
\r
+/**\r
+ * Use this component to duty cycle the radio. When a message is heard, \r
+ * disable DutyCycling.\r
+ *\r
+ * @author David Moss dmm@rincon.com\r
+ */\r
+\r
+#include "CC2420DutyCycle.h"\r
+\r
+configuration CC2420DutyCycleC {\r
+  provides {\r
+    interface CC2420DutyCycle;\r
+    interface SplitControl;\r
+    interface State as SplitControlState;\r
+  }\r
+}\r
+\r
+implementation {\r
+  components MainC,\r
+      CC2420DutyCycleP,\r
+      CC2420TransmitC,\r
+      CC2420CsmaC,\r
+      LedsC,\r
+      new StateC() as RadioPowerStateC,\r
+      new StateC() as DutyCycleStateC,\r
+      new StateC() as CheckStateC,\r
+      new StateC() as SplitControlStateC,\r
+      new TimerMilliC() as OnTimerC,\r
+      new TimerMilliC() as CheckTimerC,\r
+      RandomC;\r
+      \r
+  CC2420DutyCycle = CC2420DutyCycleP;\r
+  SplitControl = CC2420DutyCycleP;\r
+  SplitControlState = SplitControlStateC;\r
+  \r
+  MainC.SoftwareInit -> CC2420DutyCycleP;\r
+  \r
+  CC2420DutyCycleP.Random -> RandomC;\r
+  CC2420DutyCycleP.CC2420Cca -> CC2420TransmitC;\r
+  CC2420DutyCycleP.SubControl -> CC2420CsmaC;\r
+  CC2420DutyCycleP.RadioPowerState -> RadioPowerStateC;\r
+  CC2420DutyCycleP.DutyCycleState -> DutyCycleStateC;\r
+  CC2420DutyCycleP.SplitControlState -> SplitControlStateC;\r
+  CC2420DutyCycleP.CheckState -> CheckStateC;\r
+  CC2420DutyCycleP.OnTimer -> OnTimerC;\r
+  CC2420DutyCycleP.Leds -> LedsC;\r
+}\r
+\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420DutyCycleP.nc b/tos/chips/cc2420_lpl/CC2420DutyCycleP.nc
new file mode 100644 (file)
index 0000000..1489166
--- /dev/null
@@ -0,0 +1,286 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
\r
+/** \r
+ * Module to duty cycle the radio on and off, performing CCA receive checks.\r
+ * When a carrier is sensed, this will leave the radio on. It is then up\r
+ * to higher layers to turn the radio off again.  Once the radio is turned\r
+ * off, this module will automatically continue duty cycling and looking for\r
+ * a modulated signal.\r
+ *\r
+ * @author David Moss\r
+ */\r
\r
+#include "CC2420DutyCycle.h"\r
+\r
+module CC2420DutyCycleP {\r
+  provides {\r
+    interface CC2420DutyCycle;\r
+    interface Init;\r
+    interface SplitControl;\r
+  }\r
+\r
+  uses {\r
+    interface Timer<TMilli> as OnTimer;\r
+    interface SplitControl as SubControl;\r
+    interface State as RadioPowerState;\r
+    interface State as DutyCycleState;\r
+    interface State as SplitControlState;\r
+    interface State as CheckState;\r
+    interface Leds;\r
+    interface CC2420Cca;\r
+    interface Random;\r
+  }\r
+}\r
+\r
+implementation {\r
+  \r
+  /** The current period of the duty cycle, equivalent of wakeup interval */\r
+  uint16_t sleepInterval;\r
+  \r
+  /** The number of times the CCA has been sampled in this wakeup period */\r
+  uint8_t ccaChecks;\r
+    \r
+  /**\r
+   * Radio Power, Check State, and Duty Cycling State\r
+   */\r
+  enum {\r
+    S_OFF, // off by default\r
+    S_ON,\r
+  };\r
+  \r
+  \r
+  /***************** Prototypes ****************/\r
+  task void stopRadio();\r
+  task void startRadio();\r
+  task void getCca();\r
+  \r
+  /***************** Init Commands ****************/\r
+  command error_t Init.init() {\r
+    sleepInterval = DEFAULT_DUTY_PERIOD;\r
+    return SUCCESS;\r
+  }\r
+  \r
+  /***************** CC2420DutyCycle Commands ****************/\r
+  /**\r
+   * Set the sleep interval, in binary milliseconds\r
+   * @param sleepIntervalMs the sleep interval in [ms]\r
+   */\r
+  command void CC2420DutyCycle.setSleepInterval(uint16_t sleepIntervalMs) {\r
+    sleepInterval = sleepIntervalMs;\r
+    \r
+    if(sleepInterval == 0 && call DutyCycleState.getState() == S_ON) {\r
+      call DutyCycleState.forceState(S_OFF);\r
+      call CheckState.toIdle();\r
+      \r
+      /*\r
+       * Leave the radio on permanently if sleepInterval == 0 and the radio is \r
+       * supposed to be enabled\r
+       */\r
+      if(call RadioPowerState.getState() == S_OFF) {\r
+        call SubControl.start();\r
+      }\r
+    }\r
+  }\r
+  \r
+  /**\r
+   * @return the sleep interval in [ms]\r
+   */\r
+  command uint16_t CC2420DutyCycle.getSleepInterval() {\r
+    return sleepInterval;\r
+  }\r
+  \r
+  /***************** SplitControl Commands ****************/\r
+  command error_t SplitControl.start() {\r
+    call SplitControlState.forceState(S_ON);\r
+    \r
+    if(sleepInterval > 0) {\r
+      // Begin duty cycling\r
+      call DutyCycleState.forceState(S_ON);\r
+      call CheckState.toIdle();\r
+      post stopRadio();\r
+      signal SplitControl.startDone(SUCCESS);\r
+      \r
+    } else {\r
+      call DutyCycleState.forceState(S_OFF);\r
+      call CheckState.toIdle();\r
+      \r
+      /*\r
+       * Leave the radio on permanently if sleepInterval == 0 and the radio is \r
+       * supposed to be enabled\r
+       */\r
+      if(call RadioPowerState.getState() == S_OFF) {\r
+        call SubControl.start();\r
+        // Here, SplitControl.startDone is signaled on SubControl.startDone\r
+        \r
+      } else {\r
+        // Radio is already on\r
+        signal SplitControl.startDone(SUCCESS);\r
+      }\r
+    }\r
+\r
+    return SUCCESS;\r
+  }\r
+  \r
+  command error_t SplitControl.stop() {\r
+    call SplitControlState.forceState(S_OFF);\r
+    call DutyCycleState.forceState(S_OFF);\r
+    call CheckState.toIdle();\r
+    return call SubControl.stop();\r
+    \r
+    /*\r
+     * SubControl.stopDone signals SplitControl.stopDone when  \r
+     * DutyCycleState is S_OFF\r
+     */\r
+  }\r
+  \r
+  /***************** Timer Events ****************/\r
+  event void OnTimer.fired() {\r
+    if(call DutyCycleState.getState() == S_ON) {\r
+      if(call RadioPowerState.getState() == S_OFF) {\r
+        call CheckState.forceState(S_ON);\r
+        ccaChecks = 0;\r
+        \r
+        /*\r
+         * The MicaZ, running on an external oscillator I think, and\r
+         * returning the microcontroller out of a sleep state to immediately\r
+         * perform an ADC conversion, sucks.  The first ADC conversion out\r
+         * of a sleep state lasts about a second.  We don't want the radio\r
+         * on that long.  Like the CC1000 RSSI pulse check implementation\r
+         * done in the Rincon CC1000Radio stack, we will perform\r
+         * a single ADC conversion and then flip on the radio to check\r
+         * the channel.\r
+         */\r
+         post getCca();\r
+        \r
+      } else {\r
+        // Someone else turned on the radio, try again in awhile\r
+        call OnTimer.startOneShot(sleepInterval);\r
+      }\r
+    }\r
+  }\r
+  \r
+  /***************** SubControl Events ****************/\r
+  event void SubControl.startDone(error_t error) {\r
+    if(call DutyCycleState.getState() == S_ON && error) {\r
+      // My responsibility to try again\r
+      post startRadio();\r
+      return;\r
+    }\r
+    \r
+    call RadioPowerState.forceState(S_ON);\r
+    //call Leds.led2On();\r
+    \r
+    if(call DutyCycleState.getState() == S_ON) {\r
+      if(call CheckState.getState() == S_ON) {\r
+        post getCca();\r
+      }\r
+      \r
+    } else {\r
+      // Must have turned the radio on manually\r
+      signal SplitControl.startDone(SUCCESS);\r
+    }\r
+  }\r
+  \r
+  event void SubControl.stopDone(error_t error) {\r
+    if(error && call DutyCycleState.getState() == S_ON) {\r
+      // My responsibility to try again\r
+      post stopRadio();\r
+      return;\r
+    }\r
+    \r
+    call RadioPowerState.forceState(S_OFF);\r
+    //call Leds.led2Off();\r
+    \r
+    if(call DutyCycleState.getState() == S_ON) {\r
+      call OnTimer.startOneShot(sleepInterval);\r
+\r
+    } else {\r
+      // Must have turned off the radio manually\r
+      signal SplitControl.stopDone(error);\r
+    }\r
+    \r
+  }\r
+  \r
+  \r
+  /***************** Tasks ****************/\r
+  task void stopRadio() {\r
+    if(call DutyCycleState.getState() == S_ON) {\r
+      if(call SubControl.stop() != SUCCESS) {\r
+        // Already stopped?\r
+        call OnTimer.startOneShot(sleepInterval);\r
+      }\r
+    }\r
+  }\r
+  \r
+  task void startRadio() {\r
+    if(call DutyCycleState.getState() == S_ON) {\r
+      if(call SubControl.start() != SUCCESS) {\r
+        post startRadio();\r
+      }\r
+    }\r
+  }\r
\r
+  \r
+  task void getCca() {\r
+    if(call DutyCycleState.getState() == S_ON) {\r
+      \r
+      ccaChecks++;\r
+      if(ccaChecks == 1) {\r
+        // Microcontroller is ready, turn on the radio and sample a few times\r
+        post startRadio();\r
+        return;\r
+      } \r
+\r
+      if(!call CC2420Cca.isChannelClear()) {\r
+        signal CC2420DutyCycle.detected(); \r
+        // Leave the radio on for upper layers to perform some transaction\r
+      \r
+      } else {\r
+        if(ccaChecks <= MAX_LPL_CCA_CHECKS) {\r
+          post getCca();\r
+          return;\r
+      \r
+        } else {\r
+          call CheckState.toIdle();\r
+          post stopRadio();\r
+        }\r
+      }\r
+    }  \r
+  }\r
+  \r
+  /**************** Defaults ****************/\r
+  default event void CC2420DutyCycle.detected() {\r
+  }\r
+\r
+}\r
+\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420Fifo.nc b/tos/chips/cc2420_lpl/CC2420Fifo.nc
new file mode 100644 (file)
index 0000000..ba4d653
--- /dev/null
@@ -0,0 +1,93 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * HAL abstraction for accessing the FIFO registers of a ChipCon\r
+ * CC2420 radio.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+interface CC2420Fifo {\r
+\r
+  /**\r
+   * Start reading from the FIFO. The <code>readDone</code> event will\r
+   * be signalled upon completion.\r
+   *\r
+   * @param data a pointer to the receive buffer.\r
+   * @param length number of bytes to read.\r
+   * @return status byte returned when sending the last address byte\r
+   * of the SPI transaction.\r
+   */\r
+  async command cc2420_status_t beginRead( uint8_t* data, uint8_t length );\r
+\r
+  /**\r
+   * Continue reading from the FIFO without having to send the address\r
+   * byte again. The <code>readDone</code> event will be signalled\r
+   * upon completion.\r
+   *\r
+   * @param data a pointer to the receive buffer.\r
+   * @param length number of bytes to read.\r
+   * @return SUCCESS always.\r
+   */\r
+  async command error_t continueRead( uint8_t* data, uint8_t length );\r
+\r
+  /**\r
+   * Signals the completion of a read operation.\r
+   *\r
+   * @param data a pointer to the receive buffer.\r
+   * @param length number of bytes read.\r
+   * @param error notification of how the operation went\r
+   */\r
+  async event void readDone( uint8_t* data, uint8_t length, error_t error );\r
+\r
+  /**\r
+   * Start writing the FIFO. The <code>writeDone</code> event will be\r
+   * signalled upon completion.\r
+   *\r
+   * @param data a pointer to the send buffer.\r
+   * @param length number of bytes to write.\r
+   * @return status byte returned when sending the last address byte\r
+   * of the SPI transaction.\r
+   */\r
+  async command cc2420_status_t write( uint8_t* data, uint8_t length );\r
+\r
+  /**\r
+   * Signals the completion of a write operation.\r
+   *\r
+   * @param data a pointer to the send buffer.\r
+   * @param length number of bytes written.\r
+   * @param error notification of how the operation went\r
+   */\r
+  async event void writeDone( uint8_t* data, uint8_t length, error_t error );\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420LowPowerListening.h b/tos/chips/cc2420_lpl/CC2420LowPowerListening.h
new file mode 100644 (file)
index 0000000..ae6d0e7
--- /dev/null
@@ -0,0 +1,66 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
\r
+ /**\r
+  * @author David Moss\r
+  */\r
+#ifndef CC2420LOWPOWERLISTENING_H\r
+#define CC2420LOWPOWERLISTENING_H\r
+\r
+#include "CC2420DutyCycle.h"\r
+\r
+/**\r
+ * The default duty period is usually 0, which is the equivalent of\r
+ * ONE_MESSAGE (below), which tells the node to transmit the message\r
+ * one time without expecting receiver duty cycling.\r
+ */\r
+#ifndef DEFAULT_TRANSMIT_PERIOD\r
+#define DEFAULT_TRANSMIT_PERIOD DEFAULT_DUTY_PERIOD\r
+#endif\r
+\r
+/**\r
+ * Amount of time, in milliseconds, to keep the radio on after\r
+ * a successful receive addressed to this node\r
+ */\r
+#ifndef DELAY_AFTER_RECEIVE\r
+#define DELAY_AFTER_RECEIVE 50\r
+#endif\r
+\r
+/**\r
+ * Value used to indicate the message being sent should be transmitted\r
+ * one time\r
+ */\r
+#ifndef ONE_MESSAGE\r
+#define ONE_MESSAGE 0\r
+#endif\r
+\r
+#endif\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420LowPowerListeningC.nc b/tos/chips/cc2420_lpl/CC2420LowPowerListeningC.nc
new file mode 100644 (file)
index 0000000..1bdfa37
--- /dev/null
@@ -0,0 +1,83 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Low Power Listening for the CC2420\r
+ * @author David Moss\r
+ */\r
\r
+#include "CC2420LowPowerListening.h"\r
+\r
+configuration CC2420LowPowerListeningC {\r
+  provides {\r
+    interface LowPowerListening;\r
+    interface Send;\r
+    interface Receive;\r
+    interface SplitControl;\r
+  }\r
+}\r
+\r
+implementation {\r
+  components MainC,\r
+      CC2420LowPowerListeningP,\r
+      CC2420DutyCycleC,\r
+      CC2420ActiveMessageC,\r
+      CC2420CsmaC,\r
+      CC2420TransmitC,\r
+      RandomC,\r
+      new StateC() as SendStateC,\r
+      new StateC() as RadioStateC,\r
+      new TimerMilliC() as OffTimerC,\r
+      new TimerMilliC() as SendDoneTimerC;\r
+  \r
+  LowPowerListening = CC2420LowPowerListeningP;\r
+  Send = CC2420LowPowerListeningP;\r
+  Receive = CC2420LowPowerListeningP;\r
+  SplitControl = CC2420DutyCycleC;\r
+  \r
+  MainC.SoftwareInit -> CC2420LowPowerListeningP;\r
+  \r
+  CC2420LowPowerListeningP.Random -> RandomC;\r
+  CC2420LowPowerListeningP.SendState -> SendStateC;\r
+  CC2420LowPowerListeningP.RadioState -> RadioStateC;\r
+  CC2420LowPowerListeningP.SplitControlState -> CC2420DutyCycleC;\r
+  CC2420LowPowerListeningP.OffTimer -> OffTimerC;\r
+  CC2420LowPowerListeningP.SendDoneTimer -> SendDoneTimerC;\r
+  CC2420LowPowerListeningP.CC2420DutyCycle -> CC2420DutyCycleC;\r
+  CC2420LowPowerListeningP.SubSend -> CC2420CsmaC;\r
+  CC2420LowPowerListeningP.Resend -> CC2420TransmitC;\r
+  CC2420LowPowerListeningP.SubReceive -> CC2420CsmaC;\r
+  CC2420LowPowerListeningP.SubControl -> CC2420CsmaC;\r
+  CC2420LowPowerListeningP.PacketAcknowledgements -> CC2420ActiveMessageC;\r
+  CC2420LowPowerListeningP.AMPacket -> CC2420ActiveMessageC;\r
+  \r
+}\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420LowPowerListeningP.nc b/tos/chips/cc2420_lpl/CC2420LowPowerListeningP.nc
new file mode 100644 (file)
index 0000000..51b405e
--- /dev/null
@@ -0,0 +1,505 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Low Power Listening for the CC2420\r
+ *\r
+ * @author David Moss\r
+ */\r
+\r
+#include "CC2420LowPowerListening.h"\r
+\r
+module CC2420LowPowerListeningP {\r
+  provides {\r
+    interface Init;\r
+    interface LowPowerListening;\r
+    interface Send;\r
+    interface Receive;\r
+  }\r
+  \r
+  uses {\r
+    interface Leds;\r
+    interface Send as SubSend;\r
+    interface CC2420Transmit as Resend;\r
+    interface Receive as SubReceive;\r
+    interface AMPacket;\r
+    interface SplitControl as SubControl;\r
+    interface CC2420DutyCycle;\r
+    interface PacketAcknowledgements;\r
+    interface State as SendState;\r
+    interface State as RadioState;\r
+    interface State as SplitControlState;\r
+    interface Random;\r
+    interface Timer<TMilli> as OffTimer;\r
+    interface Timer<TMilli> as SendDoneTimer;\r
+  }\r
+}\r
+\r
+implementation {\r
+  \r
+  /** The message currently being sent */\r
+  message_t *currentSendMsg;\r
+  \r
+  /** The length of the current send message */\r
+  uint8_t currentSendLen;\r
+  \r
+  /** TRUE if the radio is duty cycling and not always on */\r
+  bool dutyCycling;\r
\r
+  /** Tx DSN to ensure multiple transmitted messages get across only once */ \r
+  uint8_t txDsn;\r
+  \r
+  /** The last received broadcast DSN. TODO is this the best way? */\r
+  uint8_t lastRxDsn;\r
+\r
+  /**\r
+   * Radio State\r
+   */\r
+  enum {\r
+    S_OFF,\r
+    S_ON,\r
+  };\r
+  \r
+  /**\r
+   * Send States\r
+   */\r
+  enum {\r
+    S_IDLE,\r
+    S_SENDING,\r
+  };\r
+  \r
+  \r
+  /***************** Prototypes ***************/\r
+  task void send();\r
+  task void resend();\r
+  task void startRadio();\r
+  task void stopRadio();\r
+  \r
+  void startOffTimer();\r
+  cc2420_header_t *getHeader(message_t *msg);\r
+  cc2420_metadata_t *getMetadata(message_t* msg);\r
+  uint16_t getActualDutyCycle(uint16_t dutyCycle);\r
+  void signalDone(error_t error);\r
+  \r
+  /***************** Init Commands ***************/\r
+  command error_t Init.init() {\r
+    txDsn = call Random.rand16();\r
+    dutyCycling = FALSE;\r
+    return SUCCESS;\r
+  }\r
+  \r
+  /***************** LowPowerListening Commands ***************/\r
+  /**\r
+   * Set this this node's radio sleep interval, in milliseconds.\r
+   * Once every interval, the node will sleep and perform an Rx check \r
+   * on the radio.  Setting the sleep interval to 0 will keep the radio\r
+   * always on.\r
+   *\r
+   * This is the equivalent of setting the local duty cycle rate.\r
+   *\r
+   * @param sleepIntervalMs the length of this node's Rx check interval, in [ms]\r
+   */\r
+  command void LowPowerListening.setLocalSleepInterval(\r
+      uint16_t sleepIntervalMs) {\r
+    call CC2420DutyCycle.setSleepInterval(sleepIntervalMs);\r
+  }\r
+  \r
+  /**\r
+   * @return the local node's sleep interval, in [ms]\r
+   */\r
+  command uint16_t LowPowerListening.getLocalSleepInterval() {\r
+    return call CC2420DutyCycle.getSleepInterval();\r
+  }\r
+  \r
+  /**\r
+   * Set this node's radio duty cycle rate, in units of [percentage*100].\r
+   * For example, to get a 0.05% duty cycle,\r
+   * <code>\r
+   *   call LowPowerListening.setDutyCycle(5);  // or equivalently...\r
+   *   call LowPowerListening.setDutyCycle(00005);  // for better readability?\r
+   * </code>\r
+   *\r
+   * For a 100% duty cycle (always on),\r
+   * <code>\r
+   *   call LowPowerListening.setDutyCycle(10000);\r
+   * </code>\r
+   *\r
+   * This is the equivalent of setting the local sleep interval explicitly.\r
+   * \r
+   * @param dutyCycle The duty cycle percentage, in units of [percentage*100]\r
+   */\r
+  command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) {\r
+    call CC2420DutyCycle.setSleepInterval(\r
+        call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));\r
+  }\r
+  \r
+  /**\r
+   * @return this node's radio duty cycle rate, in units of [percentage*100]\r
+   */\r
+  command uint16_t LowPowerListening.getLocalDutyCycle() {\r
+    return call LowPowerListening.sleepIntervalToDutyCycle(\r
+        call CC2420DutyCycle.getSleepInterval());\r
+  }\r
+  \r
+  \r
+  /**\r
+   * Configure this outgoing message so it can be transmitted to a neighbor mote\r
+   * with the specified Rx sleep interval.\r
+   * @param msg Pointer to the message that will be sent\r
+   * @param sleepInterval The receiving node's sleep interval, in [ms]\r
+   */\r
+  command void LowPowerListening.setRxSleepInterval(message_t *msg, \r
+      uint16_t sleepIntervalMs) {\r
+    getMetadata(msg)->rxInterval = sleepIntervalMs;\r
+  }\r
+  \r
+  /**\r
+   * @return the destination node's sleep interval configured in this message\r
+   */\r
+  command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) {\r
+    return getMetadata(msg)->rxInterval;\r
+  }\r
+  \r
+  /**\r
+   * Configure this outgoing message so it can be transmitted to a neighbor mote\r
+   * with the specified Rx duty cycle rate.\r
+   * Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25.\r
+   * \r
+   * @param msg Pointer to the message that will be sent\r
+   * @param dutyCycle The duty cycle of the receiving mote, in units of \r
+   *     [percentage*100]\r
+   */\r
+  command void LowPowerListening.setRxDutyCycle(message_t *msg, \r
+      uint16_t dutyCycle) {\r
+    getMetadata(msg)->rxInterval =\r
+        call LowPowerListening.dutyCycleToSleepInterval(dutyCycle);\r
+  }\r
+  \r
+    \r
+  /**\r
+   * @return the destination node's duty cycle configured in this message\r
+   *     in units of [percentage*100]\r
+   */\r
+  command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) {\r
+    return call LowPowerListening.sleepIntervalToDutyCycle(\r
+        getMetadata(msg)->rxInterval);\r
+  }\r
+  \r
+  /**\r
+   * Convert a duty cycle, in units of [percentage*100], to\r
+   * the sleep interval of the mote in milliseconds\r
+   * @param dutyCycle The duty cycle in units of [percentage*100]\r
+   * @return The equivalent sleep interval, in units of [ms]\r
+   */\r
+  command uint16_t LowPowerListening.dutyCycleToSleepInterval(\r
+      uint16_t dutyCycle) {\r
+    dutyCycle = getActualDutyCycle(dutyCycle);\r
+    \r
+    if(dutyCycle == 10000) {\r
+      return 0;\r
+    }\r
+    \r
+    return (DUTY_ON_TIME * (10000 - dutyCycle)) / dutyCycle;\r
+  }\r
+  \r
+  /**\r
+   * Convert a sleep interval, in units of [ms], to a duty cycle\r
+   * in units of [percentage*100]\r
+   * @param sleepInterval The sleep interval in units of [ms]\r
+   * @return The duty cycle in units of [percentage*100]\r
+   */\r
+  command uint16_t LowPowerListening.sleepIntervalToDutyCycle(\r
+      uint16_t sleepInterval) {\r
+    if(sleepInterval == 0) {\r
+      return 10000;\r
+    }\r
+    \r
+    return getActualDutyCycle((DUTY_ON_TIME * 10000) \r
+        / (sleepInterval + DUTY_ON_TIME));\r
+  }\r
+\r
+  \r
+  /***************** Send Commands ***************/\r
+  /**\r
+   * Each call to this send command gives the message a single\r
+   * DSN that does not change for every copy of the message\r
+   * sent out.  For messages that are not acknowledged, such as\r
+   * a broadcast address message, the receiving end does not\r
+   * signal receive() more than once for that message.\r
+   */\r
+  command error_t Send.send(message_t *msg, uint8_t len) {\r
+    if(call SplitControlState.getState() == S_OFF) {\r
+      // Everything is off right now, start SplitControl and try again\r
+      return EOFF;\r
+    }\r
+    \r
+    if(call SendState.requestState(S_SENDING) == SUCCESS) {\r
+      currentSendMsg = msg;\r
+      currentSendLen = len;\r
+      (getHeader(msg))->dsn = ++txDsn;\r
+      \r
+      // In case our off timer is running...\r
+      call OffTimer.stop();\r
+      \r
+      if(call RadioState.getState() == S_ON) {\r
+        if(call LowPowerListening.getRxSleepInterval(currentSendMsg) \r
+            > ONE_MESSAGE) {\r
+          // Send it repetitively within our transmit window\r
+          call PacketAcknowledgements.requestAck(currentSendMsg);\r
+          call SendDoneTimer.startOneShot(\r
+              call LowPowerListening.getRxSleepInterval(currentSendMsg) * 2);\r
+        }\r
+        \r
+        post send();\r
+    \r
+      } else {\r
+        post startRadio();\r
+      }\r
+      \r
+      return SUCCESS;\r
+    }\r
+    \r
+    return FAIL;\r
+  }\r
+\r
+  command error_t Send.cancel(message_t *msg) {\r
+    if(currentSendMsg == msg) {\r
+      call SendState.toIdle();\r
+      return SUCCESS;\r
+    }\r
+    \r
+    return FAIL;\r
+  }\r
+  \r
+  \r
+  command uint8_t Send.maxPayloadLength() {\r
+    return call SubSend.maxPayloadLength();\r
+  }\r
+\r
+  command void *Send.getPayload(message_t* msg) {\r
+    return call SubSend.getPayload(msg);\r
+  }\r
+  \r
+  /***************** Receive Commands ***************/\r
+  command void *Receive.getPayload(message_t* msg, uint8_t* len) {\r
+    return call SubReceive.getPayload(msg, len);\r
+  }\r
+\r
+  command uint8_t Receive.payloadLength(message_t* msg) {\r
+    return call SubReceive.payloadLength(msg);\r
+  }\r
+\r
+\r
+  /***************** DutyCycle Events ***************/\r
+  /**\r
+   * A transmitter was detected.  You must now take action to\r
+   * turn the radio off when the transaction is complete.\r
+   */\r
+  event void CC2420DutyCycle.detected() {\r
+    // At this point, the duty cycling has been disabled temporary\r
+    // and it will be this component's job to turn the radio back off\r
+   \r
+    startOffTimer();\r
+  }\r
+  \r
+  \r
+  /***************** SubControl Events ***************/\r
+  event void SubControl.startDone(error_t error) {\r
+    if(!error) {\r
+      call RadioState.forceState(S_ON);\r
+      \r
+      if(call SendState.getState() == S_SENDING) {\r
+        if(call LowPowerListening.getRxSleepInterval(currentSendMsg) \r
+            > ONE_MESSAGE) {\r
+          // Send it repetitively within our transmit window\r
+          call PacketAcknowledgements.requestAck(currentSendMsg);\r
+          call SendDoneTimer.startOneShot(\r
+              call LowPowerListening.getRxSleepInterval(currentSendMsg) * 2);\r
+        }\r
+        \r
+        post send();\r
+      }\r
+    }\r
+  }\r
+    \r
+  event void SubControl.stopDone(error_t error) {\r
+    if(!error) {\r
+      call RadioState.forceState(S_OFF);\r
+\r
+      if(call SendState.getState() == S_SENDING) {\r
+        // We're in the middle of sending a message; start the radio back up\r
+        post startRadio();\r
+      }\r
+    }\r
+  }\r
+  \r
+  /***************** SubSend Events ***************/\r
+  event void SubSend.sendDone(message_t* msg, error_t error) {\r
+    if(call SendState.getState() == S_SENDING  \r
+        && call SendDoneTimer.isRunning()) {\r
+      if(call PacketAcknowledgements.wasAcked(msg)) {\r
+        signalDone(error);\r
+        \r
+      } else {\r
+        post resend();\r
+      }\r
+      \r
+      return;\r
+    }\r
+    \r
+    signalDone(error);\r
+  }\r
+  \r
+  /***************** SubReceive Events ***************/\r
+  /**\r
+   * If the received message is new, we signal the receive event and\r
+   * start the off timer.  If the last message we received had the same\r
+   * DSN as this message, then the chances are pretty good\r
+   * that this message should be ignored, especially if the destination address\r
+   * as the broadcast address\r
+   *\r
+   * TODO\r
+   * What happens if a unicast Tx doesn't get Rx's ack, and resends that\r
+   * message?\r
+   */\r
+  event message_t *SubReceive.receive(message_t* msg, void* payload, \r
+      uint8_t len) {\r
+    \r
+    if((getHeader(msg))->dsn == lastRxDsn \r
+        && call AMPacket.destination(msg) == AM_BROADCAST_ADDR) {\r
+      // Already got this broadcast message.\r
+      // TODO should we do something similar with unicast messages?\r
+      return msg;\r
+\r
+    } else {\r
+      lastRxDsn = (getHeader(msg))->dsn;\r
+      startOffTimer();\r
+      return signal Receive.receive(msg, payload, len);\r
+    }\r
+  }\r
+  \r
+  /***************** Timer Events ****************/\r
+  event void OffTimer.fired() {\r
+    /*\r
+     * Only stop the radio if the radio is supposed to be off permanently\r
+     * or if the duty cycle is on and our sleep interval is not 0\r
+     */\r
+    if(call SplitControlState.getState() == S_OFF\r
+        || (call CC2420DutyCycle.getSleepInterval() > 0\r
+            && call SplitControlState.getState() == S_ON)) { \r
+      post stopRadio();\r
+    }\r
+  }\r
+  \r
+  /**\r
+   * When this timer is running, that means we're sending repeating messages\r
+   * to a node that is receive check duty cycling.\r
+   */\r
+  event void SendDoneTimer.fired() {\r
+    if(call SendState.getState() == S_SENDING) {\r
+      // The next time SubSend.sendDone is signaled, send is complete.\r
+      call SendState.toIdle();\r
+    }\r
+  }\r
+  \r
+  /***************** Resend Events ****************/\r
+  /**\r
+   * Signal that a message has been sent\r
+   *\r
+   * @param p_msg message to send.\r
+   * @param error notifaction of how the operation went.\r
+   */\r
+  async event void Resend.sendDone( message_t* p_msg, error_t error ) {\r
+    // This is actually caught by SubSend.sendDone\r
+  }\r
+  \r
+  \r
+  /***************** Tasks ***************/\r
+  task void send() {\r
+    if(call SubSend.send(currentSendMsg, currentSendLen) != SUCCESS) {\r
+      post send();\r
+    }\r
+  }\r
+  \r
+  task void resend() {\r
+    // Resend the last message without CCA checks.\r
+    if(call Resend.resend() != SUCCESS) {\r
+      post resend();\r
+    }\r
+  }\r
+  \r
+  task void startRadio() {\r
+    if(call SubControl.start() != SUCCESS) {\r
+      post startRadio();\r
+    }\r
+  }\r
+  \r
+  task void stopRadio() {\r
+    if(call SubControl.stop() != SUCCESS) {\r
+      post stopRadio();\r
+    }\r
+  }\r
+  \r
+  /***************** Functions ***************/\r
+  void startOffTimer() {\r
+    call OffTimer.startOneShot(DELAY_AFTER_RECEIVE);\r
+  }\r
+  \r
+  /**\r
+   * Check the bounds on a given duty cycle\r
+   * We're never over 100%, and we're never at 0%\r
+   */\r
+  uint16_t getActualDutyCycle(uint16_t dutyCycle) {\r
+    if(dutyCycle > 10000) {\r
+      return 10000;\r
+    } else if(dutyCycle == 0) {\r
+      return 1;\r
+    }\r
+    \r
+    return dutyCycle;\r
+  }\r
+  \r
+  cc2420_header_t *getHeader(message_t *msg) {\r
+    return (cc2420_header_t *)(msg->data - sizeof( cc2420_header_t ));\r
+  }\r
+  \r
+  cc2420_metadata_t *getMetadata(message_t* msg) {\r
+    return (cc2420_metadata_t*)msg->metadata;\r
+  }\r
+  \r
+  void signalDone(error_t error) {\r
+    call SendState.toIdle();\r
+    startOffTimer();\r
+    signal Send.sendDone(currentSendMsg, error);\r
+    currentSendMsg = NULL;\r
+  }\r
+}\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420LplDummyP.nc b/tos/chips/cc2420_lpl/CC2420LplDummyP.nc
new file mode 100644 (file)
index 0000000..63f5c26
--- /dev/null
@@ -0,0 +1,84 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
\r
+/**\r
+ * Dummy low power listening interface used when LowPowerListening is not\r
+ * compiled in with the application.\r
+ * Sleep interval is always 0, and duty cycle is always 100%\r
+ * @author David Moss\r
+ */\r
\r
+module CC2420LplDummyP {\r
+  provides {\r
+    interface LowPowerListening;\r
+  }\r
+}\r
+\r
+implementation {\r
+\r
+  command void LowPowerListening.setLocalSleepInterval(uint16_t sleepIntervalMs) {\r
+  }\r
+  \r
+  command uint16_t LowPowerListening.getLocalSleepInterval() {\r
+    return 0;\r
+  }\r
+  \r
+  command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) {\r
+  }\r
+  \r
+  command uint16_t LowPowerListening.getLocalDutyCycle() {\r
+    return 10000;\r
+  }\r
+  \r
+  command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) {\r
+  }\r
+  \r
+  command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) {\r
+    return 0;\r
+  }\r
+  \r
+  command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) {\r
+  }\r
+  \r
+  command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) {\r
+    return 10000;\r
+  }\r
+  \r
+  command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) {\r
+    return 0;\r
+  }\r
+  \r
+  command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) {\r
+    return 10000;\r
+  }\r
+  \r
+}\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420Packet.nc b/tos/chips/cc2420_lpl/CC2420Packet.nc
new file mode 100644 (file)
index 0000000..5eee2ae
--- /dev/null
@@ -0,0 +1,71 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+interface CC2420Packet {\r
+  \r
+  /**\r
+   * Get transmission power setting for current packet.\r
+   *\r
+   * @param the message\r
+   */\r
+  async command uint8_t getPower( message_t* p_msg );\r
+\r
+  /**\r
+   * Set transmission power for a given packet. Valid ranges are\r
+   * between 0 and 31.\r
+   *\r
+   * @param p_msg the message.\r
+   * @param power transmission power.\r
+   */\r
+  async command void setPower( message_t* p_msg, uint8_t power );\r
+  \r
+  /**\r
+   * Get rssi value for a given packet. For received packets, it is\r
+   * the received signal strength when receiving that packet. For sent\r
+   * packets, it is the received signal strength of the ack if an ack\r
+   * was received.\r
+   */\r
+  async command int8_t getRssi( message_t* p_msg );\r
+\r
+  /**\r
+   * Get lqi value for a given packet. For received packets, it is the\r
+   * link quality indicator value when receiving that packet. For sent\r
+   * packets, it is the link quality indicator value of the ack if an\r
+   * ack was received.\r
+   */\r
+  async command uint8_t getLqi( message_t* p_msg );\r
+  \r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420PacketC.nc b/tos/chips/cc2420_lpl/CC2420PacketC.nc
new file mode 100644 (file)
index 0000000..84c5ceb
--- /dev/null
@@ -0,0 +1,86 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+module CC2420PacketC {\r
+\r
+  provides interface CC2420Packet;\r
+  provides interface PacketAcknowledgements as Acks;\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  cc2420_header_t* getHeader( message_t* msg ) {\r
+    return (cc2420_header_t*)( msg->data - sizeof( cc2420_header_t ) );\r
+  }\r
+\r
+  cc2420_metadata_t* getMetadata( message_t* msg ) {\r
+    return (cc2420_metadata_t*)msg->metadata;\r
+  }\r
+\r
+  async command error_t Acks.requestAck( message_t* p_msg ) {\r
+    getHeader( p_msg )->fcf |= 1 << IEEE154_FCF_ACK_REQ;\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command error_t Acks.noAck( message_t* p_msg ) {\r
+    getHeader( p_msg )->fcf &= ~(1 << IEEE154_FCF_ACK_REQ);\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command bool Acks.wasAcked( message_t* p_msg ) {\r
+    return getMetadata( p_msg )->ack;\r
+  }\r
+\r
+  async command void CC2420Packet.setPower( message_t* p_msg, uint8_t power ) {\r
+    if ( power > 31 )\r
+      power = 31;\r
+    getMetadata( p_msg )->tx_power = power;\r
+  }\r
+\r
+  async command uint8_t CC2420Packet.getPower( message_t* p_msg ) {\r
+    return getMetadata( p_msg )->tx_power;\r
+  }\r
+   \r
+  async command int8_t CC2420Packet.getRssi( message_t* p_msg ) {\r
+    return getMetadata( p_msg )->rssi;\r
+  }\r
+\r
+  async command error_t CC2420Packet.getLqi( message_t* p_msg ) {\r
+    return getMetadata( p_msg )->lqi;\r
+  }\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420Power.nc b/tos/chips/cc2420_lpl/CC2420Power.nc
new file mode 100644 (file)
index 0000000..0fcfedf
--- /dev/null
@@ -0,0 +1,99 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * An HAL abstraction of the ChipCon CC2420 radio. This abstraction\r
+ * deals specifically with radio power operations (e.g. voltage\r
+ * regulator, oscillator, etc). However, it does not include\r
+ * transmission power, see the CC2420Config interface.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+interface CC2420Power {\r
+\r
+  /**\r
+   * Start the voltage regulator on the CC2420. On SUCCESS,\r
+   * <code>startVReg()</code> will be signalled when the voltage\r
+   * regulator is fully on.\r
+   *\r
+   * @return SUCCESS if the request was accepted, FAIL otherwise.\r
+   */\r
+  async command error_t startVReg();\r
+\r
+  /**\r
+   * Signals that the voltage regulator has been started.\r
+   */\r
+  async event void startVRegDone();\r
+  \r
+  /**\r
+   * Stop the voltage regulator immediately.\r
+   *\r
+   * @return SUCCESS always\r
+   */\r
+  async command error_t stopVReg();\r
+\r
+  /**\r
+   * Start the oscillator. On SUCCESS, <code>startOscillator</code>\r
+   * will be signalled when the oscillator has been started.\r
+   *\r
+   * @return SUCCESS if the request was accepted, FAIL otherwise.\r
+   */\r
+  async command error_t startOscillator();\r
+\r
+  /**\r
+   * Signals that the oscillator has been started.\r
+   */\r
+  async event void startOscillatorDone();\r
+\r
+  /**\r
+   * Stop the oscillator.\r
+   *\r
+   * @return SUCCESS if the oscillator was stopped, FAIL otherwise.\r
+   */\r
+  async command error_t stopOscillator();\r
+\r
+  /**\r
+   * Enable RX.\r
+   *\r
+   * @return SUCCESS if receive mode has been enabled, FAIL otherwise.\r
+   */\r
+  async command error_t rxOn();\r
+\r
+  /**\r
+   * Disable RX.\r
+   *\r
+   * @return SUCCESS if receive mode has been disabled, FAIL otherwise.\r
+   */\r
+  async command error_t rfOff();\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420Ram.nc b/tos/chips/cc2420_lpl/CC2420Ram.nc
new file mode 100644 (file)
index 0000000..fce5028
--- /dev/null
@@ -0,0 +1,65 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * HAL abstraction for accessing theRAM of a ChipCon CC2420 radio.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#include "CC2420.h"\r
+\r
+interface CC2420Ram {\r
+\r
+  /**\r
+   * Read data from a RAM. This operation is sychronous.\r
+   *\r
+   * @param offset within the field.\r
+   * @param data a pointer to the receive buffer.\r
+   * @param length number of bytes to read.\r
+   * @return status byte returned when sending the last byte\r
+   * of the SPI transaction.\r
+   */\r
+  async command cc2420_status_t read( uint8_t offset, uint8_t* data, uint8_t length );\r
+\r
+  /**\r
+   * Write data to RAM. This operation is sychronous.\r
+   *\r
+   * @param offset within the field.\r
+   * @param data a pointer to the send buffer.\r
+   * @param length number of bytes to write.\r
+   * @return status byte returned when sending the last address byte\r
+   * of the SPI transaction.\r
+   */\r
+  async command cc2420_status_t write( uint8_t offset, uint8_t* data, uint8_t length );\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420Receive.nc b/tos/chips/cc2420_lpl/CC2420Receive.nc
new file mode 100644 (file)
index 0000000..47cb15d
--- /dev/null
@@ -0,0 +1,64 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Low-level abstraction of the receive path implementation for the\r
+ * ChipCon CC2420 radio.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+interface CC2420Receive {\r
+\r
+  /**\r
+   * Notification that an SFD capture has occured.\r
+   *\r
+   * @param time at which the capture happened.\r
+   */\r
+  async command void sfd( uint16_t time );\r
+\r
+  /**\r
+   * Notification that the packet has been dropped by the radio\r
+   * (e.g. due to address rejection).\r
+   */\r
+  async command void sfd_dropped();\r
+\r
+  /**\r
+   * Signals that a message has been received.\r
+   *\r
+   * @param type of the message received.\r
+   * @param message pointer to message received.\r
+   */\r
+  async event void receive( uint8_t type, message_t* message );\r
+\r
+}\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420ReceiveC.nc b/tos/chips/cc2420_lpl/CC2420ReceiveC.nc
new file mode 100644 (file)
index 0000000..f9b1b71
--- /dev/null
@@ -0,0 +1,73 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Implementation of the receive path for the ChipCon CC2420 radio.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+configuration CC2420ReceiveC {\r
+\r
+  provides interface Init;\r
+  provides interface AsyncStdControl;\r
+  provides interface CC2420Receive;\r
+  provides interface Receive;\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  components CC2420ReceiveP;\r
+  components new CC2420SpiC() as Spi;\r
+\r
+  components HplCC2420PinsC as Pins;\r
+  components HplCC2420InterruptsC as InterruptsC;\r
+\r
+  components LedsC as Leds;\r
+  CC2420ReceiveP.Leds -> Leds;\r
+\r
+  Init = CC2420ReceiveP;\r
+  AsyncStdControl = CC2420ReceiveP;\r
+  CC2420Receive = CC2420ReceiveP;\r
+  Receive = CC2420ReceiveP;\r
+\r
+  CC2420ReceiveP.CSN -> Pins.CSN;\r
+  CC2420ReceiveP.FIFO -> Pins.FIFO;\r
+  CC2420ReceiveP.FIFOP -> Pins.FIFOP;\r
+  CC2420ReceiveP.InterruptFIFOP -> InterruptsC.InterruptFIFOP;\r
+\r
+  CC2420ReceiveP.SpiResource -> Spi;\r
+  CC2420ReceiveP.RXFIFO -> Spi.RXFIFO;\r
+  CC2420ReceiveP.SFLUSHRX -> Spi.SFLUSHRX;\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420ReceiveP.nc b/tos/chips/cc2420_lpl/CC2420ReceiveP.nc
new file mode 100644 (file)
index 0000000..f7f59aa
--- /dev/null
@@ -0,0 +1,287 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+module CC2420ReceiveP {\r
+\r
+  provides interface Init;\r
+  provides interface AsyncStdControl;\r
+  provides interface CC2420Receive;\r
+  provides interface Receive;\r
+\r
+  uses interface GeneralIO as CSN;\r
+  uses interface GeneralIO as FIFO;\r
+  uses interface GeneralIO as FIFOP;\r
+  uses interface GpioInterrupt as InterruptFIFOP;\r
+\r
+  uses interface Resource as SpiResource;\r
+  uses interface CC2420Fifo as RXFIFO;\r
+  uses interface CC2420Strobe as SACK;\r
+  uses interface CC2420Strobe as SFLUSHRX;\r
+\r
+  uses interface Leds;\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  typedef enum {\r
+    S_STOPPED,\r
+    S_STARTED,\r
+    S_RX_HEADER,\r
+    S_RX_PAYLOAD,\r
+  } cc2420_receive_state_t;\r
+\r
+  enum {\r
+    RXFIFO_SIZE = 128,\r
+    TIMESTAMP_QUEUE_SIZE = 8,\r
+  };\r
+\r
+  uint16_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];\r
+  uint8_t m_timestamp_head, m_timestamp_size;\r
+  uint8_t m_missed_packets;\r
+\r
+  bool fallingEdgeEnabled;\r
+  \r
+  norace uint8_t m_bytes_left;\r
+  norace message_t* m_p_rx_buf;\r
+\r
+  message_t m_rx_buf;\r
+  cc2420_receive_state_t m_state;\r
+\r
+  void beginReceive();\r
+  void receive();\r
+  void waitForNextPacket();\r
+  task void receiveDone_task();\r
+\r
+  cc2420_header_t* getHeader( message_t* msg ) {\r
+    return (cc2420_header_t*)( msg->data - sizeof( cc2420_header_t ) );\r
+  }\r
+  \r
+  cc2420_metadata_t* getMetadata( message_t* msg ) {\r
+    return (cc2420_metadata_t*)msg->metadata;\r
+  }\r
+  \r
+  command error_t Init.init() {\r
+    fallingEdgeEnabled = FALSE;\r
+    m_p_rx_buf = &m_rx_buf;\r
+    return SUCCESS;\r
+  }\r
+\r
+  void reset_state() {\r
+    m_bytes_left = RXFIFO_SIZE;\r
+    m_timestamp_head = m_timestamp_size = 0;\r
+    m_missed_packets = 0;\r
+  }\r
+\r
+  async command error_t AsyncStdControl.start() {\r
+    atomic {\r
+      reset_state();\r
+      m_state = S_STARTED;\r
+      \r
+      // MicaZ's don't like to re-enable the falling edge\r
+      if(!fallingEdgeEnabled) {\r
+        call InterruptFIFOP.enableFallingEdge();\r
+        fallingEdgeEnabled = TRUE;\r
+      }\r
+    }\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command error_t AsyncStdControl.stop() {\r
+    atomic {\r
+      m_state = S_STOPPED;\r
+      // MicaZ's don't like to re-enable the falling edge\r
+      //call InterruptFIFOP.disable();\r
+    }\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command void CC2420Receive.sfd( uint16_t time ) {\r
+    if ( m_timestamp_size < TIMESTAMP_QUEUE_SIZE ) {\r
+      uint8_t tail =  ( ( m_timestamp_head + m_timestamp_size ) % \r
+                       TIMESTAMP_QUEUE_SIZE );\r
+      m_timestamp_queue[ tail ] = time;\r
+      m_timestamp_size++;\r
+    }\r
+  }\r
+\r
+  async command void CC2420Receive.sfd_dropped() {\r
+    if ( m_timestamp_size )\r
+      m_timestamp_size--;\r
+  }\r
+\r
+  async event void InterruptFIFOP.fired() {\r
+    if ( m_state == S_STARTED )\r
+      beginReceive();\r
+    else\r
+      m_missed_packets++;\r
+  }\r
+  \r
+  void beginReceive() { \r
+    m_state = S_RX_HEADER;\r
+    if ( call SpiResource.immediateRequest() == SUCCESS )\r
+      receive();\r
+    else\r
+      call SpiResource.request();\r
+  }\r
+  \r
+  event void SpiResource.granted() {\r
+    receive();\r
+  }\r
+\r
+  void receive() {\r
+    call CSN.clr();\r
+    call RXFIFO.beginRead( (uint8_t*)getHeader( m_p_rx_buf ), 1 );\r
+  }\r
+\r
+  async event void RXFIFO.readDone( uint8_t* rx_buf, uint8_t rx_len,\r
+                                   error_t error ) {\r
+\r
+    cc2420_header_t* header = getHeader( m_p_rx_buf );\r
+    cc2420_metadata_t* metadata = getMetadata( m_p_rx_buf );\r
+    uint8_t* buf = (uint8_t*)header;\r
+    uint8_t length = buf[ 0 ];\r
+\r
+    switch( m_state ) {\r
+\r
+    case S_RX_HEADER:\r
+      m_state = S_RX_PAYLOAD;\r
+      if ( length + 1 > m_bytes_left ) {\r
+       reset_state();\r
+       call CSN.set();\r
+       call CSN.clr();\r
+       call SFLUSHRX.strobe();\r
+       call SFLUSHRX.strobe();\r
+       call CSN.set();\r
+       call SpiResource.release();\r
+       waitForNextPacket();\r
+      }\r
+      else {\r
+       if ( !call FIFO.get() && !call FIFOP.get() )\r
+         m_bytes_left -= length + 1;\r
+       call RXFIFO.continueRead( (length <= MAC_PACKET_SIZE) ? buf + 1 : NULL,\r
+                                 length );\r
+      }\r
+      break;\r
+      \r
+    case S_RX_PAYLOAD:\r
+      \r
+      call CSN.set();\r
+      call SpiResource.release();\r
+      \r
+      if ( m_timestamp_size ) {\r
+       if ( length > 10 ) {\r
+         metadata->time = m_timestamp_queue[ m_timestamp_head ];\r
+         m_timestamp_head = ( m_timestamp_head + 1 ) % TIMESTAMP_QUEUE_SIZE;\r
+         m_timestamp_size--;\r
+       }\r
+      }\r
+      else {\r
+       metadata->time = 0xffff;\r
+      }\r
+      \r
+      // pass packet up if crc is good\r
+      if ( ( buf[ length ] >> 7 ) && rx_buf ) {\r
+       uint8_t type = ( header->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7;\r
+       signal CC2420Receive.receive( type, m_p_rx_buf );\r
+       if ( type == IEEE154_TYPE_DATA ) {\r
+         post receiveDone_task();\r
+         return;\r
+       }\r
+      }\r
+      \r
+      waitForNextPacket();\r
+      break;\r
+\r
+    default:\r
+      call CSN.set();\r
+      call SpiResource.release();\r
+      break;\r
+      \r
+    }\r
+    \r
+  }\r
+\r
+  task void receiveDone_task() {\r
+    \r
+    cc2420_header_t* header = getHeader( m_p_rx_buf );\r
+    cc2420_metadata_t* metadata = getMetadata( m_p_rx_buf );\r
+    uint8_t* buf = (uint8_t*)header;\r
+    uint8_t length = buf[ 0 ];\r
+    \r
+    metadata->crc = buf[ length ] >> 7;\r
+    metadata->rssi = buf[ length - 1 ];\r
+    metadata->lqi = buf[ length ] & 0x7f;\r
+    m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data, \r
+                                        length );\r
+\r
+    waitForNextPacket();\r
+\r
+  }\r
+\r
+  void waitForNextPacket() {\r
+\r
+    atomic {\r
+      if ( m_state == S_STOPPED )\r
+       return;\r
+\r
+      if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get() ) {\r
+       if ( m_missed_packets )\r
+         m_missed_packets--;\r
+       beginReceive();\r
+      }\r
+      else {\r
+       m_state = S_STARTED;\r
+       m_missed_packets = 0;\r
+      }\r
+    }      \r
+    \r
+  }\r
+\r
+  command void* Receive.getPayload(message_t* m, uint8_t* len) {\r
+    if (len != NULL) {\r
+      *len = TOSH_DATA_LENGTH;\r
+    }\r
+    return m->data;\r
+  }\r
+\r
+  command uint8_t Receive.payloadLength(message_t* m) {\r
+    uint8_t* buf = (uint8_t*)getHeader( m_p_rx_buf );\r
+    return buf[0];\r
+  }\r
+\r
+  async event void RXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {}  \r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420Register.nc b/tos/chips/cc2420_lpl/CC2420Register.nc
new file mode 100644 (file)
index 0000000..5a95aee
--- /dev/null
@@ -0,0 +1,57 @@
+/*                                                                     tab:4\r
+ * "Copyright (c) 2005 Stanford University. All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and\r
+ * its documentation for any purpose, without fee, and without written\r
+ * agreement is hereby granted, provided that the above copyright\r
+ * notice, the following two paragraphs and the author appear in all\r
+ * copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\r
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN\r
+ * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ * \r
+ * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE\r
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY\r
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,\r
+ * ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ */\r
+\r
+/**\r
+ * Interface representing one of the Read/Write registers on the\r
+ * CC2420 radio. The return values (when appropriate) refer to the\r
+ * status byte returned on the CC2420 SO pin. A full list of RW\r
+ * registers can be found on page 61 of the CC2420 datasheet (rev\r
+ * 1.2). Page 25 of the same document describes the protocol for\r
+ * interacting with these registers over the CC2420 SPI bus.\r
+ *\r
+ * @author Philip Levis\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#include "CC2420.h"\r
+\r
+interface CC2420Register {\r
+\r
+  /**\r
+   * Read a 16-bit data word from the register.\r
+   *\r
+   * @param data pointer to place the register value.\r
+   * @return status byte from the read.\r
+   */\r
+  async command cc2420_status_t read(uint16_t* data);\r
+\r
+  /**\r
+   * Write a 16-bit data word to the register.\r
+   * \r
+   * @param data value to write to register.\r
+   * @return status byte from the write.\r
+   */\r
+  async command cc2420_status_t write(uint16_t data);\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420SpiC.nc b/tos/chips/cc2420_lpl/CC2420SpiC.nc
new file mode 100644 (file)
index 0000000..7e35a93
--- /dev/null
@@ -0,0 +1,115 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Implementation of basic SPI primitives for the ChipCon CC2420 radio.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+generic configuration CC2420SpiC() {\r
+\r
+  provides interface Resource;\r
+\r
+  // commands\r
+  provides interface CC2420Strobe as SFLUSHRX;\r
+  provides interface CC2420Strobe as SFLUSHTX;\r
+  provides interface CC2420Strobe as SNOP;\r
+  provides interface CC2420Strobe as SRXON;\r
+  provides interface CC2420Strobe as SRFOFF;\r
+  provides interface CC2420Strobe as STXON;\r
+  provides interface CC2420Strobe as STXONCCA;\r
+  provides interface CC2420Strobe as SXOSCON;\r
+  provides interface CC2420Strobe as SXOSCOFF;\r
+\r
+  // registers\r
+  provides interface CC2420Register as FSCTRL;\r
+  provides interface CC2420Register as IOCFG0;\r
+  provides interface CC2420Register as IOCFG1;\r
+  provides interface CC2420Register as MDMCTRL0;\r
+  provides interface CC2420Register as MDMCTRL1;\r
+  provides interface CC2420Register as TXCTRL;\r
+\r
+  // ram\r
+  provides interface CC2420Ram as IEEEADR;\r
+  provides interface CC2420Ram as PANID;\r
+  provides interface CC2420Ram as SHORTADR;\r
+  provides interface CC2420Ram as TXFIFO_RAM;\r
+\r
+  // fifos\r
+  provides interface CC2420Fifo as RXFIFO;\r
+  provides interface CC2420Fifo as TXFIFO;\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  enum {\r
+    CLIENT_ID = unique( "CC2420Spi.Resource" ),\r
+  };\r
+\r
+  components HplCC2420PinsC as Pins;\r
+  components CC2420SpiP as Spi;\r
+  \r
+  Resource = Spi.Resource[ CLIENT_ID ];\r
+\r
+  // commands\r
+  SFLUSHRX = Spi.Strobe[ CC2420_SFLUSHRX ];\r
+  SFLUSHTX = Spi.Strobe[ CC2420_SFLUSHTX ];\r
+  SNOP = Spi.Strobe[ CC2420_SNOP ];\r
+  SRXON = Spi.Strobe[ CC2420_SRXON ];\r
+  SRFOFF = Spi.Strobe[ CC2420_SRFOFF ];\r
+  STXON = Spi.Strobe[ CC2420_STXON ];\r
+  STXONCCA = Spi.Strobe[ CC2420_STXONCCA ];\r
+  SXOSCON = Spi.Strobe[ CC2420_SXOSCON ];\r
+  SXOSCOFF = Spi.Strobe[ CC2420_SXOSCOFF ];\r
+\r
+  // registers\r
+  FSCTRL = Spi.Reg[ CC2420_FSCTRL ];\r
+  IOCFG0 = Spi.Reg[ CC2420_IOCFG0 ];\r
+  IOCFG1 = Spi.Reg[ CC2420_IOCFG1 ];\r
+  MDMCTRL0 = Spi.Reg[ CC2420_MDMCTRL0 ];\r
+  MDMCTRL1 = Spi.Reg[ CC2420_MDMCTRL1 ];\r
+  TXCTRL = Spi.Reg[ CC2420_TXCTRL ];\r
+\r
+  // ram\r
+  IEEEADR = Spi.Ram[ CC2420_RAM_IEEEADR ];\r
+  PANID = Spi.Ram[ CC2420_RAM_PANID ];\r
+  SHORTADR = Spi.Ram[ CC2420_RAM_SHORTADR ];\r
+  TXFIFO_RAM = Spi.Ram[ CC2420_RAM_TXFIFO ];\r
+\r
+  // fifos\r
+  RXFIFO = Spi.Fifo[ CC2420_RXFIFO ];\r
+  TXFIFO = Spi.Fifo[ CC2420_TXFIFO ];\r
+\r
+}\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420SpiImplP.nc b/tos/chips/cc2420_lpl/CC2420SpiImplP.nc
new file mode 100644 (file)
index 0000000..75adec4
--- /dev/null
@@ -0,0 +1,233 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+module CC2420SpiImplP {\r
+\r
+  provides interface Resource[ uint8_t id ];\r
+  provides interface CC2420Fifo as Fifo[ uint8_t id ];\r
+  provides interface CC2420Ram as Ram[ uint16_t id ];\r
+  provides interface CC2420Register as Reg[ uint8_t id ];\r
+  provides interface CC2420Strobe as Strobe[ uint8_t id ];\r
+\r
+  uses interface Resource as SpiResource;\r
+  uses interface SpiByte;\r
+  uses interface SpiPacket;\r
+  uses interface Leds;\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  enum {\r
+    RESOURCE_COUNT = uniqueCount( "CC2420Spi.Resource" ),\r
+    NO_HOLDER = 0xff,\r
+  };\r
+\r
+  norace uint16_t m_addr;\r
+  bool m_resource_busy = FALSE;\r
+  uint8_t m_requests = 0;\r
+  uint8_t m_holder = NO_HOLDER;\r
+\r
+  default event void Resource.granted[ uint8_t id ]() {\r
+  }\r
+\r
+  async command error_t Resource.request[ uint8_t id ]() {\r
+    atomic {\r
+      if ( m_resource_busy )\r
+       m_requests |= 1 << id;\r
+      else {\r
+       m_holder = id;\r
+       m_resource_busy = TRUE;\r
+       call SpiResource.request();\r
+      }\r
+    }\r
+    return SUCCESS;\r
+  }\r
+  \r
+  async command error_t Resource.immediateRequest[ uint8_t id ]() {\r
+    error_t error;\r
+    atomic {\r
+      if ( m_resource_busy )\r
+       return EBUSY;\r
+      error = call SpiResource.immediateRequest();\r
+      if ( error == SUCCESS ) {\r
+       m_holder = id;\r
+       m_resource_busy = TRUE;\r
+      }\r
+    }\r
+    return error;\r
+  }\r
+\r
+  async command error_t Resource.release[ uint8_t id ]() {\r
+    uint8_t i;\r
+    atomic {\r
+      if ( m_holder != id )\r
+       return FAIL;\r
+      m_holder = NO_HOLDER;\r
+      call SpiResource.release();\r
+      if ( !m_requests ) {\r
+       m_resource_busy = FALSE;\r
+      }\r
+      else {\r
+       for ( i = m_holder + 1; ; i++ ) {\r
+         if ( i >= RESOURCE_COUNT )\r
+           i = 0;\r
+         if ( m_requests & ( 1 << i ) ) {\r
+           m_holder = i;\r
+           m_requests &= ~( 1 << i );\r
+           call SpiResource.request();\r
+           return SUCCESS;\r
+         }\r
+       }\r
+      }\r
+      return SUCCESS;\r
+    }\r
+  }\r
+  \r
+  async command uint8_t Resource.isOwner[ uint8_t id ]() {\r
+    atomic return m_holder == id;\r
+  }\r
+\r
+  event void SpiResource.granted() {\r
+    uint8_t holder;\r
+    atomic holder = m_holder;\r
+    signal Resource.granted[ holder ]();\r
+  }\r
+\r
+  async command cc2420_status_t Fifo.beginRead[ uint8_t addr ]( uint8_t* data, \r
+                                                               uint8_t len ) {\r
+    \r
+    cc2420_status_t status;\r
+    \r
+    m_addr = addr | 0x40;\r
+    \r
+    status = call SpiByte.write( m_addr );\r
+    call Fifo.continueRead[ addr ]( data, len );\r
+    \r
+    return status;\r
+    \r
+  }\r
+\r
+  async command error_t Fifo.continueRead[ uint8_t addr ]( uint8_t* data,\r
+                                                          uint8_t len ) {\r
+    call SpiPacket.send( NULL, data, len );\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command cc2420_status_t Fifo.write[ uint8_t addr ]( uint8_t* data, \r
+                                                           uint8_t len ) {\r
+\r
+    uint8_t status;\r
+\r
+    m_addr = addr;\r
+\r
+    status = call SpiByte.write( m_addr );\r
+    call SpiPacket.send( data, NULL, len );\r
+\r
+    return status;\r
+\r
+  }\r
+\r
+  async command cc2420_status_t Ram.read[ uint16_t addr ]( uint8_t offset,\r
+                                                          uint8_t* data, \r
+                                                          uint8_t len ) {\r
+\r
+    cc2420_status_t status;\r
+\r
+    addr += offset;\r
+\r
+    call SpiByte.write( addr | 0x80 );\r
+    status = call SpiByte.write( ( ( addr >> 1 ) & 0xc0 ) | 0x20 );\r
+    for ( ; len; len-- )\r
+      *data++ = call SpiByte.write( 0 );\r
+\r
+    return status;\r
+\r
+  }\r
+\r
+  async event void SpiPacket.sendDone( uint8_t* tx_buf, uint8_t* rx_buf, \r
+                                      uint16_t len, error_t error ) {\r
+    if ( m_addr & 0x40 )\r
+      signal Fifo.readDone[ m_addr & ~0x40 ]( rx_buf, len, error );\r
+    else\r
+      signal Fifo.writeDone[ m_addr ]( tx_buf, len, error );\r
+  }\r
+\r
+  async command cc2420_status_t Ram.write[ uint16_t addr ]( uint8_t offset,\r
+                                                           uint8_t* data, \r
+                                                           uint8_t len ) {\r
+\r
+    cc2420_status_t status = 0;\r
+\r
+    addr += offset;\r
+\r
+    call SpiByte.write( addr | 0x80 );\r
+    call SpiByte.write( ( addr >> 1 ) & 0xc0 );\r
+    for ( ; len; len-- )\r
+      status = call SpiByte.write( *data++ );\r
+\r
+    return status;\r
+\r
+  }\r
+\r
+  async command cc2420_status_t Reg.read[ uint8_t addr ]( uint16_t* data ) {\r
+\r
+    cc2420_status_t status;\r
+    \r
+    status = call SpiByte.write( addr | 0x40 );\r
+    *data = (uint16_t)call SpiByte.write( 0 ) << 8;\r
+    *data |= call SpiByte.write( 0 );\r
+    \r
+    return status;\r
+\r
+  }\r
+\r
+  async command cc2420_status_t Reg.write[ uint8_t addr ]( uint16_t data ) {\r
+\r
+    call SpiByte.write( addr );\r
+    call SpiByte.write( data >> 8 );\r
+    return call SpiByte.write( data & 0xff );\r
+\r
+  }\r
+\r
+  async command cc2420_status_t Strobe.strobe[ uint8_t addr ]() {\r
+    return call SpiByte.write( addr );\r
+  }\r
+\r
+  default async event void Fifo.readDone[ uint8_t addr ]( uint8_t* rx_buf, uint8_t rx_len, error_t error ) {}\r
+  default async event void Fifo.writeDone[ uint8_t addr ]( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {}\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420SpiP.nc b/tos/chips/cc2420_lpl/CC2420SpiP.nc
new file mode 100644 (file)
index 0000000..dd7d4d4
--- /dev/null
@@ -0,0 +1,64 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+configuration CC2420SpiP {\r
+\r
+  provides interface Resource[ uint8_t id ];\r
+  provides interface CC2420Fifo as Fifo[ uint8_t id ];\r
+  provides interface CC2420Ram as Ram[ uint16_t id ];\r
+  provides interface CC2420Register as Reg[ uint8_t id ];\r
+  provides interface CC2420Strobe as Strobe[ uint8_t id ];\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  components CC2420SpiImplP as SpiP;\r
+  Resource = SpiP;\r
+  Fifo = SpiP;\r
+  Ram = SpiP;\r
+  Reg = SpiP;\r
+  Strobe = SpiP;\r
+\r
+  components new HplCC2420SpiC();\r
+  SpiP.SpiResource -> HplCC2420SpiC;\r
+  SpiP.SpiByte -> HplCC2420SpiC;\r
+  SpiP.SpiPacket -> HplCC2420SpiC;\r
+\r
+  components LedsC;\r
+  SpiP.Leds -> LedsC;\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420Strobe.nc b/tos/chips/cc2420_lpl/CC2420Strobe.nc
new file mode 100644 (file)
index 0000000..ae7ae75
--- /dev/null
@@ -0,0 +1,47 @@
+/*                                                                     tab:4\r
+ * "Copyright (c) 2005 Stanford University. All rights reserved.\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software and\r
+ * its documentation for any purpose, without fee, and without written\r
+ * agreement is hereby granted, provided that the above copyright\r
+ * notice, the following two paragraphs and the author appear in all\r
+ * copies of this software.\r
+ * \r
+ * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR\r
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\r
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN\r
+ * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ * \r
+ * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE\r
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY\r
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,\r
+ * ENHANCEMENTS, OR MODIFICATIONS."\r
+ *\r
+ */\r
+\r
+/**\r
+ * Interface representing one of the CC2420 command strobe registers.\r
+ * Writing to one of these registers enacts a command on the CC2420,\r
+ * such as power-up, transmission, or clear a FIFO.\r
+ *\r
+ * @author Philip Levis\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#include "CC2420.h"\r
+\r
+interface CC2420Strobe {\r
+\r
+  /**\r
+   * Send a command strobe to the register. The return value is the\r
+   * CC2420 status register. Table 5 on page 27 of the CC2420\r
+   * datasheet (v1.2) describes the contents of this register.\r
+   * \r
+   * @return Status byte from the CC2420.\r
+   */\r
+  async command cc2420_status_t strobe();\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420Transmit.nc b/tos/chips/cc2420_lpl/CC2420Transmit.nc
new file mode 100644 (file)
index 0000000..0f887b2
--- /dev/null
@@ -0,0 +1,99 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Low-level abstraction for the transmit path implementaiton of the\r
+ * ChipCon CC2420 radio.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+interface CC2420Transmit {\r
+\r
+  /**\r
+   * Send a message with CCA enabled.\r
+   *\r
+   * @param p_msg message to send.\r
+   * @return SUCCESS if the request was accepted, FAIL otherwise.\r
+   */\r
+  async command error_t sendCCA( message_t* p_msg );\r
+\r
+  /**\r
+   * Send a message with CCA disabled.\r
+   *\r
+   * @param p_msg message to send.\r
+   * @return SUCCESS if the request was accepted, FAIL otherwise.\r
+   */\r
+  async command error_t send( message_t* p_msg );\r
+\r
+  /**\r
+   * Send the previous message again with CCA enabled.\r
+   *\r
+   * @return SUCCESS if the request was accepted, FAIL otherwise.\r
+   */\r
+  async command error_t resendCCA();\r
+\r
+  /**\r
+   * Send the previous message again with CCA disabled.\r
+   *\r
+   * @return SUCCESS if the request was accepted, FAIL otherwise.\r
+   */\r
+  async command error_t resend();\r
+\r
+  /**\r
+   * Cancel sending of the message.\r
+   *\r
+   * @return SUCCESS if the request was accepted, FAIL otherwise.\r
+   */\r
+  async command error_t cancel();\r
+\r
+  /**\r
+   * Signal that a message has been sent\r
+   *\r
+   * @param p_msg message to send.\r
+   * @param error notifaction of how the operation went.\r
+   */\r
+  async event void sendDone( message_t* p_msg, error_t error );\r
+\r
+  /**\r
+   * Modify the contents of a packet. This command can only be used\r
+   * when an SFD capture event for the sending packet is signalled.\r
+   *\r
+   * @param offset in the message to start modifying.\r
+   * @param buf to data to write\r
+   * @param len of bytes to write\r
+   * @return SUCCESS if the request was accepted, FAIL otherwise.\r
+   */\r
+  async command error_t modify( uint8_t offset, uint8_t* buf, uint8_t len );\r
+\r
+}\r
+\r
diff --git a/tos/chips/cc2420_lpl/CC2420TransmitC.nc b/tos/chips/cc2420_lpl/CC2420TransmitC.nc
new file mode 100644 (file)
index 0000000..442d282
--- /dev/null
@@ -0,0 +1,96 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * Implementation of the transmit path for the ChipCon CC2420 radio.\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#include "IEEE802154.h"\r
+\r
+configuration CC2420TransmitC {\r
+\r
+  provides {\r
+    interface Init;\r
+    interface AsyncStdControl;\r
+    interface CC2420Transmit;\r
+    interface CsmaBackoff;\r
+    interface RadioTimeStamping;\r
+    interface CC2420Cca;\r
+  }\r
+}\r
+\r
+implementation {\r
+\r
+  components CC2420TransmitP;\r
+  Init = Alarm;\r
+  Init = CC2420TransmitP;\r
+  AsyncStdControl = CC2420TransmitP;\r
+  CC2420Transmit = CC2420TransmitP;\r
+  CsmaBackoff = CC2420TransmitP;\r
+  RadioTimeStamping = CC2420TransmitP;\r
+  CC2420Cca = CC2420TransmitP;\r
+\r
+  components AlarmMultiplexC as Alarm;\r
+  CC2420TransmitP.BackoffTimer -> Alarm;\r
+\r
+#ifdef PLATFORM_MICAZ\r
+  components new TimerMilliC() as WatchdogTimerC;\r
+  CC2420TransmitP.WatchdogTimer -> WatchdogTimerC;\r
+#endif\r
+\r
+  components HplCC2420PinsC as Pins;\r
+  CC2420TransmitP.CCA -> Pins.CCA;\r
+  CC2420TransmitP.CSN -> Pins.CSN;\r
+  CC2420TransmitP.SFD -> Pins.SFD;\r
+\r
+  components HplCC2420InterruptsC as Interrupts;\r
+  CC2420TransmitP.CaptureSFD -> Interrupts.CaptureSFD;\r
+\r
+  components new CC2420SpiC() as Spi;\r
+  CC2420TransmitP.SpiResource -> Spi;\r
+  CC2420TransmitP.SNOP        -> Spi.SNOP;\r
+  CC2420TransmitP.STXON       -> Spi.STXON;\r
+  CC2420TransmitP.STXONCCA    -> Spi.STXONCCA;\r
+  CC2420TransmitP.SFLUSHTX    -> Spi.SFLUSHTX;\r
+  CC2420TransmitP.TXCTRL      -> Spi.TXCTRL;\r
+  CC2420TransmitP.TXFIFO      -> Spi.TXFIFO;\r
+  CC2420TransmitP.TXFIFO_RAM  -> Spi.TXFIFO_RAM;\r
+\r
+  components CC2420ReceiveC;\r
+  CC2420TransmitP.CC2420Receive -> CC2420ReceiveC;\r
+\r
+  components LedsC as Leds;\r
+  CC2420TransmitP.Leds -> Leds;\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/CC2420TransmitP.nc b/tos/chips/cc2420_lpl/CC2420TransmitP.nc
new file mode 100644 (file)
index 0000000..9aa7c13
--- /dev/null
@@ -0,0 +1,575 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
\r
+#include "IEEE802154.h"\r
+\r
+module CC2420TransmitP {\r
+\r
+  provides interface Init;\r
+  provides interface AsyncStdControl;\r
+  provides interface CC2420Transmit as Send;\r
+  provides interface CsmaBackoff;\r
+  provides interface RadioTimeStamping as TimeStamp;\r
+  provides interface CC2420Cca;\r
+  \r
+  uses interface Alarm<T32khz,uint32_t> as BackoffTimer;\r
+\r
+#ifdef PLATFORM_MICAZ\r
+  uses interface Timer<TMilli> as WatchdogTimer;\r
+#endif\r
+\r
+  uses interface GpioCapture as CaptureSFD;\r
+  uses interface GeneralIO as CCA;\r
+  uses interface GeneralIO as CSN;\r
+  uses interface GeneralIO as SFD;\r
+\r
+  uses interface Resource as SpiResource;\r
+  uses interface CC2420Fifo as TXFIFO;\r
+  uses interface CC2420Ram as TXFIFO_RAM;\r
+  uses interface CC2420Register as TXCTRL;\r
+  uses interface CC2420Strobe as SNOP;\r
+  uses interface CC2420Strobe as STXON;\r
+  uses interface CC2420Strobe as STXONCCA;\r
+  uses interface CC2420Strobe as SFLUSHTX;\r
+\r
+  uses interface CC2420Receive;\r
+  uses interface Leds;\r
+\r
+}\r
+\r
+implementation {\r
+\r
+  typedef enum {\r
+    S_STOPPED,\r
+    S_STARTED,\r
+    S_LOAD,\r
+    S_SAMPLE_CCA,\r
+    S_SAMPLE_CCA_ONLY,\r
+    S_BEGIN_TRANSMIT,\r
+    S_SFD,\r
+    S_EFD,\r
+    S_ACK_WAIT,\r
+    S_CANCEL,\r
+  } cc2420_transmit_state_t;\r
+\r
+  // This specifies how many jiffies the stack should wait after a\r
+  // TXACTIVE to receive an SFD interrupt before assuming something is\r
+  // wrong and aborting the send. There seems to be a condition\r
+  // on the micaZ where the SFD interrupt is never handled.\r
+  enum {\r
+    CC2420_ABORT_PERIOD = 320\r
+  };\r
+  \r
+  norace message_t* m_msg;\r
+  \r
+  norace bool m_cca;\r
+  \r
+  norace uint8_t m_tx_power;\r
+  \r
+  cc2420_transmit_state_t m_state = S_STOPPED;\r
+  \r
+  bool m_receiving = FALSE;\r
+  \r
+  uint16_t m_prev_time;\r
+\r
+\r
+  /***************** Prototypes ****************/\r
+  void loadTXFIFO();\r
+  void attemptSend();\r
+  cc2420_header_t* getHeader( message_t* msg );\r
+  cc2420_metadata_t* getMetadata( message_t* msg );\r
+  void startBackoffTimer(uint16_t time);\r
+  void stopBackoffTimer();\r
+  error_t acquireSpiResource();\r
+  void releaseSpiResource();\r
+  void signalDone(error_t err);\r
+  void congestionBackoff();\r
+  error_t send( message_t* p_msg, bool cca );\r
+  error_t resend( bool cca );\r
+  \r
+#ifdef PLATFORM_MICAZ\r
+  task void startWatchdogTimer();\r
+  task void stopWatchdogTimer();\r
+#endif\r
+\r
+\r
+  /***************** Init Commands ****************/\r
+  command error_t Init.init() {\r
+    call CCA.makeInput();\r
+    call CSN.makeOutput();\r
+    call SFD.makeInput();\r
+    return SUCCESS;\r
+  }\r
+\r
+  /***************** AsyncStdControl Commands ****************/\r
+  async command error_t AsyncStdControl.start() {\r
+    atomic {\r
+      call CaptureSFD.captureRisingEdge();\r
+      m_state = S_STARTED;\r
+      m_receiving = FALSE;\r
+      m_tx_power = 0;\r
+    }\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command error_t AsyncStdControl.stop() {\r
+    atomic {\r
+      m_state = S_STOPPED;\r
+      stopBackoffTimer();\r
+      call CaptureSFD.disable();\r
+    }\r
+    return SUCCESS;\r
+  }\r
+\r
+  /***************** Send Commands ****************/\r
+  async command error_t Send.sendCCA( message_t* p_msg ) {\r
+    return send( p_msg, TRUE );\r
+  }\r
+\r
+  async command error_t Send.send( message_t* p_msg ) {\r
+    return send( p_msg, FALSE );\r
+  }\r
+\r
+  async command error_t Send.resendCCA() {\r
+    return resend( TRUE );\r
+  }\r
+\r
+  async command error_t Send.resend() {\r
+    return resend( FALSE );\r
+  }\r
+\r
+  async command error_t Send.cancel() {\r
+    stopBackoffTimer();\r
+\r
+    atomic {\r
+      switch( m_state ) {\r
+      case S_LOAD:\r
+        m_state = S_CANCEL;\r
+        break;\r
+        \r
+      case S_SAMPLE_CCA: \r
+      case S_BEGIN_TRANSMIT:\r
+        m_state = S_STARTED;\r
+        break;\r
+      \r
+      default:\r
+        // cancel not allowed while radio is busy transmitting\r
+        return FAIL;\r
+      }\r
+    }\r
+\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command error_t Send.modify( uint8_t offset, uint8_t* buf, \r
+                                     uint8_t len ) {\r
+    call CSN.clr();\r
+    call TXFIFO_RAM.write( offset, buf, len );\r
+    call CSN.set();\r
+    return SUCCESS;\r
+  }\r
+\r
+  /***************** CC2420Cca Commands ****************/\r
+  /**\r
+   * @return TRUE if the CCA pin shows a clear channel\r
+   */\r
+  command bool CC2420Cca.isChannelClear() {\r
+    return call CCA.get();\r
+  }\r
+  \r
+  /***************** CaptureSFD Events ****************/\r
+  async event void CaptureSFD.captured( uint16_t time ) {\r
+\r
+    atomic {\r
+      switch( m_state ) {\r
+        \r
+      case S_SFD:\r
+        call CaptureSFD.captureFallingEdge();\r
+        signal TimeStamp.transmittedSFD( time, m_msg );\r
+        releaseSpiResource();\r
+        stopBackoffTimer();\r
+        m_state = S_EFD;\r
+        if ( ( ( getHeader( m_msg )->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7 ) == \r
+             IEEE154_TYPE_DATA )\r
+          getMetadata( m_msg )->time = time;\r
+        if ( call SFD.get() )\r
+          break;\r
+        \r
+      case S_EFD:\r
+        call CaptureSFD.captureRisingEdge();\r
+        if ( getHeader( m_msg )->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) {\r
+          m_state = S_ACK_WAIT;\r
+          startBackoffTimer( CC2420_ACK_WAIT_DELAY );\r
+        }\r
+        else {\r
+          signalDone(SUCCESS);\r
+        }\r
+        if ( !call SFD.get() )\r
+          break;\r
+        \r
+      default:\r
+        if ( !m_receiving ) {\r
+          call CaptureSFD.captureFallingEdge();\r
+          signal TimeStamp.receivedSFD( time );\r
+          call CC2420Receive.sfd( time );\r
+          m_receiving = TRUE;\r
+          m_prev_time = time;\r
+          if ( call SFD.get() )\r
+            return;\r
+        }\r
+        if ( m_receiving ) {\r
+          call CaptureSFD.captureRisingEdge();\r
+          m_receiving = FALSE;\r
+          if ( time - m_prev_time < 10 )\r
+            call CC2420Receive.sfd_dropped();\r
+        }\r
+        break;\r
+      \r
+      }\r
+    }\r
+  }\r
+\r
+  /***************** CC2420Receive Events ****************/\r
+  async event void CC2420Receive.receive( uint8_t type, message_t* ack_msg ) {\r
+\r
+    if ( type == IEEE154_TYPE_ACK ) {\r
+      cc2420_header_t* ack_header = getHeader( ack_msg );\r
+      cc2420_header_t* msg_header = getHeader( m_msg );\r
+      cc2420_metadata_t* msg_metadata = getMetadata( m_msg );\r
+      uint8_t* ack_buf = (uint8_t*)ack_header;\r
+      uint8_t length = ack_header->length;\r
+      \r
+      if ( m_state == S_ACK_WAIT &&\r
+           msg_header->dsn == ack_header->dsn ) {\r
+        stopBackoffTimer();\r
+        msg_metadata->ack = TRUE;\r
+        msg_metadata->rssi = ack_buf[ length - 1 ];\r
+        msg_metadata->lqi = ack_buf[ length ] & 0x7f;\r
+        signalDone(SUCCESS);\r
+      }\r
+    }\r
+  }\r
+\r
+  /***************** SpiResource Events ****************/\r
+  event void SpiResource.granted() {\r
+    uint8_t cur_state;\r
+\r
+    atomic {\r
+      cur_state = m_state;\r
+    }\r
+\r
+    switch( cur_state ) {\r
+      case S_LOAD: \r
+        loadTXFIFO(); \r
+        break;\r
+      \r
+      case S_BEGIN_TRANSMIT: \r
+        attemptSend(); \r
+        break;\r
+      \r
+      default: \r
+        releaseSpiResource(); \r
+        break;\r
+    }\r
+  }\r
+\r
+  /***************** TXFIFO Events ****************/\r
+  async event void TXFIFO.readDone( uint8_t* tx_buf, uint8_t tx_len, \r
+      error_t error ) {\r
+  }\r
+\r
+\r
+  async event void TXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len,\r
+                                     error_t error ) {\r
+    call CSN.set();\r
+\r
+    if ( m_state == S_CANCEL ) {\r
+      m_state = S_STARTED;\r
+    }\r
+    else if ( !m_cca ) {\r
+      m_state = S_BEGIN_TRANSMIT;\r
+      attemptSend();\r
+    }\r
+    else {\r
+      releaseSpiResource();\r
+      m_state = S_SAMPLE_CCA;\r
+      startBackoffTimer( signal CsmaBackoff.initial( m_msg ) + 1);\r
+    }\r
+  }\r
+  \r
+  /***************** Timer Events ****************/\r
+  async event void BackoffTimer.fired() {\r
+\r
+    atomic {\r
+      switch( m_state ) {        \r
+      case S_SAMPLE_CCA :\r
+        // sample CCA and wait a little longer if free, just in case we\r
+        // sampled during the ack turn-around window\r
+        if ( call CCA.get() ) {\r
+          m_state = S_BEGIN_TRANSMIT;\r
+          startBackoffTimer( CC2420_TIME_ACK_TURNAROUND );\r
+        }\r
+        else {\r
+          congestionBackoff();\r
+        }\r
+        break;\r
+        \r
+      case S_BEGIN_TRANSMIT :\r
+        if ( acquireSpiResource() == SUCCESS )\r
+          attemptSend();\r
+        break;\r
+        \r
+      case S_ACK_WAIT :\r
+        signalDone( SUCCESS );\r
+        break;\r
+        \r
+#ifdef PLATFORM_MICAZ\r
+      case S_SFD:\r
+        // We didn't receive an SFD interrupt within CC2420_ABORT_PERIOD\r
+        // jiffies. Assume something is wrong.\r
+        call SFLUSHTX.strobe();\r
+        call CaptureSFD.disable();\r
+        call CaptureSFD.captureRisingEdge();\r
+        signalDone( ERETRY );\r
+        break;\r
+#endif\r
+      default:\r
+        break;\r
+      }\r
+    }\r
+  }\r
+  \r
+    \r
+#ifdef PLATFORM_MICAZ\r
+  event void WatchdogTimer.fired() {\r
+    atomic m_state = S_STARTED;\r
+    releaseSpiResource();\r
+    signalDone(ERETRY);\r
+  }\r
+#endif\r
+  \r
+  \r
+  /***************** Functions ****************/\r
+  /**\r
+   * Send a message with or without CCA\r
+   */\r
+  error_t send( message_t* p_msg, bool cca ) {\r
+    atomic {\r
+      if ( m_state != S_STARTED ) {\r
+        return FAIL;\r
+      }\r
+      \r
+      m_state = S_LOAD;\r
+      m_cca = cca;\r
+      m_msg = p_msg;\r
+    }\r
+\r
+#ifdef PLATFORM_MICAZ\r
+    post startWatchdogTimer();\r
+#endif\r
+\r
+    if ( acquireSpiResource() == SUCCESS ) {\r
+      loadTXFIFO();\r
+    }\r
+    // Else, we wait for the SpiResource.granted event..\r
+    \r
+    return SUCCESS;\r
+  }\r
+  \r
+  /**\r
+   * Resend a message with or without CCA\r
+   */\r
+  error_t resend( bool cca ) {\r
+    atomic {\r
+      if ( m_state != S_STARTED )\r
+        return FAIL;\r
+      m_cca = cca;\r
+      m_state = cca ? S_SAMPLE_CCA : S_BEGIN_TRANSMIT;\r
+    }\r
+\r
+#ifdef PLATFORM_MICAZ\r
+    post startWatchdogTimer();\r
+#endif\r
+\r
+    if ( m_cca ) {\r
+      startBackoffTimer( signal CsmaBackoff.initial( m_msg ) );\r
+    }\r
+    else if ( acquireSpiResource() == SUCCESS ) {\r
+      attemptSend();\r
+    }\r
+    \r
+    return SUCCESS;\r
+  }\r
+  \r
+  /**\r
+   * Attempt to send a message\r
+   */\r
+  void attemptSend() {\r
+    uint8_t status;\r
+    bool congestion = TRUE;\r
+\r
+    call CSN.clr();\r
+\r
+    status = m_cca ? call STXONCCA.strobe() : call STXON.strobe();\r
+    if ( !( status & CC2420_STATUS_TX_ACTIVE ) ) {\r
+      status = call SNOP.strobe();\r
+      if ( status & CC2420_STATUS_TX_ACTIVE )\r
+        congestion = FALSE;\r
+    }\r
+    atomic m_state = congestion ? S_SAMPLE_CCA : S_SFD;\r
+    \r
+    call CSN.set();\r
+\r
+    if ( congestion ) {\r
+      releaseSpiResource();\r
+      congestionBackoff();\r
+    }\r
+#ifdef PLATFORM_MICAZ\r
+    else {\r
+      startBackoffTimer(CC2420_ABORT_PERIOD);\r
+    }\r
+#endif\r
+  }\r
+  \r
+  \r
+  /**\r
+   * Get the CC2420 message header\r
+   */\r
+  cc2420_header_t* getHeader( message_t* msg ) {\r
+    return (cc2420_header_t*)( msg->data - sizeof( cc2420_header_t ) );\r
+  }\r
+\r
+  /**\r
+   * Get the CC2420 message metadata\r
+   */\r
+  cc2420_metadata_t* getMetadata( message_t* msg ) {\r
+    return (cc2420_metadata_t*)msg->metadata;\r
+  }\r
+  \r
+#ifdef PLATFORM_MICAZ\r
+  /**\r
+   * Start the watchdog timer\r
+   */\r
+  task void startWatchdogTimer() {\r
+    call WatchdogTimer.startOneShot(50);\r
+  }\r
+  \r
+  /**\r
+   * Stop the watchdog timer\r
+   */\r
+  task void stopWatchdogTimer() {\r
+    call WatchdogTimer.stop();\r
+  }\r
+#endif\r
+  \r
+  /**\r
+   * Start the backoff timer\r
+   */\r
+  void startBackoffTimer(uint16_t time) {\r
+    call BackoffTimer.start(time);\r
+  }\r
+\r
+  /** \r
+   * Stop the backoff timer\r
+   */\r
+  void stopBackoffTimer() {\r
+    call BackoffTimer.stop();\r
+  }\r
+\r
+  /**\r
+   * Acquire the SPI bus resource immediately, or defer it till later\r
+   */\r
+  error_t acquireSpiResource() {\r
+    error_t error = call SpiResource.immediateRequest();\r
+    if ( error != SUCCESS ) {\r
+      call SpiResource.request();\r
+    }\r
+    return error;\r
+  }\r
+\r
+  /**\r
+   * Release the SPI resource\r
+   */\r
+  void releaseSpiResource() {\r
+    call SpiResource.release();\r
+  }\r
+\r
+  /**\r
+   * Signal done\r
+   */\r
+  void signalDone( error_t err ) {\r
+    atomic m_state = S_STARTED;\r
+\r
+#ifdef PLATFORM_MICAZ\r
+    post stopWatchdogTimer();\r
+#endif\r
+\r
+    signal Send.sendDone( m_msg, err );\r
+  }\r
+\r
+  /**  \r
+   * Congestion Backoff\r
+   */\r
+  void congestionBackoff() {\r
+    atomic {\r
+      startBackoffTimer(signal CsmaBackoff.congestion( m_msg ) + 1);\r
+    }\r
+  }\r
+  \r
+  /**\r
+   * Load TX FIFO\r
+   */\r
+  void loadTXFIFO() {\r
+    cc2420_header_t* header = getHeader( m_msg );\r
+    uint8_t tx_power = getMetadata( m_msg )->tx_power;\r
+    \r
+    if ( !tx_power )\r
+      tx_power = CC2420_DEF_RFPOWER;\r
+    call CSN.clr();\r
+    if ( m_tx_power != tx_power )\r
+      call TXCTRL.write( ( 2 << CC2420_TXCTRL_TXMIXBUF_CUR ) |\r
+                         ( 3 << CC2420_TXCTRL_PA_CURRENT ) |\r
+                         ( 1 << CC2420_TXCTRL_RESERVED ) |\r
+                         ( tx_power << CC2420_TXCTRL_PA_LEVEL ) );\r
+    m_tx_power = tx_power;\r
+    call TXFIFO.write( (uint8_t*)header, header->length - 1 );\r
+  }\r
+   \r
+  /***************** Defaults ****************/\r
+  default async event void TimeStamp.transmittedSFD( uint16_t time, message_t* p_msg ) {}\r
+  default async event void TimeStamp.receivedSFD( uint16_t time ) {}\r
+\r
+}\r
diff --git a/tos/chips/cc2420_lpl/IEEE802154.h b/tos/chips/cc2420_lpl/IEEE802154.h
new file mode 100644 (file)
index 0000000..65aab6f
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * Copyright (c) 2005-2006 Arch Rock Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ *\r
+ * @author Jonathan Hui <jhui@archrock.com>\r
+ * @version $Revision$ $Date$\r
+ */\r
+\r
+#ifndef __IEEE802154_H__\r
+#define __IEEE802154_H__\r
+\r
+enum ieee154_fcf_enums {\r
+  IEEE154_FCF_FRAME_TYPE = 0,\r
+  IEEE154_FCF_SECURITY_ENABLED = 3,\r
+  IEEE154_FCF_FRAME_PENDING = 4,\r
+  IEEE154_FCF_ACK_REQ = 5,\r
+  IEEE154_FCF_INTRAPAN = 6,\r
+  IEEE154_FCF_DEST_ADDR_MODE = 10,\r
+  IEEE154_FCF_SRC_ADDR_MODE = 14,\r
+};\r
+\r
+enum ieee154_fcf_type_enums {\r
+  IEEE154_TYPE_BEACON = 0,\r
+  IEEE154_TYPE_DATA = 1,\r
+  IEEE154_TYPE_ACK = 2,\r
+  IEEE154_TYPE_MAC_CMD = 3,\r
+};\r
+\r
+enum iee154_fcf_addr_mode_enums {\r
+  IEEE154_ADDR_NONE = 0,\r
+  IEEE154_ADDR_SHORT = 2,\r
+  IEEE154_ADDR_EXT = 3,\r
+};\r
+\r
+#endif\r
diff --git a/tos/chips/cc2420_lpl/LowPowerListening.nc b/tos/chips/cc2420_lpl/LowPowerListening.nc
new file mode 100644 (file)
index 0000000..c8649c8
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2005-2006 Rincon Research 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
+ */
+/**
+ * Low Power Listening interface
+ *
+ * @author David Moss
+ * @author Jonathan Hui
+ */
+interface LowPowerListening {
+
+  /**
+   * Set this this node's radio sleep interval, in milliseconds.
+   * Once every interval, the node will sleep and perform an Rx check 
+   * on the radio.  Setting the sleep interval to 0 will keep the radio
+   * always on.
+   *
+   * This is the equivalent of setting the local duty cycle rate.
+   *
+   * @param sleepIntervalMs the length of this node's Rx check interval, in [ms]
+   */
+  command void setLocalSleepInterval(uint16_t sleepIntervalMs);
+  
+  /**
+   * @return the local node's sleep interval, in [ms]
+   */
+  command uint16_t getLocalSleepInterval();
+  
+  /**
+   * Set this node's radio duty cycle rate, in units of [percentage*100].
+   * For example, to get a 0.05% duty cycle,
+   * <code>
+   *   call LowPowerListening.setDutyCycle(5);  // or equivalently...
+   *   call LowPowerListening.setDutyCycle(00005);  // for better readability?
+   * </code>
+   *
+   * For a 100% duty cycle (always on),
+   * <code>
+   *   call LowPowerListening.setDutyCycle(10000);
+   * </code>
+   *
+   * This is the equivalent of setting the local sleep interval explicitly.
+   * 
+   * @param dutyCycle The duty cycle percentage, in units of [percentage*100]
+   */
+  command void setLocalDutyCycle(uint16_t dutyCycle);
+  
+  /**
+   * @return this node's radio duty cycle rate, in units of [percentage*100]
+   */
+  command uint16_t getLocalDutyCycle();
+  
+  
+  /**
+   * Configure this outgoing message so it can be transmitted to a neighbor mote
+   * with the specified Rx sleep interval.
+   * @param msg Pointer to the message that will be sent
+   * @param sleepInterval The receiving node's sleep interval, in [ms]
+   */
+  command void setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs);
+  
+  /**
+   * @return the destination node's sleep interval configured in this message
+   */
+  command uint16_t getRxSleepInterval(message_t *msg);
+  
+  /**
+   * Configure this outgoing message so it can be transmitted to a neighbor mote
+   * with the specified Rx duty cycle rate.
+   * Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25.
+   * 
+   * @param msg Pointer to the message that will be sent
+   * @param dutyCycle The duty cycle of the receiving mote, in units of 
+   *     [percentage*100]
+   */
+  command void setRxDutyCycle(message_t *msg, uint16_t dutyCycle);
+  
+  /**
+   * @return the destination node's duty cycle configured in this message
+   *     in units of [percentage*100]
+   */
+  command uint16_t getRxDutyCycle(message_t *msg);
+  
+  /**
+   * Convert a duty cycle, in units of [percentage*100], to
+   * the sleep interval of the mote in milliseconds
+   * @param dutyCycle The duty cycle in units of [percentage*100]
+   * @return The equivalent sleep interval, in units of [ms]
+   */
+  command uint16_t dutyCycleToSleepInterval(uint16_t dutyCycle);
+  
+  /**
+   * Convert a sleep interval, in units of [ms], to a duty cycle
+   * in units of [percentage*100]
+   * @param sleepInterval The sleep interval in units of [ms]
+   * @return The duty cycle in units of [percentage*100]
+   */
+  command uint16_t sleepIntervalToDutyCycle(uint16_t sleepInterval);
+  
+}
diff --git a/tos/chips/ds2745/DS2745.h b/tos/chips/ds2745/DS2745.h
new file mode 100644 (file)
index 0000000..0c36b82
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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
+ */
+
+/**
+ * Types and definitions for the Dallas DS2745 I2C Battery Monitor
+ *
+ * @author Phil Buonadonna <pbuonadonna@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#ifndef _DS2745_H
+#define _DS2745_H
+
+#define DS2745_PTR_SC          (0x01)
+#define DS2745_PTR_TEMPMSB     (0x0A)
+#define DS2745_PTR_TEMPLSB     (0x0B)
+#define DS2745_PTR_VOLTMSB     (0x0C)
+#define DS2745_PTR_VOLTLSB     (0x0D)
+#define DS2745_PTR_CURRMSB     (0x0E)
+#define DS2745_PTR_CURRLSB     (0x0F)
+#define DS2745_PTR_ACCURMSB    (0x10)
+#define DS2745_PTR_ACCURLSB    (0x11)
+#define DS2745_PTR_OFFSETBIAS  (0x61)
+#define DS2745_PTR_ACCBIAS     (0x62)
+
+#define DS2745_SC_PORF         (1 << 6)
+#define DS2745_SC_SMOD         (1 << 5)
+#define DS2745_SC_NBEN         (1 << 4)
+#define DS2745_SC_PIO          (1 << 3)
+#define DS2745_SC_FQ(_x)       (((_x) & 0x3))
+
+#endif /* _DS2745_H */
diff --git a/tos/chips/ds2745/HplDS2745.nc b/tos/chips/ds2745/HplDS2745.nc
new file mode 100644 (file)
index 0000000..3966400
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 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 Arched 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
+ */
+
+/**
+ * HplDS2745 is the HPL inteface to the Dallas DS2745 I2C Battery 
+ * Monitor.
+ *
+ * @author Phil Buonadonna <pbuonadonna@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+interface HplDS2745 {
+
+  /**
+   * Sets a new value to the DS2745 configuration register.
+   *
+   * @param val the new value to be written
+   *
+   * @return SUCCESS if the set will be performed
+   */
+  command error_t setConfig( uint8_t val );
+
+  /**
+   * Signals the completion of the configuration register set.
+   *
+   * @param error SUCCESS if the set was successful
+   */
+  async event void setConfigDone( error_t error );
+
+
+  /**
+   * Starts a temperature measurement.
+   *
+   * @return SUCCESS if the measurement will be made
+   */
+  command error_t measureTemperature();
+
+  /**
+   * Presents the result of a temperature measurement.
+   *
+   * @param error SUCCESS if the measurement was successful
+   * @param val the temperature reading
+   */
+  async event void measureTemperatureDone( error_t error, uint16_t val );
+
+
+  /** 
+   * Starts a voltage measurement.
+   *
+   * @return SUCCESS if the measurement will be made
+   */
+  command error_t measureVoltage();
+
+  /**
+   * Presents the result of a voltage measurement.
+   *
+   * @param error SUCCESS if the measurement was successful
+   * @param val the voltage reading
+   */
+  async event void measureVoltageDone( error_t error, uint16_t val);
+
+
+  /** 
+   * Starts a current measurement.
+   *
+   * @return SUCCESS if the measurement will be made
+   */
+  command error_t measureCurrent();
+
+  /**
+   * Presents the result of a current measurement.
+   *
+   * @param error SUCCESS if the measurement was successful
+   * @param val the current reading
+   */
+  async event void measureCurrentDone( error_t error, uint16_t val);
+
+
+  /** 
+   * Starts an accumulated current measurement.
+   *
+   * @return SUCCESS if the measurement will be made
+   */
+  command error_t measureAccCurrent();
+
+  /**
+   * Presents the result of a accumulated current measurement.
+   *
+   * @param error SUCCESS if the measurement was successful
+   * @param val the accumulated current reading
+   */
+  async event void measureAccCurrentDone( error_t error, uint16_t val);
+
+
+  /** 
+   * Initiates setting of the current offset bias value
+   *
+   * @param The signed two's complement bias value.
+   *
+   * @return SUCCESS if the setting will be made
+   */
+  command error_t setOffsetBias(int8_t val);
+
+  /**
+   * Signals completion and error, if any, in setting the current
+   * offset bias value.
+   *
+   * @param error SUCCESS if the setting was successful
+   */
+  async event void setOffsetBiasDone( error_t error );
+
+
+  /** 
+   * Initiates setting of the accumulated current offset bias value
+   *
+   * @param The signed two's complement bias value.
+   *
+   * @return SUCCESS if the setting will be made
+   */
+  command error_t setAccOffsetBias(int8_t val);
+
+  /**
+   * Signals completion and error, if any, in setting the accumulated
+   * current offset bias value.
+   *
+   * @param error SUCCESS if the setting was successful
+   */
+  async event void setAccOffsetBiasDone( error_t error );
+
+
+}
diff --git a/tos/chips/ds2745/HplDS2745LogicP.nc b/tos/chips/ds2745/HplDS2745LogicP.nc
new file mode 100644 (file)
index 0000000..df4d11c
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * 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 Arched 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
+ */
+
+/**
+ * HplDS2745LogicP is the driver for the Dallas DS2745. It requires an 
+ * I2C packet interface and provides the HplTMP175 HPL interface.
+ * 
+ * @author Phil Buonadonna <pbuonadonna@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#include "DS2745.h"
+#include "I2C.h"
+
+generic module HplDS2745LogicP(uint16_t devAddr)
+{
+  provides interface Init;
+  provides interface SplitControl;
+  provides interface HplDS2745;
+
+  uses interface I2CPacket<TI2CBasicAddr>;
+
+}
+
+implementation {
+
+  enum {
+    STATE_IDLE,
+    STATE_STARTING,
+    STATE_STOPPING,
+    STATE_STOPPED,
+    STATE_SETCONFIG,
+    STATE_READTEMP,
+    STATE_READVOLTAGE,
+    STATE_READCURRENT,
+    STATE_READACCCURRENT,
+    STATE_SETBIAS,
+    STATE_SETACCBIAS
+  };
+
+  uint8_t mI2CBuffer[4];
+  uint8_t mState;
+  norace error_t mSSError = SUCCESS;
+
+  static error_t doReadReg(uint8_t nextState, uint8_t reg) {
+    error_t error = SUCCESS;
+       
+    atomic {
+      if (mState == STATE_IDLE) {
+       mState = nextState;
+      }
+      else {
+       error = EBUSY;
+      }
+    }
+    if (error)
+      return error;
+
+    mI2CBuffer[0] = reg;
+
+    error = call I2CPacket.write(I2C_START,devAddr,1,mI2CBuffer);
+    
+    if (error) 
+      atomic mState = STATE_IDLE;
+
+    return error;
+
+  }
+
+  static error_t doSetReg(uint8_t nextState, uint8_t reg, uint16_t val) {
+    error_t error = SUCCESS;
+
+    atomic {
+      if (mState == STATE_IDLE) {
+       mState = nextState;
+      }
+      else {
+       error = EBUSY;
+      }
+    }
+    if (error)
+      return error;
+
+    mI2CBuffer[0] = reg;
+    mI2CBuffer[1] = val;
+
+    error = call I2CPacket.write((I2C_START | I2C_STOP),devAddr,2,mI2CBuffer);
+    
+    if (error) 
+      atomic mState = STATE_IDLE;
+
+    return error;
+  }
+
+  task void StartDone() {
+    atomic mState = STATE_IDLE;
+    signal SplitControl.startDone(mSSError);
+    return;
+  }
+
+  task void StopDone() {
+    atomic mState = STATE_STOPPED;
+    signal SplitControl.stopDone(mSSError);
+    return;
+  }
+
+  command error_t Init.init() {
+    mState = STATE_STOPPED;
+    return SUCCESS;
+  }
+
+  command error_t SplitControl.start() {
+    error_t error = SUCCESS;
+    atomic {
+      if (mState == STATE_STOPPED) { 
+       mState = STATE_STARTING; 
+      }
+      else {
+       error = EBUSY;
+      }
+    }
+    if (!error)
+      post StartDone();
+
+    return error;
+  }
+
+  command error_t SplitControl.stop() {
+    error_t error = SUCCESS;
+    atomic {
+      if (mState == STATE_IDLE) {
+       mState = STATE_STOPPING;
+      }
+      else {
+       error = EBUSY;
+      }
+    }
+    if (!error)
+      post StopDone();
+
+    return error;
+  }
+  
+  command error_t HplDS2745.setConfig(uint8_t val) {
+    return doSetReg(STATE_SETCONFIG,DS2745_PTR_SC,val);
+  }
+
+  command error_t HplDS2745.measureTemperature() { 
+    return doReadReg(STATE_READTEMP,DS2745_PTR_TEMPMSB);
+  }
+
+  command error_t HplDS2745.measureVoltage() { 
+    return doReadReg(STATE_READVOLTAGE,DS2745_PTR_VOLTMSB);
+  }
+
+  command error_t HplDS2745.measureCurrent() { 
+    return doReadReg(STATE_READCURRENT,DS2745_PTR_CURRMSB);
+  }
+
+  command error_t HplDS2745.measureAccCurrent() { 
+    return doReadReg(STATE_READTEMP,DS2745_PTR_ACCURMSB);
+  }
+
+  command error_t HplDS2745.setOffsetBias(int8_t val) { 
+    return doSetReg(STATE_SETBIAS,DS2745_PTR_OFFSETBIAS,val); 
+  }
+
+  command error_t HplDS2745.setAccOffsetBias(int8_t val) {
+    return doSetReg(STATE_SETACCBIAS,DS2745_PTR_ACCBIAS,val); 
+  }
+
+  async event void I2CPacket.readDone(error_t i2c_error, uint16_t chipAddr, uint8_t len, uint8_t *buf) {
+    uint16_t tempVal;
+    tempVal = buf[0];
+    tempVal = ((tempVal << 8) | buf[1]);
+
+    switch (mState) {
+    case STATE_READTEMP:
+      signal HplDS2745.measureTemperatureDone(i2c_error,tempVal);
+      break;
+    case STATE_READVOLTAGE:
+      signal HplDS2745.measureVoltageDone(i2c_error,tempVal);
+      break;
+    case STATE_READCURRENT:
+      signal HplDS2745.measureCurrentDone(i2c_error,tempVal);
+      break;
+    case STATE_READACCCURRENT:
+      signal HplDS2745.measureAccCurrentDone(i2c_error,tempVal);
+      break;
+    default:
+      break;
+    }
+    atomic mState = STATE_IDLE;
+    return;
+  }
+
+  async event void I2CPacket.writeDone(error_t i2c_error, uint16_t chipAddr, uint8_t len, uint8_t *buf) {
+    error_t error = i2c_error;
+
+    switch (mState) {
+    case STATE_SETCONFIG:
+      atomic mState = STATE_IDLE;
+      signal HplDS2745.setConfigDone(error);
+      break;     
+    case STATE_READTEMP:
+      if (error) 
+       signal HplDS2745.measureTemperatureDone(error,0);
+      else
+       error = call I2CPacket.read((I2C_START | I2C_STOP),devAddr,2,mI2CBuffer);
+      break;
+    case STATE_READVOLTAGE:
+      if (error) 
+       signal HplDS2745.measureVoltageDone(error,0);
+      else
+       error = call I2CPacket.read((I2C_START | I2C_STOP),devAddr,2,mI2CBuffer);
+      break;
+    case STATE_READCURRENT:
+      if (error) 
+       signal HplDS2745.measureCurrentDone(error,0);
+      else 
+       error = call I2CPacket.read((I2C_START | I2C_STOP),devAddr,2,mI2CBuffer);
+      break;
+    case STATE_READACCCURRENT:
+      if (error) 
+       signal HplDS2745.measureAccCurrentDone(error,0);
+      else
+       error = call I2CPacket.read((I2C_START | I2C_STOP),devAddr,2,mI2CBuffer);
+      break;
+    case STATE_SETBIAS:
+      atomic mState = STATE_IDLE;
+      signal HplDS2745.setOffsetBiasDone(error);
+      break;
+    case STATE_SETACCBIAS:
+      atomic mState = STATE_IDLE;
+      signal HplDS2745.setAccOffsetBiasDone(error);
+      break;
+    default:
+      atomic mState = STATE_IDLE;
+      break;
+    }
+    if (error)
+      atomic mState = STATE_IDLE;
+    return;
+  }
+  
+  default event void SplitControl.startDone( error_t error ) { return; }
+  default event void SplitControl.stopDone( error_t error ) { return; }
+  default async event void HplDS2745.setConfigDone(error_t error) {return; }
+  default async event void HplDS2745.measureTemperatureDone( error_t error, uint16_t val ){ return; }
+  default async event void HplDS2745.measureVoltageDone( error_t error, uint16_t val ){ return; }
+  default async event void HplDS2745.measureCurrentDone( error_t error, uint16_t val ){ return; }
+  default async event void HplDS2745.measureAccCurrentDone( error_t error, uint16_t val ){ return; }
+  default async event void HplDS2745.setOffsetBiasDone( error_t error ){ return; }
+  default async event void HplDS2745.setAccOffsetBiasDone(error_t error){ return; }
+}
diff --git a/tos/chips/msp430/adc12/AdcP.nc b/tos/chips/msp430/adc12/AdcP.nc
new file mode 100644 (file)
index 0000000..654807a
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+module AdcP {
+  provides {
+    interface Read<uint16_t> as Read[uint8_t client];
+    interface ReadNow<uint16_t> as ReadNow[uint8_t client];
+    interface Resource as ResourceReadNow[uint8_t client];
+    interface ReadStream<uint16_t> as ReadStream[uint8_t streamClient];
+  }
+  uses {
+    // for Read only:
+    interface Resource as ResourceRead[uint8_t client];
+    // for ReadNow only:
+    interface Resource as SubResourceReadNow[uint8_t client];
+    // for Read and ReadNow:
+    interface AdcConfigure<const msp430adc12_channel_config_t*> as Config[uint8_t client];
+    interface Msp430Adc12SingleChannel as SingleChannel[uint8_t client];
+    // for ReadStream only:
+    interface AdcConfigure<const msp430adc12_channel_config_t*> as ConfigReadStream[uint8_t streamClient];
+    interface Msp430Adc12SingleChannel as SingleChannelReadStream[uint8_t streamClient];
+    interface Resource as ResourceReadStream[uint8_t streamClient];
+
+  }
+}
+implementation
+{
+  enum {
+    STATE_READ,
+    STATE_READNOW,
+    STATE_READNOW_INVALID_CONFIG,
+    STATE_READSTREAM,
+  };
+  
+  struct stream_entry_t {
+    uint16_t count;
+    struct stream_entry_t *next;
+  };
+  
+  // Resource interface / arbiter makes norace declaration safe
+  norace uint8_t state;
+  norace uint8_t owner;
+  norace uint16_t value;
+  norace uint16_t *resultBuf; 
+
+  // atomic section in postBuffer() makes norace safe
+  norace struct stream_entry_t *streamBuf[uniqueCount(ADCC_READ_STREAM_SERVICE)];
+  norace uint32_t usPeriod[uniqueCount(ADCC_READ_STREAM_SERVICE)];
+  msp430adc12_channel_config_t streamConfig;
+    
+  void task finishStreamRequest();
+  void task signalBufferDone();
+  void nextReadStreamRequest(uint8_t streamClient);
+
+  error_t configure(uint8_t client)
+  {
+    error_t result = EINVAL;
+    const msp430adc12_channel_config_t *config;
+    config = call Config.getConfiguration[client]();
+    if (config->inch != INPUT_CHANNEL_NONE)
+      result = call SingleChannel.configureSingle[client](config);
+    return result;
+  }
+
+  command error_t Read.read[uint8_t client]()
+  {
+    if (call ResourceRead.isOwner[client]())
+      return EBUSY;
+    return call ResourceRead.request[client]();
+  }
+
+  event void ResourceRead.granted[uint8_t client]() 
+  {
+    // signalled only for Read.read()
+    error_t result = configure(client);
+    if (result == SUCCESS){
+      state = STATE_READ;
+      result = call SingleChannel.getData[client]();
+    }
+    if (result != SUCCESS){
+      call ResourceRead.release[client]();
+      signal Read.readDone[client](result, 0);
+    }
+  }
+  
+  async command error_t ResourceReadNow.request[uint8_t nowClient]()
+  {
+    return call SubResourceReadNow.request[nowClient]();
+  }
+
+  event void SubResourceReadNow.granted[uint8_t nowClient]()
+  {
+    if (configure(nowClient) == SUCCESS)
+      state = STATE_READNOW;
+    else
+      state = STATE_READNOW_INVALID_CONFIG;
+    signal ResourceReadNow.granted[nowClient]();
+  }
+
+  async command error_t ResourceReadNow.immediateRequest[uint8_t nowClient]()
+  {
+    error_t result = call SubResourceReadNow.immediateRequest[nowClient]();
+    if (result == SUCCESS){
+      result = configure(nowClient);
+      if (result == SUCCESS)
+        state = STATE_READNOW;
+    }
+    return result;
+  }
+
+  async command error_t ResourceReadNow.release[uint8_t nowClient]()
+  {
+    return call SubResourceReadNow.release[nowClient]();
+  }
+
+  async command bool ResourceReadNow.isOwner[uint8_t nowClient]()
+  {
+    return call SubResourceReadNow.isOwner[nowClient]();
+  }
+    
+  async command error_t ReadNow.read[uint8_t nowClient]()
+  {
+    if (state == STATE_READNOW_INVALID_CONFIG)
+      return EINVAL;
+    else
+      return call SingleChannel.getData[nowClient]();
+  }
+  
+  void task readDone()
+  {
+    call ResourceRead.release[owner]();
+    signal Read.readDone[owner](SUCCESS, value);
+  }
+
+  async event error_t SingleChannel.singleDataReady[uint8_t client](uint16_t data)
+  {
+    switch (state)
+    {
+      case STATE_READ:
+        owner = client;
+        value = data;
+        post readDone();
+        break;
+      case STATE_READNOW:
+        signal ReadNow.readDone[client](SUCCESS, data);
+        break;
+      default:
+        // error !
+        break;
+    }
+    return SUCCESS;
+  }
+
+  async event uint16_t* SingleChannel.multipleDataReady[uint8_t client](
+      uint16_t *buf, uint16_t length)
+  {
+    // error !
+    return 0;
+  }
+  
+  command error_t ReadStream.postBuffer[uint8_t streamClient]( uint16_t* buf, uint16_t count )
+  {
+    struct stream_entry_t *newEntry = (struct stream_entry_t *) buf;
+    
+    newEntry->count = count;
+    newEntry->next = 0;
+    atomic {
+      if (!streamBuf[streamClient])
+        streamBuf[streamClient] = newEntry;
+      else {
+        struct stream_entry_t *tmp = streamBuf[streamClient];
+        while (tmp->next)
+          tmp = tmp->next;
+        tmp->next = newEntry;
+      }
+    }
+    return SUCCESS;
+  }
+  
+  command error_t ReadStream.read[uint8_t streamClient]( uint32_t _usPeriod )
+  {
+    if (!streamBuf[streamClient])
+      return EINVAL;
+    if (call ResourceReadStream.isOwner[streamClient]())
+      return EBUSY;
+    usPeriod[streamClient] = _usPeriod;
+    return call ResourceReadStream.request[streamClient]();
+  }
+
+  void task finishStreamRequest()
+  {
+    call ResourceReadStream.release[owner]();
+    if (!streamBuf[owner])
+      // all posted buffers were filled
+      signal ReadStream.readDone[owner]( SUCCESS, usPeriod[owner] );
+    else {
+      // the commented code below makes gcc throw
+      // "internal error: unsupported relocation error" !?!
+      /*
+      do {
+        signal ReadStream.bufferDone[owner]( FAIL, (uint16_t *) streamBuf[owner], 0);
+        streamBuf[owner] = streamBuf[owner]->next;
+      } while (streamBuf[owner]);
+      */
+      signal ReadStream.readDone[owner]( FAIL, 0 );
+    }
+  }  
+
+  event void ResourceReadStream.granted[uint8_t streamClient]() 
+  {
+    error_t result;
+    const msp430adc12_channel_config_t *config;
+    struct stream_entry_t *entry = streamBuf[streamClient];
+
+    if (!entry)
+      result = EINVAL;
+    else {
+      config = call ConfigReadStream.getConfiguration[streamClient]();
+      if (config->inch == INPUT_CHANNEL_NONE)
+        result = EINVAL;
+      else {
+        owner = streamClient;
+        streamConfig = *config;
+        streamConfig.sampcon_ssel = SAMPCON_SOURCE_SMCLK; // assumption: SMCLK runs at 1 MHz
+        streamConfig.sampcon_id = SAMPCON_CLOCK_DIV_1; 
+        streamBuf[streamClient] = entry->next;
+        result = call SingleChannelReadStream.configureMultiple[streamClient](
+            &streamConfig, (uint16_t *) entry, entry->count, usPeriod[streamClient]);
+        if (result == SUCCESS)
+          result = call SingleChannelReadStream.getData[streamClient]();
+        else {
+          streamBuf[streamClient] = entry;
+          post finishStreamRequest();
+          return;
+        }
+      }
+    }
+    if (result != SUCCESS){
+      call ResourceReadStream.release[streamClient]();
+      signal ReadStream.readDone[streamClient]( FAIL, 0 );
+    }
+    return;
+  }
+
+
+  async event uint16_t* SingleChannelReadStream.multipleDataReady[uint8_t streamClient](
+      uint16_t *buf, uint16_t length)
+  {
+    error_t nextRequest;
+    
+    if (!resultBuf){
+      value = length;
+      resultBuf = buf;
+      post signalBufferDone();
+      if (!streamBuf[streamClient])
+        post finishStreamRequest();
+      else {
+        // fill next buffer (this is the only async code dealing with buffers)
+        struct stream_entry_t *entry = streamBuf[streamClient];
+        streamBuf[streamClient] = streamBuf[streamClient]->next;
+        nextRequest = call SingleChannelReadStream.configureMultiple[streamClient](
+            &streamConfig, (uint16_t *) entry, entry->count, usPeriod[streamClient]);
+        if (nextRequest == SUCCESS)
+          nextRequest = call SingleChannelReadStream.getData[streamClient]();
+        if (nextRequest != SUCCESS){
+          streamBuf[owner] = entry;
+          post finishStreamRequest();
+        }
+      }
+    } else {
+      // overflow: can't signal data fast enough
+      struct stream_entry_t *entry = (struct stream_entry_t *) buf;
+      entry->next = streamBuf[streamClient];
+      streamBuf[streamClient] = entry; // what a waste
+      post finishStreamRequest();
+    }
+    return 0;
+  }
+
+  void task signalBufferDone()
+  {
+    signal ReadStream.bufferDone[owner]( SUCCESS, resultBuf, value);
+    resultBuf = 0;
+  }
+  
+  async event error_t SingleChannelReadStream.singleDataReady[uint8_t streamClient](uint16_t data)
+  {
+    // won't happen
+    return SUCCESS;
+  }
+
+  default async command error_t ResourceRead.request[uint8_t client]() { return FAIL; }
+  default async command error_t ResourceRead.immediateRequest[uint8_t client]() { return FAIL; }
+  default async command error_t ResourceRead.release[uint8_t client]() { return FAIL; }
+  default async command bool ResourceRead.isOwner[uint8_t client]() { return FALSE; }
+  default event void Read.readDone[uint8_t client]( error_t result, uint16_t val ){}
+
+  default async command error_t SubResourceReadNow.release[uint8_t nowClient](){ return FAIL;}
+  default async command error_t SubResourceReadNow.request[uint8_t nowClient](){ return FAIL; }
+  default async command bool SubResourceReadNow.isOwner[uint8_t client]() { return FALSE; }
+  default event void ResourceReadNow.granted[uint8_t nowClient](){}
+  default async event void ReadNow.readDone[uint8_t client]( error_t result, uint16_t val ){}
+  default async command error_t SubResourceReadNow.immediateRequest[uint8_t nowClient]()
+  { 
+    return FAIL; 
+  }
+  
+  default async command error_t ResourceReadStream.request[uint8_t streamClient]() { return FAIL; }
+  default async command error_t ResourceReadStream.release[uint8_t streamClient]() { return FAIL; }
+  default async command bool ResourceReadStream.isOwner[uint8_t streamClient]() { return FALSE; }
+  default event void ReadStream.bufferDone[uint8_t streamClient]( error_t result, 
+                        uint16_t* buf, uint16_t count ){}
+  default event void ReadStream.readDone[uint8_t streamClient]( error_t result, uint32_t actualPeriod ){ } 
+
+  default async command error_t SingleChannel.getData[uint8_t client]()
+  {
+    return EINVAL;
+  }
+
+  // will be placed in flash
+  const msp430adc12_channel_config_t defaultConfig = {INPUT_CHANNEL_NONE,0,0,0,0,0,0,0}; 
+  default async command const msp430adc12_channel_config_t*
+    Config.getConfiguration[uint8_t client]()
+  { 
+    return &defaultConfig;
+  }
+
+  default async command const msp430adc12_channel_config_t*
+    ConfigReadStream.getConfiguration[uint8_t client]()
+  { 
+    return &defaultConfig;
+  }
+
+  default async command error_t SingleChannelReadStream.configureMultiple[uint8_t client](
+      const msp430adc12_channel_config_t *config, uint16_t buffer[], 
+      uint16_t numSamples, uint16_t jiffies)
+  {
+    return FAIL;
+  }
+
+  default async command error_t SingleChannelReadStream.getData[uint8_t client]()
+  {
+    return FAIL;
+  }
+
+  default async command error_t SingleChannel.configureSingle[uint8_t client](
+      const msp430adc12_channel_config_t *config){ return FAIL; }
+
+
+}
+
diff --git a/tos/chips/msp430/adc12/Msp430Adc12ClientAutoDMAC.nc b/tos/chips/msp430/adc12/Msp430Adc12ClientAutoDMAC.nc
new file mode 100644 (file)
index 0000000..241627c
--- /dev/null
@@ -0,0 +1,66 @@
+/* \r
+ * Copyright (c) 2006, Technische Universitaet Berlin\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright notice,\r
+ *   this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the distribution.\r
+ * - Neither the name of the Technische Universitaet Berlin nor the names\r
+ *   of its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\r
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\r
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\r
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * - Revision -------------------------------------------------------------\r
+ * $Revision$\r
+ * $Date$\r
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>\r
+ * ========================================================================\r
+ */\r
+\r
+/** \r
+ * This component virtualizes access to the HAL of the MSP430 ADC12.  ADC\r
+ * conversion results are copied using DMA.\r
+ * \r
+ * @author Jan Hauer \r
+ *\r
+ * @see  Please refer to the README.txt and TEP 101 for more information about\r
+ * this component and its intended use.\r
+ */\r
+\r
+generic configuration Msp430Adc12ClientAutoDMAC()\r
+{\r
+  provides {\r
+    interface Resource;\r
+    interface Msp430Adc12SingleChannel;\r
+  }\r
+} implementation {\r
+  components Msp430DmaC, Msp430Adc12DMAP, Msp430Adc12P;\r
+   \r
+  enum {\r
+    ID = unique(MSP430ADC12_RESOURCE),\r
+  };\r
+  Resource = Msp430Adc12P.Resource[ID];\r
+  Msp430Adc12SingleChannel = Msp430Adc12DMAP.SingleChannel[ID];\r
+  \r
+  Msp430Adc12DMAP.SubSingleChannel[ID] -> Msp430Adc12P.SingleChannel[ID];\r
+  Msp430Adc12DMAP.AsyncAdcControl[ID] -> Msp430Adc12P.DMAExtension[ID];\r
+\r
+  Msp430Adc12DMAP.DMAControl -> Msp430DmaC.Control;\r
+  Msp430Adc12DMAP.DMAChannel -> Msp430DmaC.Channel0;\r
+}\r
diff --git a/tos/chips/msp430/adc12/Msp430Adc12ClientAutoDMA_RVGC.nc b/tos/chips/msp430/adc12/Msp430Adc12ClientAutoDMA_RVGC.nc
new file mode 100644 (file)
index 0000000..ee713db
--- /dev/null
@@ -0,0 +1,73 @@
+/* \r
+ * Copyright (c) 2006, Technische Universitaet Berlin All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ * - Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the following disclaimer.  - Redistributions in\r
+ * binary form must reproduce the above copyright notice, this list of\r
+ * conditions and the following disclaimer in the documentation and/or other\r
+ * materials provided with the distribution.  - Neither the name of the\r
+ * Technische Universitaet Berlin nor the names of its contributors may be used\r
+ * to endorse or promote products derived from this software without specific\r
+ * prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * - Revision -------------------------------------------------------------\r
+ * $Revision$ $Date$ @author: Jan Hauer\r
+ * <hauer@tkn.tu-berlin.de>\r
+ * ========================================================================\r
+ */\r
\r
+\r
+/** \r
+ * This component virtualizes access to the HAL of the MSP430 ADC12.  ADC\r
+ * conversion results are copied using DMA and reference voltage is enabled as\r
+ * required by the configuration.\r
+ * \r
+ * @author Jan Hauer \r
+ *\r
+ * @see  Please refer to the README.txt and TEP 101 for more information about\r
+ * this component and its intended use.\r
+ */\r
+\r
+generic configuration Msp430Adc12ClientAutoDMA_RVGC()\r
+{\r
+  provides {\r
+    interface Resource;\r
+    interface Msp430Adc12SingleChannel;\r
+  }\r
+  uses interface AdcConfigure<const msp430adc12_channel_config_t*>;\r
+} implementation {\r
+  components Msp430Adc12P, Msp430RefVoltArbiterP;\r
+\r
+  enum {\r
+    ID = unique(MSP430ADC12_RESOURCE),\r
+  };\r
+  Resource = Msp430RefVoltArbiterP.ClientResource[ID];\r
+  \r
+  Msp430RefVoltArbiterP.AdcResource[ID] -> Msp430Adc12P.Resource[ID];\r
+  AdcConfigure = Msp430RefVoltArbiterP.Config[ID]; \r
+\r
+  components Msp430DmaC, Msp430Adc12DMAP;\r
+  \r
+  Msp430Adc12SingleChannel = Msp430Adc12DMAP.SingleChannel[ID];\r
+  \r
+  Msp430Adc12DMAP.SubSingleChannel[ID] -> Msp430Adc12P.SingleChannel[ID];\r
+  Msp430Adc12DMAP.AsyncAdcControl[ID] -> Msp430Adc12P.DMAExtension[ID];\r
+\r
+  Msp430Adc12DMAP.DMAControl -> Msp430DmaC.Control;\r
+  Msp430Adc12DMAP.DMAChannel -> Msp430DmaC.Channel0;\r
+  \r
+}\r
diff --git a/tos/chips/msp430/adc12/Msp430Adc12ClientAutoRVGC.nc b/tos/chips/msp430/adc12/Msp430Adc12ClientAutoRVGC.nc
new file mode 100644 (file)
index 0000000..97cc789
--- /dev/null
@@ -0,0 +1,61 @@
+/* \r
+ * Copyright (c) 2006, Technische Universitaet Berlin All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ * - Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the following disclaimer.  - Redistributions in\r
+ * binary form must reproduce the above copyright notice, this list of\r
+ * conditions and the following disclaimer in the documentation and/or other\r
+ * materials provided with the distribution.  - Neither the name of the\r
+ * Technische Universitaet Berlin nor the names of its contributors may be used\r
+ * to endorse or promote products derived from this software without specific\r
+ * prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * - Revision -------------------------------------------------------------\r
+ * $Revision$ $Date$ @author: Jan Hauer\r
+ * <hauer@tkn.tu-berlin.de>\r
+ * ========================================================================\r
+ */\r
\r
+/** \r
+ * This component virtualizes access to the HAL of the MSP430 ADC12.\r
+ * Reference voltage is enabled automatically as required by the configuration.\r
+ * \r
+ * @author Jan Hauer \r
+ *\r
+ * @see  Please refer to the README.txt and TEP 101 for more information about\r
+ * this component and its intended use.\r
+ */\r
+\r
+generic configuration Msp430Adc12ClientAutoRVGC()\r
+{\r
+  provides {\r
+    interface Resource;\r
+    interface Msp430Adc12SingleChannel;\r
+  }\r
+  uses interface AdcConfigure<const msp430adc12_channel_config_t*>;\r
+} implementation {\r
+  components Msp430Adc12P, Msp430RefVoltArbiterP;\r
+\r
+  enum {\r
+    ID = unique(MSP430ADC12_RESOURCE),\r
+  };\r
+  Resource = Msp430RefVoltArbiterP.ClientResource[ID];\r
+  Msp430Adc12SingleChannel = Msp430Adc12P.SingleChannel[ID];\r
+  \r
+  Msp430RefVoltArbiterP.AdcResource[ID] -> Msp430Adc12P.Resource[ID];\r
+  AdcConfigure = Msp430RefVoltArbiterP.Config[ID]; \r
+}\r
diff --git a/tos/chips/msp430/adc12/Msp430Adc12DMAP.nc b/tos/chips/msp430/adc12/Msp430Adc12DMAP.nc
new file mode 100644 (file)
index 0000000..9f98dbb
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+#include <Msp430Adc12.h>
+#include <Msp430Dma.h>
+module Msp430Adc12DMAP 
+{
+  provides {
+    interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id];
+       }
+       uses {
+    interface Msp430DmaControl as DMAControl;
+    interface Msp430DmaChannel as DMAChannel;
+    interface Msp430Adc12SingleChannel as SubSingleChannel[uint8_t id];
+    interface AsyncStdControl as AsyncAdcControl[uint8_t id];
+       }
+}
+implementation
+{ 
+  enum {
+    MULTIPLE_SINGLE,
+    MULTIPLE_REPEAT,
+    MULTIPLE_SINGLE_AGAIN,
+  };
+
+  // norace declarations are safe here, because Msp430Adc12P.nc implements 
+  // a lock mechanism which guarantees that no two clients can access the ADC
+  // and the module variables below are only changed after the lock was acquired
+  norace uint8_t client;
+  norace uint8_t mode;
+  norace uint16_t *buffer;
+  norace uint16_t numSamples;
+
+  async command error_t SingleChannel.configureSingle[uint8_t id](
+      const msp430adc12_channel_config_t *config)
+  {
+    // don't use DMA for single conversions
+    return call SubSingleChannel.configureSingle[id](config);
+  }
+
+  async command error_t SingleChannel.configureSingleRepeat[uint8_t id](
+      const msp430adc12_channel_config_t *config,
+      uint16_t jiffies)
+  {
+    // don't use DMA for single conversions
+    return call SubSingleChannel.configureSingleRepeat[id](config, jiffies);
+  }
+  
+  error_t configure(uint8_t id, const msp430adc12_channel_config_t *config, 
+      uint16_t *buf, uint16_t length, uint16_t jiffies, uint8_t _mode)
+  {
+    // for multiple samples single-channel repat-conversion mode
+    // is used, because then there is only one interrupt at the
+    // the end of the whole sequence and DMA has done all the copying
+    error_t result = call SubSingleChannel.configureSingleRepeat[id](config, jiffies);
+    if (result == SUCCESS){
+      call DMAControl.init();
+      call DMAControl.setFlags(ENABLE_NMI, NOT_ROUND_ROBIN, ON_FETCH);
+      call DMAChannel.setupTransfer(
+        DMA_REPEATED_SINGLE_TRANSFER, 
+        DMA_TRIGGER_ADC12IFGx,
+        DMA_EDGE_SENSITIVE,
+        ADC12MEM,
+        buf,
+        length,
+        DMA_WORD,
+        DMA_WORD,
+        DMA_ADDRESS_UNCHANGED,
+        DMA_ADDRESS_INCREMENTED
+        );
+      call DMAChannel.startTransfer();
+      client = id;
+      mode = _mode;
+      buffer = buf;
+      numSamples = length;
+      call AsyncAdcControl.start[id]();
+    }
+    return result;
+  }
+
+  async command error_t SingleChannel.configureMultiple[uint8_t id](
+      const msp430adc12_channel_config_t *config,
+      uint16_t *buf, uint16_t length, uint16_t jiffies)
+  {
+    return configure(id, config, buf, length, jiffies, MULTIPLE_SINGLE);
+  }
+
+  async command error_t SingleChannel.configureMultipleRepeat[uint8_t id](
+      const msp430adc12_channel_config_t *config,
+      uint16_t *buf, uint8_t length, uint16_t jiffies)
+  {
+    return configure(id, config, buf, length, jiffies, MULTIPLE_REPEAT);
+  }
+
+  async command error_t SingleChannel.getData[uint8_t id]()
+  {
+    if (mode == MULTIPLE_SINGLE_AGAIN)
+      call DMAChannel.repeatTransfer(ADC12MEM, buffer, numSamples);
+    return call SubSingleChannel.getData[id]();
+  }
+  
+  async event error_t SubSingleChannel.singleDataReady[uint8_t id](uint16_t data)
+  {
+    // forward (only signalled if not in DMA mode)
+    return signal SingleChannel.singleDataReady[id](data);
+  }
+
+  async event uint16_t* SubSingleChannel.multipleDataReady[uint8_t id](uint16_t buf[], uint16_t num)
+  {
+    // will never get here
+    return 0;
+  }
+  
+  async event void DMAChannel.transferDone(error_t success)
+  {
+    uint16_t* next;
+    uint8_t oldMode = mode;
+    if (oldMode != MULTIPLE_REPEAT){
+      call AsyncAdcControl.stop[client]();
+      mode = MULTIPLE_SINGLE_AGAIN;
+    }
+    next = signal SingleChannel.multipleDataReady[client](buffer, numSamples);
+    if (oldMode == MULTIPLE_REPEAT)
+      if (next){
+        call DMAChannel.repeatTransfer(ADC12MEM, next, numSamples);
+        call AsyncAdcControl.start[client]();
+      } else
+        call AsyncAdcControl.stop[client]();
+  }
+
+  default async command error_t SubSingleChannel.configureSingle[uint8_t id](
+      const msp430adc12_channel_config_t *config)
+  { return FAIL; }
+
+  default async command error_t SubSingleChannel.configureSingleRepeat[uint8_t id](
+      const msp430adc12_channel_config_t *config, uint16_t jiffies)
+  { return FAIL; }
+  
+  default async command error_t SubSingleChannel.configureMultiple[uint8_t id]( 
+      const msp430adc12_channel_config_t
+      *config, uint16_t buf[], uint16_t num, uint16_t jiffies)
+  { return FAIL; }
+
+  default async command error_t SubSingleChannel.configureMultipleRepeat[uint8_t id](
+      const msp430adc12_channel_config_t *config, uint16_t buf[], uint8_t
+      num, uint16_t jiffies)
+  { return FAIL; }
+
+  default async command error_t SubSingleChannel.getData[uint8_t id]()
+  { return FAIL;}
+
+  default async event error_t SingleChannel.singleDataReady[uint8_t id](
+      uint16_t data)
+  { return FAIL; }
+
+  default async event uint16_t* SingleChannel.multipleDataReady[uint8_t id](
+      uint16_t buf[], uint16_t num)
+  { return 0;}
+  
+  default async command error_t AsyncAdcControl.stop[uint8_t id]()
+  { return FAIL; }
+  default async command error_t AsyncAdcControl.start[uint8_t id]()
+  { return FAIL; }
+}
diff --git a/tos/chips/msp430/adc12/Msp430Adc12ImplP.nc b/tos/chips/msp430/adc12/Msp430Adc12ImplP.nc
new file mode 100644 (file)
index 0000000..4b5c3ff
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+#include <Msp430Adc12.h>
+module Msp430Adc12ImplP 
+{
+  provides {
+    interface Init;
+    interface Msp430Adc12SingleChannel as SingleChannel[uint8_t id];
+    interface AsyncStdControl as DMAExtension[uint8_t id];
+       }
+       uses {
+    interface ArbiterInfo as ADCArbiterInfo;
+         interface HplAdc12;
+    interface Msp430Timer as TimerA;;
+    interface Msp430TimerControl as ControlA0;
+    interface Msp430TimerControl as ControlA1;
+    interface Msp430Compare as CompareA0;
+    interface Msp430Compare as CompareA1;
+    interface HplMsp430GeneralIO as Port60;
+    interface HplMsp430GeneralIO as Port61;
+    interface HplMsp430GeneralIO as Port62;
+    interface HplMsp430GeneralIO as Port63;
+    interface HplMsp430GeneralIO as Port64;
+    interface HplMsp430GeneralIO as Port65;
+    interface HplMsp430GeneralIO as Port66;
+    interface HplMsp430GeneralIO as Port67;
+       }
+}
+implementation
+{ 
+  enum {
+    SINGLE_DATA = 1,
+    SINGLE_DATA_REPEAT = 2,
+    MULTIPLE_DATA = 4,
+    MULTIPLE_DATA_REPEAT = 8,
+    CONVERSION_MODE_MASK = 0x0F,
+
+    ADC_BUSY = 16,                /* request pending */
+    USE_TIMERA = 32,              /* TimerA used for SAMPCON signal */
+  };
+
+  uint8_t state;                  /* see enum above */
+  
+  uint16_t *resultBuffer;  /* conversion results */
+  uint16_t resultBufferLength;    /* length of buffer */
+  uint16_t resultBufferIndex;     /* offset into buffer */
+  uint8_t clientID;               /* ID of client that called getData() */
+
+  command error_t Init.init()
+  {
+    call HplAdc12.stopConversion();
+    return SUCCESS;
+  }
+
+  void prepareTimerA(uint16_t interval, uint16_t csSAMPCON, uint16_t cdSAMPCON)
+  {
+    msp430_compare_control_t ccResetSHI = {
+      ccifg : 0, cov : 0, out : 0, cci : 0, ccie : 0,
+      outmod : 0, cap : 0, clld : 0, scs : 0, ccis : 0, cm : 0 };
+
+    call TimerA.setMode(MSP430TIMER_STOP_MODE);
+    call TimerA.clear();
+    call TimerA.disableEvents();
+    call TimerA.setClockSource(csSAMPCON);
+    call TimerA.setInputDivider(cdSAMPCON);
+    call ControlA0.setControl(ccResetSHI);
+    call CompareA0.setEvent(interval-1);
+    call CompareA1.setEvent((interval-1)/2);
+  }
+    
+  void startTimerA()
+  {
+    msp430_compare_control_t ccSetSHI = {
+      ccifg : 0, cov : 0, out : 1, cci : 0, ccie : 0,
+      outmod : 0, cap : 0, clld : 0, scs : 0, ccis : 0, cm : 0 };
+    msp430_compare_control_t ccResetSHI = {
+      ccifg : 0, cov : 0, out : 0, cci : 0, ccie : 0,
+      outmod : 0, cap : 0, clld : 0, scs : 0, ccis : 0, cm : 0 };
+    msp430_compare_control_t ccRSOutmod = {
+      ccifg : 0, cov : 0, out : 0, cci : 0, ccie : 0,
+      outmod : 7, cap : 0, clld : 0, scs : 0, ccis : 0, cm : 0 };
+    // manually trigger first conversion, then switch to Reset/set conversionMode
+    call ControlA1.setControl(ccResetSHI);
+    call ControlA1.setControl(ccSetSHI);   
+    //call ControlA1.setControl(ccResetSHI); 
+    call ControlA1.setControl(ccRSOutmod);
+    call TimerA.setMode(MSP430TIMER_UP_MODE); // go!
+  }   
+  
+  void configureAdcPin( uint8_t inch )
+  {
+#ifdef P6PIN_AUTO_CONFIGURE
+    switch (inch)
+    {
+      case 0: call Port60.selectModuleFunc(); call Port60.makeInput(); break;
+      case 1: call Port61.selectModuleFunc(); call Port61.makeInput(); break;
+      case 2: call Port62.selectModuleFunc(); call Port62.makeInput(); break;
+      case 3: call Port63.selectModuleFunc(); call Port63.makeInput(); break;
+      case 4: call Port64.selectModuleFunc(); call Port64.makeInput(); break;
+      case 5: call Port65.selectModuleFunc(); call Port65.makeInput(); break;
+      case 6: call Port66.selectModuleFunc(); call Port66.makeInput(); break;
+      case 7: call Port67.selectModuleFunc(); call Port67.makeInput(); break;
+    }
+#endif
+  }
+  
+  void resetAdcPin( uint8_t inch )
+  {
+#ifdef P6PIN_AUTO_CONFIGURE
+    switch (inch)
+    {
+      case 0: call Port60.selectIOFunc(); break;
+      case 1: call Port61.selectIOFunc(); break;
+      case 2: call Port62.selectIOFunc(); break;
+      case 3: call Port63.selectIOFunc(); break;
+      case 4: call Port64.selectIOFunc(); break;
+      case 5: call Port65.selectIOFunc(); break;
+      case 6: call Port66.selectIOFunc(); break;
+      case 7: call Port67.selectIOFunc(); break;
+    }
+#endif
+  }
+  
+  async command error_t SingleChannel.configureSingle[uint8_t id](
+      const msp430adc12_channel_config_t *config)
+  {
+    error_t result = ERESERVE;
+#ifdef CHECK_ARGS
+    if (!config)
+      return EINVAL;
+#endif
+    atomic {
+      if (state & ADC_BUSY)
+        return EBUSY;
+      if (call ADCArbiterInfo.userId() == id){
+        adc12ctl1_t ctl1 = {
+          adc12busy: 0,
+          conseq: 0,
+          adc12ssel: config->adc12ssel,
+          adc12div: config->adc12div,
+          issh: 0,
+          shp: 1,
+          shs: 0,
+          cstartadd: 0
+        };
+        adc12memctl_t memctl = {
+          inch: config->inch,
+          sref: config->sref,
+          eos: 1
+        };        
+        adc12ctl0_t ctl0 = call HplAdc12.getCtl0();
+        ctl0.msc = 1;
+        ctl0.sht0 = config->sht;
+        ctl0.sht1 = config->sht;
+
+        state = SINGLE_DATA;
+        call HplAdc12.setCtl0(ctl0);
+        call HplAdc12.setCtl1(ctl1);
+        call HplAdc12.setMCtl(0, memctl);
+        call HplAdc12.setIEFlags(0x01);
+        result = SUCCESS;
+      } 
+    }
+    return result;
+  }
+
+  async command error_t SingleChannel.configureSingleRepeat[uint8_t id](
+      const msp430adc12_channel_config_t *config,
+      uint16_t jiffies)
+  {
+    error_t result = ERESERVE;
+#ifdef CHECK_ARGS
+    if (!config || jiffies == 1 || jiffies == 2)
+      return EINVAL;
+#endif
+    atomic {
+      if (state & ADC_BUSY)
+        return EBUSY;
+      if (call ADCArbiterInfo.userId() == id) {
+        adc12ctl1_t ctl1 = {
+          adc12busy: 0,
+          conseq: 2,
+          adc12ssel: config->adc12ssel,
+          adc12div: config->adc12div,
+          issh: 0,
+          shp: 1,
+          shs: (jiffies == 0) ? 0 : 1,
+          cstartadd: 0
+        };
+        adc12memctl_t memctl = {
+          inch: config->inch,
+          sref: config->sref,
+          eos: 1
+        };        
+        adc12ctl0_t ctl0 = call HplAdc12.getCtl0();
+        ctl0.msc = (jiffies == 0) ? 1 : 0;
+        ctl0.sht0 = config->sht;
+        ctl0.sht1 = config->sht;
+
+        state = SINGLE_DATA_REPEAT;
+        call HplAdc12.setCtl0(ctl0);
+        call HplAdc12.setCtl1(ctl1);
+        call HplAdc12.setMCtl(0, memctl);
+        call HplAdc12.setIEFlags(0x01);
+        if (jiffies){
+          state |= USE_TIMERA;   
+          prepareTimerA(jiffies, config->sampcon_ssel, config->sampcon_id);
+        }
+        result = SUCCESS;
+      }     
+    }
+    return result;
+  }
+
+  async command error_t SingleChannel.configureMultiple[uint8_t id](
+      const msp430adc12_channel_config_t *config,
+      uint16_t *buf, uint16_t length, uint16_t jiffies)
+  {
+    error_t result = ERESERVE;
+#ifdef CHECK_ARGS
+    if (!config || !buf || !length || jiffies == 1 || jiffies == 2)
+      return EINVAL;
+#endif
+    atomic {
+      if (state & ADC_BUSY)
+        return EBUSY;
+      if (call ADCArbiterInfo.userId() == id){
+        adc12ctl1_t ctl1 = {
+          adc12busy: 0,
+          conseq: (length > 16) ? 3 : 1,
+          adc12ssel: config->adc12ssel,
+          adc12div: config->adc12div,
+          issh: 0,
+          shp: 1,
+          shs: (jiffies == 0) ? 0 : 1,
+          cstartadd: 0
+        };
+        adc12memctl_t memctl = {
+          inch: config->inch,
+          sref: config->sref,
+          eos: 0
+        };        
+        uint16_t i, mask = 1;
+        adc12ctl0_t ctl0 = call HplAdc12.getCtl0();
+        ctl0.msc = (jiffies == 0) ? 1 : 0;
+        ctl0.sht0 = config->sht;
+        ctl0.sht1 = config->sht;
+
+        state = MULTIPLE_DATA;
+        resultBuffer = buf;
+        resultBufferLength = length;
+        resultBufferIndex = 0;
+        call HplAdc12.setCtl0(ctl0);
+        call HplAdc12.setCtl1(ctl1);
+        for (i=0; i<(length-1) && i < 15; i++)
+          call HplAdc12.setMCtl(i, memctl);
+        memctl.eos = 1;  
+        call HplAdc12.setMCtl(i, memctl);
+        call HplAdc12.setIEFlags(mask << i);        
+        
+        if (jiffies){
+          state |= USE_TIMERA;
+          prepareTimerA(jiffies, config->sampcon_ssel, config->sampcon_id);
+        }
+        result = SUCCESS;
+      }      
+    }
+    return result;
+  }
+
+  async command error_t SingleChannel.configureMultipleRepeat[uint8_t id](
+      const msp430adc12_channel_config_t *config,
+      uint16_t *buf, uint8_t length, uint16_t jiffies)
+  {
+    error_t result = ERESERVE;
+#ifdef CHECK_ARGS
+    if (!config || !buf || !length || length > 16 || jiffies == 1 || jiffies == 2)
+      return EINVAL;
+#endif
+    atomic {
+      if (state & ADC_BUSY)
+        return EBUSY;
+      if (call ADCArbiterInfo.userId() == id){
+        adc12ctl1_t ctl1 = {
+          adc12busy: 0,
+          ctl1.conseq = 3,
+          adc12ssel: config->adc12ssel,
+          adc12div: config->adc12div,
+          issh: 0,
+          shp: 1,
+          shs: (jiffies == 0) ? 0 : 1,
+          cstartadd: 0
+        };
+        adc12memctl_t memctl = {
+          inch: config->inch,
+          sref: config->sref,
+          eos: 0
+        };        
+        uint16_t i, mask = 1;
+        adc12ctl0_t ctl0 = call HplAdc12.getCtl0();
+        ctl0.msc = (jiffies == 0) ? 1 : 0;
+        ctl0.sht0 = config->sht;
+        ctl0.sht1 = config->sht;
+
+        state = MULTIPLE_DATA_REPEAT;
+        resultBuffer = buf;
+        resultBufferLength = length;
+        resultBufferIndex = 0;            
+        
+        call HplAdc12.setCtl0(ctl0);
+        call HplAdc12.setCtl1(ctl1);
+        for (i=0; i<(length-1) && i < 15; i++)
+          call HplAdc12.setMCtl(i, memctl);
+        memctl.eos = 1;  
+        call HplAdc12.setMCtl(i, memctl);
+        call HplAdc12.setIEFlags(mask << i);        
+        
+        if (jiffies){
+          state |= USE_TIMERA;
+          prepareTimerA(jiffies, config->sampcon_ssel, config->sampcon_id);
+        }
+        result = SUCCESS;
+      }
+    }
+    return result;
+  }
+
+  async command error_t SingleChannel.getData[uint8_t id]()
+  {
+    atomic {
+      if (call ADCArbiterInfo.userId() == id){
+        if (state & MULTIPLE_DATA_REPEAT && !resultBuffer)
+          return EINVAL;
+        if (state & ADC_BUSY)
+          return EBUSY;
+        state |= ADC_BUSY;
+        clientID = id;
+        configureAdcPin((call HplAdc12.getMCtl(0)).inch);
+        call HplAdc12.startConversion();
+        if (state & USE_TIMERA)
+          startTimerA(); 
+        return SUCCESS;
+      }
+    }
+    return FAIL;
+  }
+
+  void stopConversion()
+  {
+    adc12memctl_t memctl = call HplAdc12.getMCtl(0);
+    if (state & USE_TIMERA)
+      call TimerA.setMode(MSP430TIMER_STOP_MODE);
+    resetAdcPin( memctl.inch );
+    call HplAdc12.stopConversion();
+    call HplAdc12.resetIFGs(); 
+    state &= ~ADC_BUSY;
+  }
+
+  async command error_t DMAExtension.start[uint8_t id]()
+  { 
+    atomic {
+      if (call ADCArbiterInfo.userId() == id){
+        call HplAdc12.setIEFlags(0);
+        call HplAdc12.resetIFGs();
+        return SUCCESS;
+      }
+    }
+    return FAIL;
+  }
+  
+  async command error_t DMAExtension.stop[uint8_t id]()
+  {
+    atomic {
+      if (call ADCArbiterInfo.userId() == id){
+        stopConversion();
+        return SUCCESS;
+      }
+    }
+    return FAIL;
+  }
+  
+  async event void TimerA.overflow(){}
+  async event void CompareA0.fired(){}
+  async event void CompareA1.fired(){}
+
+  async event void HplAdc12.conversionDone(uint16_t iv)
+  {
+    switch (state & CONVERSION_MODE_MASK) 
+    { 
+      case SINGLE_DATA:
+        stopConversion();
+        signal SingleChannel.singleDataReady[clientID](call HplAdc12.getMem(0));
+        break;
+      case SINGLE_DATA_REPEAT:
+        {
+          error_t repeatContinue;
+          repeatContinue = signal SingleChannel.singleDataReady[clientID](
+                call HplAdc12.getMem(0));
+          if (repeatContinue == FAIL)
+            stopConversion();
+          break;
+        }
+      case MULTIPLE_DATA:
+        {
+          uint16_t i = 0, length;
+          if (resultBufferLength - resultBufferIndex > 16) 
+            length = 16;
+          else
+            length = resultBufferLength - resultBufferIndex;
+          do {
+            *resultBuffer++ = call HplAdc12.getMem(i);
+          } while (++i < length);
+          resultBufferIndex += length;
+              
+          if (resultBufferLength - resultBufferIndex > 15)
+            return;
+          else if (resultBufferLength - resultBufferIndex > 0){
+            adc12memctl_t memctl = call HplAdc12.getMCtl(0);
+            memctl.eos = 1;
+            call HplAdc12.setMCtl(resultBufferLength - resultBufferIndex, memctl);
+          } else {
+            stopConversion();
+            resultBuffer -= resultBufferLength;
+            resultBufferIndex = 0;
+            signal SingleChannel.multipleDataReady[clientID](resultBuffer, resultBufferLength);
+          }
+        }
+        break;
+      case MULTIPLE_DATA_REPEAT:
+        {
+          uint8_t i = 0;
+          do {
+            *resultBuffer++ = call HplAdc12.getMem(i);
+          } while (++i < resultBufferLength);
+          
+          resultBuffer = signal SingleChannel.multipleDataReady[clientID](
+              resultBuffer-resultBufferLength,
+                    resultBufferLength);
+          if (!resultBuffer)  
+            stopConversion();
+          break;
+        }
+      } // switch
+  }
+
+  default async event error_t SingleChannel.singleDataReady[uint8_t id](uint16_t data)
+  {
+    return FAIL;
+  }
+   
+  default async event uint16_t* SingleChannel.multipleDataReady[uint8_t id](
+      uint16_t *buf, uint16_t length)
+  {
+    return 0;
+  }
+  
+  async event void HplAdc12.memOverflow(){}
+  async event void HplAdc12.conversionTimeOverflow(){}
+
+}
+
diff --git a/tos/chips/msp430/adc12/Msp430RefVoltArbiterImplP.nc b/tos/chips/msp430/adc12/Msp430RefVoltArbiterImplP.nc
new file mode 100644 (file)
index 0000000..afe625e
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2006, Technische Universität Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische 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.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+module Msp430RefVoltArbiterImplP
+{
+  provides interface Resource as ClientResource[uint8_t client];
+  uses {
+    interface Resource as AdcResource[uint8_t client];
+    interface SplitControl as RefVolt_1_5V;
+    interface SplitControl as RefVolt_2_5V;  
+    interface AdcConfigure<const msp430adc12_channel_config_t*> as Config[uint8_t client];
+  }
+} implementation {
+  enum {
+    NO_OWNER = 0xFF,
+  };
+  norace uint8_t owner = NO_OWNER;
+
+  task void switchOff();
+  
+  async command error_t ClientResource.request[uint8_t client]()
+  {
+    return call AdcResource.request[client]();
+  }
+   
+  async command error_t ClientResource.immediateRequest[uint8_t client]()
+  {
+    const msp430adc12_channel_config_t* settings = call Config.getConfiguration[client]();
+    if (settings->sref == REFERENCE_VREFplus_AVss ||
+        settings->sref == REFERENCE_VREFplus_VREFnegterm)
+      // always fails, because of the possible start-up delay (and async-sync transition)
+      return FAIL;
+    else {
+      error_t request = call AdcResource.immediateRequest[client]();
+      if (request == SUCCESS)
+        owner = client;
+      return request;
+    }
+  }
+
+  event void AdcResource.granted[uint8_t client]()
+  {
+    const msp430adc12_channel_config_t* settings  = call Config.getConfiguration[client]();
+    owner = client;
+    if (settings->sref == REFERENCE_VREFplus_AVss ||
+        settings->sref == REFERENCE_VREFplus_VREFnegterm){
+      error_t started;
+      if (settings->ref2_5v == REFVOLT_LEVEL_1_5)
+        started = call RefVolt_1_5V.start();
+      else
+        started = call RefVolt_2_5V.start();
+      if (started != SUCCESS){
+        owner = NO_OWNER;
+        call AdcResource.release[client]();
+        call AdcResource.request[client]();
+      }
+    } else 
+      signal ClientResource.granted[client]();
+  }
+   
+  event void RefVolt_1_5V.startDone(error_t error)
+  {
+    if (owner != NO_OWNER){
+      // Note that it can still not be guaranteed that ClientResource.granted()
+      // is not signalled after ClientResource.release() has been called.
+      signal ClientResource.granted[owner]();
+    }
+  }
+   
+  event void RefVolt_2_5V.startDone(error_t error)
+  {
+    if (owner != NO_OWNER){
+      // Note that it can still not be guaranteed that ClientResource.granted()
+      // is not signalled after ClientResource.release() has been called.
+      signal ClientResource.granted[owner]();
+    }
+  }
+
+  async command error_t ClientResource.release[uint8_t client]()
+  {
+    atomic {
+      if (owner == client){
+        owner = NO_OWNER;
+        post switchOff();
+      }
+    }
+    return call AdcResource.release[client]();
+  }
+
+  task void switchOff()
+  {
+    if (owner == NO_OWNER)
+      if (call RefVolt_1_5V.stop() != SUCCESS)
+        post switchOff();
+  }
+
+  event void RefVolt_1_5V.stopDone(error_t error)
+  {
+  }
+  
+  event void RefVolt_2_5V.stopDone(error_t error)
+  {
+  }
+
+  async command uint8_t ClientResource.isOwner[uint8_t client]()
+  {
+    return call AdcResource.isOwner[client]();
+  }
+
+  default event void ClientResource.granted[uint8_t client](){}
+  default async command error_t AdcResource.request[uint8_t client]()
+  {
+    return FAIL;
+  }
+  default async command error_t AdcResource.immediateRequest[uint8_t client]()
+  {
+    return FAIL;
+  }
+  default async command bool AdcResource.isOwner[uint8_t client]() { return FALSE; }
+  default async command error_t AdcResource.release[uint8_t client](){return FAIL;}
+  const msp430adc12_channel_config_t defaultConfig = {INPUT_CHANNEL_NONE,0,0,0,0,0,0,0}; 
+  default async command const msp430adc12_channel_config_t*
+    Config.getConfiguration[uint8_t client]()
+  { 
+    return &defaultConfig;
+  }
+}  
+
diff --git a/tos/chips/msp430/adc12/README.txt b/tos/chips/msp430/adc12/README.txt
new file mode 100644 (file)
index 0000000..377a7e6
--- /dev/null
@@ -0,0 +1,68 @@
+The implementation of the 12-bit ADC stack on the MSP430 is in compliance with
+TEP 101 (tinyos-2.x/doc/txt/tep101.txt) and provides virtualized access to the
+ADC12 by seven different components: AdcReadClientC, AdcReadNowClientC,
+AdcReadStreamClientC, Msp430Adc12ClientC, Msp430Adc12ClientAutoDMAC,
+Msp430Adc12ClientAutoRVGC and Msp430Adc12ClientAutoDMA_RVGC. A client
+component may wire to any of these components and it SHOULD NOT wire to any
+other components in 'tinyos-2.x/tos/chips/msp430/adc12'. This document
+explains the difference between the seven components.
+
+
+A platform-independent application (an application like 'Oscilloscope' that is
+supposed to run on, for example, the 'telosb' and 'micaz' platform at the same
+time) cannot wire to an MSP430-specific interface like Msp430Adc12SingleChannel
+(there is no MSP430 on micaz).  Instead such an application may access the
+MSP430 ADC through any of the three following components:
+
+  * AdcReadClientC: to read single ADC values
+  * AdcReadNowClientC: to read single ADC values asynchronously (fast)
+  * AdcReadStreamClientC: to read multiple ADC values
+
+These components are less efficient than the MSP430-specific ADC components
+(described below), but they provide standard TinyOS interfaces for reading ADC
+values. Thus, if a client component does not care so much about efficiency but
+rather about portability it should wire to any of these components.
+
+
+An application that is written for an MSP430-based platform like 'eyesIFX' or
+'telosb' can access the ADC12 in a more efficient way to, for example, do
+high-frequency sampling through the Msp430Adc12SingleChannel interface. On the
+MSP430 two additional hardware modules may become relevant when the ADC12 is
+used: the internal reference voltage generator and the DMA controller. The
+voltage generator outputs stabilized voltage of 1.5 V or 2.5 V, which may be
+used as reference voltage in the conversion process. Whether the internal
+reference voltage generator should be enabled during the conversion is
+platform-specific (e.g. the light sensor on the 'eyesIFX' requires a stable
+reference voltage). When an application requires a stable reference voltage
+during the sampling process it should wire to the Msp430Adc12ClientAutoRVGC
+component. This assures that when the app is signalled the Resource.granted()
+event the reference voltage generator outputs a stable voltage (the level is
+defined in the configuration data supplied by the application). The DMA
+controller can be used to efficiently copy conversion data from ADC data
+registers to the application buffer. DMA is only present on MSP430x15x and
+MSP430x16x devices. When an application wants to use the DMA it can wire to
+the Msp430Adc12ClientAutoDMAC component and then conversion results are
+transferred using DMA. Both, enabling the reference generator and using the
+DMA, therefore happens transparent to the app. There are four possible
+combinations reflected by the following components that an MSP430-based
+application may wire to:
+
+  * Msp430Adc12ClientC: no DMA, no automatic reference voltage
+  * Msp430Adc12ClientAutoRVGC: automatic reference voltage, but no DMA
+  * Msp430Adc12ClientAutoDMAC: DMA, but no automatic reference voltage
+  * Msp430Adc12ClientAutoDMA_RVGC: DMA and automatic reference voltage
+
+During a conversion the respective ADC port pin (ports 6.0 - 6.7) must be
+configured such that the peripheral module function is selected and the port
+pin is switched to input direction. By default, for every client this is done
+**automatically** in the ADC stack (Msp430Adc12ImplP), i.e. just before the
+conversion starts the respective pin is switched to peripheral module function
+and input direction and immediately after the conversion has finished it is
+switched to I/O function mode. To disable this feature please comment out the
+"P6PIN_AUTO_CONFIGURE" macro in Msp430Adc12.h.
+
+-----
+
+$Date$
+@author: Jan Hauer <hauer@tkn.tu-berlin.de>
+
diff --git a/tos/chips/msp430/timer/Alarm32khz16C.nc b/tos/chips/msp430/timer/Alarm32khz16C.nc
new file mode 100644 (file)
index 0000000..463d0a8
--- /dev/null
@@ -0,0 +1,47 @@
+
+/* "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement
+ * is hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
+ * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * Alarm32khzC is the alarm for async 32khz alarms
+ *
+ * @author Cory Sharp <cssharp@eecs.berkeley.edu>
+ * @see  Please refer to TEP 102 for more information about this component and its
+ *          intended use.
+ */
+
+generic configuration Alarm32khz16C()
+{
+  provides interface Init;
+  provides interface Alarm<T32khz,uint16_t>;
+}
+implementation
+{
+  components new Msp430Timer32khzC() as Msp430Timer;
+  components new Msp430AlarmC(T32khz) as Msp430Alarm;
+
+  Init = Msp430Alarm;
+  Alarm = Msp430Alarm;
+
+  Msp430Alarm.Msp430Timer -> Msp430Timer;
+  Msp430Alarm.Msp430TimerControl -> Msp430Timer;
+  Msp430Alarm.Msp430Compare -> Msp430Timer;
+}
+
diff --git a/tos/chips/msp430/timer/Alarm32khz32C.nc b/tos/chips/msp430/timer/Alarm32khz32C.nc
new file mode 100644 (file)
index 0000000..be9ca2d
--- /dev/null
@@ -0,0 +1,47 @@
+
+/* "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement
+ * is hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
+ * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * Alarm32khzC is the alarm for async 32khz alarms
+ *
+ * @author Cory Sharp <cssharp@eecs.berkeley.edu>
+ * @see  Please refer to TEP 102 for more information about this component and its
+ *          intended use.
+ */
+
+generic configuration Alarm32khz32C()
+{
+  provides interface Init;
+  provides interface Alarm<T32khz,uint32_t>;
+}
+implementation
+{
+  components new Alarm32khz16C() as AlarmC;
+  components Counter32khz32C as Counter;
+  components new TransformAlarmC(T32khz,uint32_t,T32khz,uint16_t,0) as Transform;
+
+  Init = AlarmC;
+  Alarm = Transform;
+
+  Transform.AlarmFrom -> AlarmC;
+  Transform.Counter -> Counter;
+}
+
diff --git a/tos/chips/msp430/timer/AlarmMilli16C.nc b/tos/chips/msp430/timer/AlarmMilli16C.nc
new file mode 100644 (file)
index 0000000..4fec742
--- /dev/null
@@ -0,0 +1,47 @@
+
+/* "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement
+ * is hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
+ * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * AlarmMilliC is the alarm for async millisecond alarms
+ *
+ * @author Cory Sharp <cssharp@eecs.berkeley.edu>
+ * @see  Please refer to TEP 102 for more information about this component and its
+ *          intended use.
+ */
+generic configuration AlarmMilli16C()
+{
+  provides interface Init;
+  provides interface Alarm<TMilli,uint16_t>;
+}
+implementation
+{
+  components new Alarm32khz16C() as AlarmFrom;
+  components CounterMilli16C as Counter;
+  components new TransformAlarmC(TMilli,uint16_t,T32khz,uint16_t,5) as Transform;
+
+  Init = AlarmFrom;
+  Alarm = Transform;
+
+  Transform.AlarmFrom -> AlarmFrom;
+  Transform.Counter -> Counter;
+}
+
diff --git a/tos/chips/msp430/timer/AlarmMilli32C.nc b/tos/chips/msp430/timer/AlarmMilli32C.nc
new file mode 100644 (file)
index 0000000..d222764
--- /dev/null
@@ -0,0 +1,47 @@
+
+/* "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement
+ * is hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
+ * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * AlarmMilliC is the alarm for async millisecond alarms
+ *
+ * @author Cory Sharp <cssharp@eecs.berkeley.edu>
+ * @see  Please refer to TEP 102 for more information about this component and its
+ *          intended use.
+ */
+generic configuration AlarmMilli32C()
+{
+  provides interface Init;
+  provides interface Alarm<TMilli,uint32_t>;
+}
+implementation
+{
+  components new Alarm32khz16C() as AlarmFrom;
+  components CounterMilli32C as Counter;
+  components new TransformAlarmC(TMilli,uint32_t,T32khz,uint16_t,5) as Transform;
+
+  Init = AlarmFrom;
+  Alarm = Transform;
+
+  Transform.AlarmFrom -> AlarmFrom;
+  Transform.Counter -> Counter;
+}
+
diff --git a/tos/chips/msp430/timer/Counter32khz16C.nc b/tos/chips/msp430/timer/Counter32khz16C.nc
new file mode 100644 (file)
index 0000000..3d272f2
--- /dev/null
@@ -0,0 +1,40 @@
+
+/* "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement
+ * is hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
+ * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * Counter32khz16C provides at 16-bit counter at 32768 ticks per second.
+ *
+ * @author Cory Sharp <cssharp@eecs.berkeley.edu>
+ * @see  Please refer to TEP 102 for more information about this component and its
+ *          intended use.
+ */
+
+configuration Counter32khz16C
+{
+  provides interface Counter<T32khz,uint16_t>;
+}
+implementation
+{
+  components Msp430Counter32khzC as CounterFrom;
+
+  Counter = CounterFrom;
+}
+
diff --git a/tos/chips/msp430/timer/Counter32khz32C.nc b/tos/chips/msp430/timer/Counter32khz32C.nc
new file mode 100644 (file)
index 0000000..e391624
--- /dev/null
@@ -0,0 +1,43 @@
+
+/* "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement
+ * is hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
+ * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * Counter32khz32C provides at 32-bit counter at 32768 ticks per second.
+ *
+ * @author Cory Sharp <cssharp@eecs.berkeley.edu>
+ * @see  Please refer to TEP 102 for more information about this component and its
+ *          intended use.
+ */
+
+configuration Counter32khz32C
+{
+  provides interface Counter<T32khz,uint32_t>;
+}
+implementation
+{
+  components Msp430Counter32khzC as CounterFrom;
+  components new TransformCounterC(T32khz,uint32_t,T32khz,uint16_t,0,uint16_t) as Transform;
+
+  Counter = Transform;
+
+  Transform.CounterFrom -> CounterFrom;
+}
+
diff --git a/tos/chips/msp430/timer/CounterMilli16C.nc b/tos/chips/msp430/timer/CounterMilli16C.nc
new file mode 100644 (file)
index 0000000..ee3b880
--- /dev/null
@@ -0,0 +1,43 @@
+
+/* "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement
+ * is hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
+ * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * CounterMilli16C provides at 16-bit counter at 1024 ticks per second.
+ *
+ * @author Cory Sharp <cssharp@eecs.berkeley.edu>
+ * @see  Please refer to TEP 102 for more information about this component and its
+ *          intended use.
+ */
+    
+configuration CounterMilli16C
+{
+  provides interface Counter<TMilli,uint16_t>;
+}
+implementation
+{
+  components Msp430Counter32khzC as CounterFrom;
+  components new TransformCounterC(TMilli,uint16_t,T32khz,uint16_t,5,uint8_t) as Transform;
+
+  Counter = Transform.Counter;
+
+  Transform.CounterFrom -> CounterFrom;
+}
+
diff --git a/tos/chips/msp430/timer/CounterMilli32C.nc b/tos/chips/msp430/timer/CounterMilli32C.nc
new file mode 100644 (file)
index 0000000..e8de47e
--- /dev/null
@@ -0,0 +1,43 @@
+
+/* "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement
+ * is hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
+ * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * CounterMilli32C provides at 32-bit counter at 1024 ticks per second.
+ *
+ * @author Cory Sharp <cssharp@eecs.berkeley.edu>
+ * @see  Please refer to TEP 102 for more information about this component and its
+ *          intended use.
+ */
+    
+configuration CounterMilli32C
+{
+  provides interface Counter<TMilli,uint32_t>;
+}
+implementation
+{
+  components Msp430Counter32khzC as CounterFrom;
+  components new TransformCounterC(TMilli,uint32_t,T32khz,uint16_t,5,uint32_t) as Transform;
+
+  Counter = Transform.Counter;
+
+  Transform.CounterFrom -> CounterFrom;
+}
+
diff --git a/tos/chips/msp430/usart/HplMsp430I2C.nc b/tos/chips/msp430/usart/HplMsp430I2C.nc
new file mode 100644 (file)
index 0000000..8f2f8e9
--- /dev/null
@@ -0,0 +1,102 @@
+
+#include <msp430usart.h>
+
+interface HplMsp430I2C {
+  
+  async command bool isI2C();
+  async command void clearModeI2C();
+  async command void setModeI2C( msp430_i2c_config_t* config );
+  
+  // U0CTL
+  async command void setMasterMode();
+  async command void setSlaveMode();
+  
+  async command void enableI2C();
+  async command void disableI2C();
+  
+  // I2CTCTL
+  async command bool getWordMode();
+  async command void setWordMode( bool mode );
+
+  async command bool getRepeatMode();
+  async command void setRepeatMode( bool mode );
+  
+  async command uint8_t getClockSource();
+  async command void setClockSource( uint8_t src );
+  
+  async command bool getTransmitReceiveMode();
+  async command void setTransmitMode();
+  async command void setReceiveMode();
+  
+  async command bool getStartByte();
+  async command void setStartByte();
+  
+  async command bool getStopBit();
+  async command void setStopBit();
+  
+  async command bool getStartBit();
+  async command void setStartBit();
+  
+  // I2CDR
+  async command uint8_t getData();
+  async command void setData( uint8_t data );
+  
+  // I2CNDAT
+  async command uint8_t getTransferByteCount();
+  async command void setTransferByteCount( uint8_t count );
+  
+  // I2CPSC
+  async command uint8_t getClockPrescaler();
+  async command void setClockPrescaler( uint8_t scaler );
+  
+  // I2CSCLH and I2CSCLL
+  async command uint16_t getShiftClock();
+  async command void setShiftClock( uint16_t shift );
+  
+  // I2COA
+  async command uint16_t getOwnAddress();
+  async command void setOwnAddress( uint16_t addr );
+  
+  // I2CSA
+  async command uint16_t getSlaveAddress();
+  async command void setSlaveAddress( uint16_t addr );
+  
+  // I2CIE
+  async command void disableStartDetect();
+  async command void enableStartDetect();
+  
+  async command void disableGeneralCall();
+  async command void enableGeneralCall();
+  
+  async command void disableTransmitReady();
+  async command void enableTransmitReady();
+  
+  async command void disableReceiveReady();
+  async command void enableReceiveReady();
+  
+  async command void disableAccessReady();
+  async command void enableAccessReady();
+  
+  async command void disableOwnAddress();
+  async command void enableOwnAddress();
+  
+  async command void disableNoAck();
+  async command void enableNoAck();
+  
+  async command void disableArbitrationLost();
+  async command void enableArbitrationLost();
+  
+  // I2CIFG
+  async command bool isStartDetectPending();
+  async command bool isGeneralCallPending();
+  async command bool isTransmitReadyPending();
+  async command bool isReceiveReadyPending();
+  async command bool isAccessReadyPending();
+  async command bool isOwnAddressPending();
+  async command bool isNoAckPending();
+  async command bool isArbitrationLostPending();
+  
+  // I2CIV
+  async command uint8_t getIV();
+  
+}
diff --git a/tos/chips/msp430/usart/HplMsp430I2C0C.nc b/tos/chips/msp430/usart/HplMsp430I2C0C.nc
new file mode 100644 (file)
index 0000000..7102814
--- /dev/null
@@ -0,0 +1,21 @@
+
+configuration HplMsp430I2C0C {
+  
+  provides interface HplMsp430I2C;
+  
+}
+
+implementation {
+  
+  components HplMsp430I2C0P as HplI2CP;
+  HplMsp430I2C = HplI2CP;
+  
+  components HplMsp430Usart0P as HplUsartP;
+  HplUsartP.HplI2C -> HplI2CP;
+  HplI2CP.HplUsart -> HplUsartP;
+  
+  components HplMsp430GeneralIOC as GIO;
+  HplI2CP.SIMO -> GIO.SIMO0;
+  HplI2CP.UCLK -> GIO.UCLK0;
+  
+}
diff --git a/tos/chips/msp430/usart/HplMsp430I2C0P.nc b/tos/chips/msp430/usart/HplMsp430I2C0P.nc
new file mode 100644 (file)
index 0000000..68398d2
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+module HplMsp430I2C0P {
+  
+  provides interface HplMsp430I2C as HplI2C;
+  
+  uses interface HplMsp430Usart as HplUsart;
+  uses interface HplMsp430GeneralIO as SIMO;
+  uses interface HplMsp430GeneralIO as UCLK;
+  
+}
+
+implementation {
+  
+  MSP430REG_NORACE(U0CTL);
+  MSP430REG_NORACE(I2CTCTL);
+  MSP430REG_NORACE(I2CDR);
+  MSP430REG_NORACE(I2CSA);
+  MSP430REG_NORACE(I2CIE);
+
+  async command bool HplI2C.isI2C() {
+    atomic return ((U0CTL & I2C) && (U0CTL & SYNC) && (U0CTL & I2CEN));
+  }
+  
+  async command void HplI2C.clearModeI2C() {
+    atomic {
+      U0CTL &= ~(I2C | SYNC | I2CEN);
+      call HplUsart.resetUsart(TRUE);
+    }
+  }
+  
+  async command void HplI2C.setModeI2C( msp430_i2c_config_t* config ) {
+    
+    call HplUsart.disableUart();
+    call HplUsart.disableSpi();
+    call SIMO.makeInput();
+    call SIMO.selectModuleFunc();
+    call UCLK.makeInput();
+    call UCLK.selectModuleFunc();
+    
+    atomic {
+      
+      U0CTL &= ~(I2C | I2CEN | SYNC);
+      U0CTL = SWRST;
+      U0CTL |= SYNC | I2C;
+      U0CTL &= ~I2CEN;
+      
+      U0CTL |= ( ( config->rxdmaen << 7 ) |
+                 ( config->txdmaen << 6 ) |
+                 ( config->xa << 4 ) |
+                 ( config->listen << 3 ) );
+      I2CTCTL = 0;
+      I2CTCTL = ( ( config->i2cword << 7 ) |
+                 ( config->i2crm << 6 ) |
+                 ( config->i2cssel << 4 ) );
+      I2CPSC = config->i2cpsc;
+      I2CSCLH = config->i2csclh;
+      I2CSCLL = config->i2cscll;
+      I2COA = config->i2coa;
+      U0CTL |= I2CEN;
+      
+    }
+    
+  }
+  
+  // U0CTL
+  async command void HplI2C.setMasterMode() { U0CTL |= MST; }
+  async command void HplI2C.setSlaveMode() { U0CTL &= ~MST; }
+  
+  async command void HplI2C.enableI2C() { U0CTL |= I2CEN; }
+  async command void HplI2C.disableI2C() { U0CTL &= ~I2CEN; }
+  
+  // I2CTCTL
+  async command bool HplI2C.getWordMode() {
+    return ( I2CTCTL & I2CWORD ) != 0;
+  }
+  
+  async command void HplI2C.setWordMode( bool mode ) {
+    I2CTCTL |= ( mode & 0x1 ) << 7;
+  }
+  
+  async command bool HplI2C.getRepeatMode() {
+    return ( I2CTCTL & I2CRM ) != 0;
+  }
+  
+  async command void HplI2C.setRepeatMode( bool mode ) { 
+    I2CTCTL |= ( mode & 0x1 ) << 6;;
+  }
+  
+  async command uint8_t HplI2C.getClockSource() {
+    return ( I2CTCTL >> 4 ) & 0x3;;
+  }
+  
+  async command void HplI2C.setClockSource( uint8_t src ) {
+    atomic I2CTCTL = ( ( src & 0x3 ) << 4 ) | I2CTCTL;
+  }
+  
+  async command bool HplI2C.getTransmitReceiveMode() { 
+    return ( I2CTCTL & I2CTRX ) != 0; 
+  }
+  
+  async command void HplI2C.setTransmitMode() { I2CTCTL |= I2CTRX; }
+  async command void HplI2C.setReceiveMode() { I2CTCTL &= ~I2CTRX; }
+  
+  async command bool HplI2C.getStartByte() { return (I2CTCTL & I2CSTB) != 0; }
+  async command void HplI2C.setStartByte() { I2CTCTL |= I2CSTB; }
+  
+  async command bool HplI2C.getStopBit() { return (I2CTCTL & I2CSTP) != 0; }
+  async command void HplI2C.setStopBit() { I2CTCTL |= I2CSTP; }
+  
+  async command bool HplI2C.getStartBit() { return (I2CTCTL & I2CSTT) != 0; }
+  async command void HplI2C.setStartBit() { I2CTCTL |= I2CSTT; }
+  
+  // I2CDR
+  async command uint8_t HplI2C.getData() { return I2CDR; }
+  async command void HplI2C.setData( uint8_t v ) { I2CDR = v; }
+  
+  // I2CNDAT
+  async command uint8_t HplI2C.getTransferByteCount() { return I2CNDAT; }
+  async command void HplI2C.setTransferByteCount( uint8_t v ) { I2CNDAT = v; }
+  
+  // I2CPSC
+  async command uint8_t HplI2C.getClockPrescaler() { return I2CPSC; }
+  async command void HplI2C.setClockPrescaler( uint8_t v ) { I2CPSC = v; }
+  
+  // I2CSCLH and I2CSCLL
+  async command uint16_t HplI2C.getShiftClock() {
+    uint16_t shift;
+    atomic {
+      shift = I2CSCLH;
+      shift <<= 8;
+      shift |= I2CSCLL;
+    }
+    return shift;
+  }
+  
+  async command void HplI2C.setShiftClock( uint16_t shift ) {
+    atomic {
+      I2CSCLH = shift >> 8;
+      I2CSCLL = shift;
+    }
+  }
+  
+  // I2COA
+  async command uint16_t HplI2C.getOwnAddress() { return I2COA; }
+  async command void HplI2C.setOwnAddress( uint16_t addr ) { I2COA = addr; }
+  
+  // I2CSA
+  async command uint16_t HplI2C.getSlaveAddress() { return I2CSA; }
+  async command void HplI2C.setSlaveAddress( uint16_t addr ) { I2CSA = addr; }
+  
+  // I2CIE
+  async command void HplI2C.disableStartDetect() { I2CIE &= ~STTIE; }
+  async command void HplI2C.enableStartDetect() { I2CIE |= STTIE; }
+  
+  async command void HplI2C.disableGeneralCall() { I2CIE &= ~GCIE; }
+  async command void HplI2C.enableGeneralCall() { I2CIE |= GCIE; }
+  
+  async command void HplI2C.disableTransmitReady() { I2CIE &= ~TXRDYIE; }
+  async command void HplI2C.enableTransmitReady() { I2CIE |= TXRDYIE; }
+  
+  async command void HplI2C.disableReceiveReady() { I2CIE &= ~RXRDYIE; }
+  async command void HplI2C.enableReceiveReady() { I2CIE |= RXRDYIE; }
+  
+  async command void HplI2C.disableAccessReady() { I2CIE &= ~ARDYIE; }
+  async command void HplI2C.enableAccessReady() { I2CIE |= ARDYIE; }
+  
+  async command void HplI2C.disableOwnAddress() { I2CIE &= ~OAIE; }
+  async command void HplI2C.enableOwnAddress() { I2CIE |= OAIE; }
+
+  async command void HplI2C.disableNoAck() { I2CIE &= ~NACKIE; }
+  async command void HplI2C.enableNoAck() { I2CIE |= NACKIE; }
+  
+  async command void HplI2C.disableArbitrationLost() { I2CIE &= ~ALIE; }
+  async command void HplI2C.enableArbitrationLost() { I2CIE |= ALIE; }
+  
+  // I2CIFG
+  async command bool HplI2C.isStartDetectPending() {
+    return ( I2CIFG & STTIFG ) != 0;
+  }
+  
+  async command bool HplI2C.isGeneralCallPending() {
+    return ( I2CIFG & GCIFG ) != 0;
+  }
+  
+  async command bool HplI2C.isTransmitReadyPending() {
+    return ( I2CIFG & TXRDYIFG ) != 0;
+  }
+  
+  async command bool HplI2C.isReceiveReadyPending() {
+    return ( I2CIFG & RXRDYIFG ) != 0;
+  }
+  
+  async command bool HplI2C.isAccessReadyPending() {
+    return ( I2CIFG & ARDYIFG ) != 0;
+  }
+  
+  async command bool HplI2C.isOwnAddressPending() {
+    return ( I2CIFG & OAIFG ) != 0;
+  }
+  
+  async command bool HplI2C.isNoAckPending() {
+    return ( I2CIFG & NACKIFG ) != 0;
+  }
+  
+  async command bool HplI2C.isArbitrationLostPending() {
+    return ( I2CIFG & ALIFG ) != 0;
+  }
+  
+  // I2CIV
+  async command uint8_t HplI2C.getIV() {
+    return I2CIV;
+  }
+  
+}
diff --git a/tos/chips/msp430/usart/HplMsp430I2CInterrupts.nc b/tos/chips/msp430/usart/HplMsp430I2CInterrupts.nc
new file mode 100644 (file)
index 0000000..454f811
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+interface HplMsp430I2CInterrupts {
+  
+  async event void fired();
+  
+}
diff --git a/tos/chips/msp430/usart/Msp430I2C0P.nc b/tos/chips/msp430/usart/Msp430I2C0P.nc
new file mode 100644 (file)
index 0000000..5ab469b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+configuration Msp430I2C0P {
+  
+  provides interface Resource[ uint8_t id ];
+  provides interface ResourceConfigure[uint8_t id ];
+  provides interface I2CPacket<TI2CBasicAddr> as I2CBasicAddr;
+  
+  uses interface Resource as UsartResource[ uint8_t id ];
+  uses interface Msp430I2CConfigure[ uint8_t id ];
+  uses interface HplMsp430I2CInterrupts as I2CInterrupts;
+  
+}
+
+implementation {
+  
+  components Msp430I2CP as I2CP;
+  Resource = I2CP.Resource;
+  ResourceConfigure = I2CP.ResourceConfigure;
+  Msp430I2CConfigure = I2CP.Msp430I2CConfigure;
+  I2CBasicAddr = I2CP.I2CBasicAddr;
+  UsartResource = I2CP.UsartResource;
+  I2CInterrupts = I2CP.I2CInterrupts;
+  
+  components HplMsp430I2C0C as HplI2CC;
+  I2CP.HplI2C -> HplI2CC;
+  
+  components LedsC as Leds;
+  I2CP.Leds -> Leds;
+  
+}
diff --git a/tos/chips/msp430/usart/Msp430I2CC.nc b/tos/chips/msp430/usart/Msp430I2CC.nc
new file mode 100644 (file)
index 0000000..7c5727b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#include <I2C.h>
+#include "msp430usart.h"
+
+generic configuration Msp430I2CC() {
+  
+  provides interface Resource;
+  provides interface I2CPacket<TI2CBasicAddr> as I2CBasicAddr;
+  
+  uses interface Msp430I2CConfigure;
+  
+}
+
+implementation {
+  
+  enum {
+    CLIENT_ID = unique( MSP430_I2CO_BUS ),
+  };
+  
+  components Msp430I2C0P as I2CP;
+  Resource = I2CP.Resource[ CLIENT_ID ];
+  I2CBasicAddr = I2CP.I2CBasicAddr;
+  Msp430I2CConfigure = I2CP.Msp430I2CConfigure[ CLIENT_ID ];
+  
+  components new Msp430Usart0C() as UsartC;
+  I2CP.ResourceConfigure[ CLIENT_ID ] <- UsartC.ResourceConfigure;
+  I2CP.UsartResource[ CLIENT_ID ] -> UsartC.Resource;
+  I2CP.I2CInterrupts -> UsartC.HplMsp430I2CInterrupts;
+  
+}
diff --git a/tos/chips/msp430/usart/Msp430I2CConfigure.nc b/tos/chips/msp430/usart/Msp430I2CConfigure.nc
new file mode 100644 (file)
index 0000000..c01e4a0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2004-2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ */
+
+/**
+ * Interface used by Msp430I2C clients to reconfigure the I2C before use
+ * @author Vlado Handziski <handzisk@tkn.tu-berlin.de>
+ * @version $Revision$ $Date$
+ */
+
+#include "msp430usart.h"
+
+interface Msp430I2CConfigure {
+  async command msp430_i2c_config_t* getConfig();
+}
diff --git a/tos/chips/msp430/usart/Msp430I2CP.nc b/tos/chips/msp430/usart/Msp430I2CP.nc
new file mode 100644 (file)
index 0000000..ff16350
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#include <I2C.h>
+
+module Msp430I2CP {
+  
+  provides interface Resource[ uint8_t id ];
+  provides interface ResourceConfigure[ uint8_t id ];
+  provides interface I2CPacket<TI2CBasicAddr> as I2CBasicAddr;
+  
+  uses interface Resource as UsartResource[ uint8_t id ];
+  uses interface Msp430I2CConfigure[ uint8_t id ];
+  uses interface HplMsp430I2C as HplI2C;
+  uses interface HplMsp430I2CInterrupts as I2CInterrupts;
+  uses interface Leds;
+  
+}
+
+implementation {
+  
+  MSP430REG_NORACE(I2CIE);
+  
+  enum {
+    TIMEOUT = 64,
+  };
+  
+  norace uint8_t* m_buf;
+  norace uint8_t m_len;
+  norace uint8_t m_pos;
+  norace i2c_flags_t m_flags;
+  
+  void nextRead();
+  void nextWrite();
+  void signalDone( error_t error );
+  
+  async command error_t Resource.immediateRequest[ uint8_t id ]() {
+    return call UsartResource.immediateRequest[ id ]();
+  }
+  
+  async command error_t Resource.request[ uint8_t id ]() {
+    return call UsartResource.request[ id ]();
+  }
+  
+  async command uint8_t Resource.isOwner[ uint8_t id ]() {
+    return call UsartResource.isOwner[ id ]();
+  }
+  
+  async command error_t Resource.release[ uint8_t id ]() {
+    return call UsartResource.release[ id ]();
+  }
+  
+  async command void ResourceConfigure.configure[ uint8_t id ]() {
+    call HplI2C.setModeI2C(call Msp430I2CConfigure.getConfig[id]());
+  }
+  
+  async command void ResourceConfigure.unconfigure[ uint8_t id ]() {
+    call HplI2C.clearModeI2C();
+  }
+  
+  event void UsartResource.granted[ uint8_t id ]() {
+    signal Resource.granted[ id ]();
+  }
+  
+  default async command error_t UsartResource.request[ uint8_t id ]() { return FAIL; }
+  default async command error_t UsartResource.immediateRequest[ uint8_t id ]() { return FAIL; }
+  default async command error_t UsartResource.release[ uint8_t id ]() {return FAIL;}
+  default event void Resource.granted[ uint8_t id ]() {}
+  default async command msp430_i2c_config_t* Msp430I2CConfigure.getConfig[uint8_t id]() {
+    return &msp430_i2c_default_config;
+  }
+  
+  async command error_t I2CBasicAddr.read( i2c_flags_t flags,
+                                          uint16_t addr, uint8_t len, 
+                                          uint8_t* buf ) {
+    
+    m_buf = buf;
+    m_len = len;
+    m_flags = flags;
+    m_pos = 0;
+
+    call HplI2C.setMasterMode();
+    call HplI2C.setReceiveMode();
+    
+    call HplI2C.setSlaveAddress( addr );
+    call HplI2C.enableReceiveReady();
+    call HplI2C.enableAccessReady();
+    call HplI2C.enableNoAck();
+    if ( flags & I2C_START )
+      call HplI2C.setStartBit();
+    else
+      nextRead();
+    
+    return SUCCESS;
+    
+  }
+  
+  async command error_t I2CBasicAddr.write( i2c_flags_t flags,
+                                           uint16_t addr, uint8_t len,
+                                           uint8_t* buf ) {
+    
+    m_buf = buf;
+    m_len = len;
+    m_flags = flags;
+    m_pos = 0;
+    
+    call HplI2C.setMasterMode();
+    call HplI2C.setTransmitMode();
+    
+    call HplI2C.setSlaveAddress( addr );
+    call HplI2C.enableTransmitReady();
+    call HplI2C.enableAccessReady();
+    call HplI2C.enableNoAck();
+    
+    if ( flags & I2C_START )
+      call HplI2C.setStartBit();
+    else
+      nextWrite();
+    
+    return SUCCESS;
+    
+  }
+  
+  async event void I2CInterrupts.fired() {
+    
+    int i = 0;
+    
+    switch( call HplI2C.getIV() ) {
+      
+    case 0x04:
+      if ( I2CDCTL & I2CBB )
+       call HplI2C.setStopBit();
+      while( I2CDCTL & I2CBUSY );
+      signalDone( FAIL );
+      break;
+      
+    case 0x08:
+      while( (I2CDCTL & I2CBUSY) ) {
+       if ( i++ >= TIMEOUT ) {
+         signalDone( FAIL );
+         return;
+       }
+      }
+      signalDone( SUCCESS );
+      break;
+      
+    case 0x0A:
+      nextRead();
+      break;
+      
+    case 0x0C:
+      nextWrite();
+      break;
+      
+    default:
+      break;
+
+    }
+    
+  }
+  
+  void nextRead() {
+    m_buf[ m_pos++ ] = call HplI2C.getData();
+    if ( m_pos == m_len ) {
+      if ( m_flags & I2C_STOP )
+       call HplI2C.setStopBit();
+      else
+       signalDone( SUCCESS );
+    }
+  }
+  
+  void nextWrite() {
+    if ( ( m_pos == m_len - 1 ) && ( m_flags & I2C_STOP ) ) {
+      call HplI2C.setStopBit();
+    }
+    else if ( m_pos == m_len ) {
+      signalDone( SUCCESS );
+      return;
+    }
+    call HplI2C.setData( m_buf[ m_pos++ ] );
+  }
+  
+  void signalDone( error_t error ) {
+    I2CIE = 0;
+    if ( call HplI2C.getTransmitReceiveMode() )
+      signal I2CBasicAddr.writeDone( error, I2CSA, m_len, m_buf );
+    else
+      signal I2CBasicAddr.readDone( error, I2CSA, m_len, m_buf );
+  }
+  
+  default async command error_t UsartResource.isOwner[ uint8_t id ]() { return FAIL; }
+
+}
diff --git a/tos/chips/msp430/usart/Msp430Spi1C.nc b/tos/chips/msp430/usart/Msp430Spi1C.nc
new file mode 100644 (file)
index 0000000..1c777d9
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * An implementation of the SPI on USART0 for the MSP430. The current
+ * implementation defaults not using the DMA and performing the SPI
+ * transfers in software. To utilize the DMA, use Msp430SpiDma0P in
+ * place of Msp430SpiNoDma0P.
+ *
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#include "msp430usart.h"
+
+generic configuration Msp430Spi1C() {
+
+  provides interface Resource;
+  provides interface SpiByte;
+  provides interface SpiPacket;
+
+  uses interface Msp430SpiConfigure;
+}
+
+implementation {
+
+  enum {
+    CLIENT_ID = unique( MSP430_SPI1_BUS ),
+  };
+
+  components Msp430SpiNoDma1P as SpiP;
+  Resource = SpiP.Resource[ CLIENT_ID ];
+  SpiByte = SpiP.SpiByte;
+  SpiPacket = SpiP.SpiPacket[ CLIENT_ID ];
+  Msp430SpiConfigure = SpiP.Msp430SpiConfigure[ CLIENT_ID ];
+
+  components new Msp430Usart1C() as UsartC;
+  SpiP.ResourceConfigure[ CLIENT_ID ] <- UsartC.ResourceConfigure;
+  SpiP.UsartResource[ CLIENT_ID ] -> UsartC.Resource;
+  SpiP.UsartInterrupts -> UsartC.HplMsp430UsartInterrupts;
+
+}
diff --git a/tos/chips/msp430/usart/Msp430SpiConfigure.nc b/tos/chips/msp430/usart/Msp430SpiConfigure.nc
new file mode 100644 (file)
index 0000000..f6fd05d
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2004-2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ */
+
+/**
+ * Interface used by Msp430Spi clients to reconfigure the SPI before use
+ * @author Vlado Handziski <handzisk@tkn.tu-berlin.de>
+ * @version $Revision$ $Date$
+ */
+
+#include "msp430usart.h"
+
+interface Msp430SpiConfigure {
+  async command msp430_spi_config_t* getConfig();
+}
diff --git a/tos/chips/msp430/usart/Msp430SpiDma1P.nc b/tos/chips/msp430/usart/Msp430SpiDma1P.nc
new file mode 100644 (file)
index 0000000..dfbd278
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+configuration Msp430SpiDma1P {
+
+  provides interface Resource[ uint8_t id ];
+  provides interface ResourceControl [uint8_t id];
+  provides interface SpiByte;
+  provides interface SpiPacket[ uint8_t id ];
+
+  uses interface Resource as UsartResource[ uint8_t id ];
+  uses interface Msp430SpiConfigure[ uint8_t id ];
+  uses interface HplMsp430UsartInterrupts as UsartInterrupts;
+
+}
+
+implementation {
+
+  components new Msp430SpiDmaP() as SpiP;
+  Resource = SpiP.Resource;
+  ResourceControl = SpiP.ResourceControl;
+  Msp430SpiConfigure = SpiP.Msp430SpiConfigure;
+  SpiByte = SpiP.SpiByte;
+  SpiPacket = SpiP.SpiPacket;
+  UsartResource = SpiP.UsartResource;
+  UsartInterrupts = SpiP.UsartInterrupts;
+
+  components HplMsp430Usart1C as UsartC;
+  SpiP.Usart -> UsartC;
+
+  components Msp430DmaC as DmaC;
+  SpiP.DmaChannel1 -> DmaC.Channel1;
+  SpiP.DmaChannel2 -> DmaC.Channel2;
+
+  components LedsC as Leds;
+  SpiP.Leds -> Leds;
+
+}
diff --git a/tos/chips/msp430/usart/Msp430SpiNoDma1P.nc b/tos/chips/msp430/usart/Msp430SpiNoDma1P.nc
new file mode 100644 (file)
index 0000000..683434e
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+configuration Msp430SpiNoDma1P {
+
+  provides interface Resource[ uint8_t id ];
+  provides interface ResourceConfigure[uint8_t id ];
+  provides interface SpiByte;
+  provides interface SpiPacket[ uint8_t id ];
+
+  uses interface Resource as UsartResource[ uint8_t id ];
+  uses interface Msp430SpiConfigure[ uint8_t id ];
+  uses interface HplMsp430UsartInterrupts as UsartInterrupts;
+
+}
+
+implementation {
+
+  components new Msp430SpiNoDmaP() as SpiP;
+  Resource = SpiP.Resource;
+  ResourceConfigure = SpiP.ResourceConfigure;
+  Msp430SpiConfigure = SpiP.Msp430SpiConfigure;
+  SpiByte = SpiP.SpiByte;
+  SpiPacket = SpiP.SpiPacket;
+  UsartResource = SpiP.UsartResource;
+  UsartInterrupts = SpiP.UsartInterrupts;
+
+  components HplMsp430Usart1C as UsartC;
+  SpiP.Usart -> UsartC;
+
+  components LedsC as Leds;
+  SpiP.Leds -> Leds;
+
+}
diff --git a/tos/chips/msp430/usart/Msp430Uart0C.nc b/tos/chips/msp430/usart/Msp430Uart0C.nc
new file mode 100644 (file)
index 0000000..470872d
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * An implementation of the UART on USART0 for the MSP430.
+ * @author Vlado Handziski <handzisk@tkn.tu-berlin.de>
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#include "msp430usart.h"
+
+generic configuration Msp430Uart0C() {
+
+  provides interface Resource;
+  provides interface UartStream;
+  provides interface UartByte;
+  provides interface Msp430UartControl as UartControl;
+
+  uses interface Msp430UartConfigure;
+}
+
+implementation {
+
+  enum {
+    CLIENT_ID = unique( MSP430_UARTO_BUS ),
+  };
+
+  components Msp430Uart0P as UartP;
+  Resource = UartP.Resource[ CLIENT_ID ];
+  UartStream = UartP.UartStream;
+  UartByte = UartP.UartByte;
+  UartControl = UartP.UartControl[ CLIENT_ID ];
+  Msp430UartConfigure = UartP.Msp430UartConfigure[ CLIENT_ID ];
+
+  components new Msp430Usart0C() as UsartC;
+  UartP.ResourceConfigure[ CLIENT_ID ] <- UsartC.ResourceConfigure;
+  UartP.UsartResource[ CLIENT_ID ] -> UsartC.Resource;
+  UartP.UsartInterrupts -> UsartC.HplMsp430UsartInterrupts;
+
+}
diff --git a/tos/chips/msp430/usart/Msp430Uart0P.nc b/tos/chips/msp430/usart/Msp430Uart0P.nc
new file mode 100644 (file)
index 0000000..f910998
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @author Vlado Handziski <handzisk@tkn.tu-berlin.de>
+ * @version $Revision$ $Date$
+ */
+
+configuration Msp430Uart0P {
+
+  provides interface Resource[ uint8_t id ];
+  provides interface ResourceConfigure[uint8_t id ];
+  provides interface Msp430UartControl as UartControl[ uint8_t id ];
+  provides interface UartStream;
+  provides interface UartByte;
+
+  uses interface Resource as UsartResource[ uint8_t id ];
+  uses interface Msp430UartConfigure[ uint8_t id ];
+  uses interface HplMsp430UsartInterrupts as UsartInterrupts;
+
+}
+
+implementation {
+
+  components new Msp430UartP() as UartP;
+  Resource = UartP.Resource;
+  ResourceConfigure = UartP.ResourceConfigure;
+  Msp430UartConfigure = UartP.Msp430UartConfigure;
+  UartControl = UartP.UartControl;
+  UartStream = UartP.UartStream;
+  UartByte = UartP.UartByte;
+  UsartResource = UartP.UsartResource;
+  UsartInterrupts = UartP.UsartInterrupts;
+
+  components HplMsp430Usart0C as UsartC;
+  UartP.Usart -> UsartC;
+
+  components Counter32khz16C as CounterC;
+  UartP.Counter -> CounterC;
+
+  components LedsC as Leds;
+  UartP.Leds -> Leds;
+
+}
diff --git a/tos/chips/msp430/usart/Msp430Uart1P.nc b/tos/chips/msp430/usart/Msp430Uart1P.nc
new file mode 100644 (file)
index 0000000..4c57206
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @author Vlado Handziski <handzisk@tkn.tu-berlin.de>
+ * @version $Revision$ $Date$
+ */
+
+configuration Msp430Uart1P {
+
+  provides interface Resource[ uint8_t id ];
+  provides interface ResourceConfigure[uint8_t id ];
+  provides interface Msp430UartControl as UartControl[ uint8_t id ];
+  provides interface UartStream;
+  provides interface UartByte;
+  
+  uses interface Resource as UsartResource[ uint8_t id ];
+  uses interface Msp430UartConfigure[ uint8_t id ];
+  uses interface HplMsp430UsartInterrupts as UsartInterrupts;
+
+}
+
+implementation {
+
+  components new Msp430UartP() as UartP;
+  Resource = UartP.Resource;
+  ResourceConfigure = UartP.ResourceConfigure;
+  Msp430UartConfigure = UartP.Msp430UartConfigure;
+  UartControl = UartP.UartControl;
+  UartStream = UartP.UartStream;
+  UartByte = UartP.UartByte;
+  UsartResource = UartP.UsartResource;
+  UsartInterrupts = UartP.UsartInterrupts;
+
+  components HplMsp430Usart1C as UsartC;
+  UartP.Usart -> UsartC;
+  
+  components Counter32khz16C as CounterC;
+  UartP.Counter -> CounterC;
+  
+  components LedsC as Leds;
+  UartP.Leds -> Leds;
+
+}
diff --git a/tos/chips/msp430/usart/Msp430UartConfigure.nc b/tos/chips/msp430/usart/Msp430UartConfigure.nc
new file mode 100644 (file)
index 0000000..92af987
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2004-2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ */
+
+/**
+ * Interface used by Msp430Uart clients to reconfigure the UART before use
+ * @author Vlado Handziski <handzisk@tkn.tu-berlin.de>
+ * @version $Revision$ $Date$
+ */
+
+#include "msp430usart.h"
+
+interface Msp430UartConfigure {
+  async command msp430_uart_config_t* getConfig();
+}
diff --git a/tos/chips/msp430/usart/Msp430UartControl.nc b/tos/chips/msp430/usart/Msp430UartControl.nc
new file mode 100644 (file)
index 0000000..49f8352
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2004-2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ */
+
+/**
+ * Interface used by Msp430Uart clients to control/configure the Uart.
+ *
+ * @author Philipp Huppertz (huppertz@tkn.tu-berlin.de)
+ */
+interface Msp430UartControl {
+
+  /**
+  * Sets the Uart to Rx mode.
+  */
+  async command void setModeRx();
+  
+  /**
+  * Sets the Uart to Tx mode.
+  */
+  async command void setModeTx();
+  
+  /**
+  * Sets the Uart to duplex mode.
+  */
+  async command void setModeDuplex();
+  
+}
diff --git a/tos/chips/msp430/usart/Msp430Usart1C.nc b/tos/chips/msp430/usart/Msp430Usart1C.nc
new file mode 100644 (file)
index 0000000..29f5d02
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * Provides an interface for USART1 on the MSP430.
+ *
+ * @author Vlado Handziski <handisk@tkn.tu-berlin.de>
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+generic configuration Msp430Usart1C() {
+
+  provides interface Resource;
+  provides interface ArbiterInfo;
+  provides interface HplMsp430Usart;
+  provides interface HplMsp430UsartInterrupts;
+
+  uses interface ResourceConfigure;
+}
+
+implementation {
+
+  enum {
+    CLIENT_ID = unique( MSP430_HPLUSART1_RESOURCE ),
+  };
+
+  components Msp430UsartShare1P as UsartShareP;
+
+  Resource = UsartShareP.Resource[ CLIENT_ID ];
+  ResourceConfigure = UsartShareP.ResourceConfigure[ CLIENT_ID ];
+  ArbiterInfo = UsartShareP.ArbiterInfo;
+  HplMsp430UsartInterrupts = UsartShareP.Interrupts[ CLIENT_ID ];
+
+  components HplMsp430Usart1C as UsartC;
+  HplMsp430Usart = UsartC;
+
+}
diff --git a/tos/chips/msp430/usart/Msp430UsartShare1P.nc b/tos/chips/msp430/usart/Msp430UsartShare1P.nc
new file mode 100644 (file)
index 0000000..153906a
--- /dev/null
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * @author Vlado Handziski <handzisk@tkn.tu-berlin.de>
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+configuration Msp430UsartShare1P {
+
+  provides interface HplMsp430UsartInterrupts as Interrupts[ uint8_t id ];
+  provides interface Resource[ uint8_t id ];
+  provides interface ArbiterInfo;
+
+  uses interface ResourceConfigure[ uint8_t id ];
+}
+
+implementation {
+
+  components new Msp430UsartShareP() as UsartShareP;
+  Interrupts = UsartShareP;
+  UsartShareP.RawInterrupts -> UsartC;
+
+  components new FcfsArbiterC( MSP430_HPLUSART1_RESOURCE ) as ArbiterC;
+  Resource = ArbiterC;
+  ResourceConfigure = ArbiterC;
+  ArbiterInfo = ArbiterC;
+  UsartShareP.ArbiterInfo -> ArbiterC;
+
+  components new AsyncStdControlPowerManagerC() as PowerManagerC;
+  PowerManagerC.ResourceController -> ArbiterC;
+       
+  components HplMsp430Usart1C as UsartC;
+  PowerManagerC.AsyncStdControl -> UsartC;
+}
diff --git a/tos/chips/pxa27x/dma/DMA.h b/tos/chips/pxa27x/dma/DMA.h
new file mode 100644 (file)
index 0000000..fd9aaaa
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ *
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+#ifndef _DMA_H
+#define _DMA_H
+
+typedef uint8_t DMAPeripheralID_t;
+typedef uint8_t DMAPriority_t;
+
+typedef enum {
+  DMA_BURST_SIZE_8BYTES,
+  DMA_BURST_SIZE_16BYTES,
+  DMA_BURST_SIZE_32BYTES,
+} DMAMaxBurstSize_t;
+
+typedef enum {
+  DMA_WIDTH_1BYTE,
+  DMA_WIDTH_2BYTES,
+  DMA_WIDTH_4BYTES,
+} DMATransferWidth_t;
+
+#endif /* _DMA_H */
diff --git a/tos/chips/pxa27x/dma/HalPXA27xDMAChannel.nc b/tos/chips/pxa27x/dma/HalPXA27xDMAChannel.nc
new file mode 100644 (file)
index 0000000..f612fef
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ *
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+#include "DMA.h"
+
+interface HalPXA27xDMAChannel 
+{
+  
+  command error_t requestChannel(DMAPeripheralID_t peripheralID, 
+                                 DMAPriority_t priority, bool permanent);
+  event error_t requestChannelDone();
+  command error_t returnChannel(DMAPeripheralID_t peripheralID);
+  
+  command error_t setSourceAddr(uint32_t val);
+  command error_t setTargetAddr(uint32_t val);
+  command error_t enableSourceAddrIncrement(bool enable);
+  command error_t enableTargetAddrIncrement(bool enable);
+  command error_t enableSourceFlowControl(bool enable);
+  command error_t enableTargetFlowControl(bool enable);
+  command error_t setMaxBurstSize(DMAMaxBurstSize_t size);
+  command error_t setTransferLength(uint16_t length);
+  command error_t setTransferWidth(DMATransferWidth_t width);
+  command error_t run(bool InterruptEn);
+  command error_t stop();
+  async event void Interrupt();
+}
diff --git a/tos/chips/pxa27x/dma/HalPXA27xDMAChannelC.nc b/tos/chips/pxa27x/dma/HalPXA27xDMAChannelC.nc
new file mode 100644 (file)
index 0000000..f4d6afd
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ *
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+configuration HalPXA27xDMAChannelC {
+  provides interface HalPXA27xDMAChannel[uint8_t chnl];
+}
+
+implementation {
+  components HplPXA27xDMAC, HalPXA27xDMAChannelM;
+
+  HalPXA27xDMAChannel = HalPXA27xDMAChannelM;
+  HalPXA27xDMAChannelM.HplPXA27xDMAChnl -> HplPXA27xDMAC;
+  HalPXA27xDMAChannelM.HplPXA27xDMACntl -> HplPXA27xDMAC;
+}
diff --git a/tos/chips/pxa27x/dma/HalPXA27xDMAChannelM.nc b/tos/chips/pxa27x/dma/HalPXA27xDMAChannelM.nc
new file mode 100644 (file)
index 0000000..4bfdc47
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ *
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+#include "DMA.h"
+
+module HalPXA27xDMAChannelM {
+  provides interface HalPXA27xDMAChannel[uint8_t chnl];
+
+  uses interface HplPXA27xDMACntl;
+  uses interface HplPXA27xDMAChnl[uint8_t chnl];
+}
+
+implementation {
+  uint8_t requestedChannel;
+  task void reqCompleteTask() {
+    signal HalPXA27xDMAChannel.requestChannelDone[requestedChannel]();
+  }
+  
+  command error_t HalPXA27xDMAChannel.requestChannel[uint8_t chnl](DMAPeripheralID_t peripheralID, DMAPriority_t priority, bool permanent) {
+    // priority is decided based on which channel you pick (PXADEV 5-4)
+    // permanent? nothing lasts forever my friend
+
+    uint32_t valDRCMR;
+    valDRCMR = call HplPXA27xDMACntl.getDRCMR(peripheralID) | DRCMR_MAPVLD;
+    valDRCMR = valDRCMR & ~DRCMR_CHLNUM(0x1F);
+    valDRCMR |= DRCMR_CHLNUM(chnl);
+    call HplPXA27xDMACntl.setDRCMR(peripheralID, valDRCMR);
+    requestedChannel = chnl;
+    post reqCompleteTask();
+    return SUCCESS;
+  }
+
+  command error_t HalPXA27xDMAChannel.returnChannel[uint8_t chnl](DMAPeripheralID_t peripheralID) {
+    // modified interface to require peripheralID, this isn't virtualized
+    uint32_t valDRCMR;
+    valDRCMR = call HplPXA27xDMACntl.getDRCMR(peripheralID) & ~DRCMR_MAPVLD;
+    call HplPXA27xDMACntl.setDRCMR(peripheralID, valDRCMR);
+    return SUCCESS;
+  }
+  
+  command error_t HalPXA27xDMAChannel.setSourceAddr[uint8_t chnl](uint32_t val) {
+    call HplPXA27xDMAChnl.setDSADR[chnl](val);
+    return SUCCESS;
+  }
+
+  command error_t HalPXA27xDMAChannel.setTargetAddr[uint8_t chnl](uint32_t val) {
+    call HplPXA27xDMAChnl.setDTADR[chnl](val);
+    return SUCCESS;
+  }
+
+  command error_t HalPXA27xDMAChannel.enableSourceAddrIncrement[uint8_t chnl](bool enable) {
+    uint32_t valDCMD;
+    valDCMD = call HplPXA27xDMAChnl.getDCMD[chnl]();
+    
+    valDCMD = (enable) ? (valDCMD | DCMD_INCSRCADDR) : (valDCMD & ~DCMD_INCSRCADDR);
+
+    call HplPXA27xDMAChnl.setDCMD[chnl](valDCMD);
+    return SUCCESS;
+  }
+
+  command error_t HalPXA27xDMAChannel.enableTargetAddrIncrement[uint8_t chnl](bool enable) {
+    uint32_t valDCMD;
+    valDCMD = call HplPXA27xDMAChnl.getDCMD[chnl]();
+    
+    valDCMD = (enable) ? (valDCMD | DCMD_INCTRGADDR) : (valDCMD & ~DCMD_INCTRGADDR);
+
+    call HplPXA27xDMAChnl.setDCMD[chnl](valDCMD);
+    return SUCCESS; 
+  }
+
+  command error_t HalPXA27xDMAChannel.enableSourceFlowControl[uint8_t chnl](bool enable) {
+    uint32_t valDCMD;
+    valDCMD = call HplPXA27xDMAChnl.getDCMD[chnl]();
+    
+    valDCMD = (enable) ? (valDCMD | DCMD_FLOWSRC) : (valDCMD & ~DCMD_FLOWSRC);
+
+    call HplPXA27xDMAChnl.setDCMD[chnl](valDCMD);
+    return SUCCESS; 
+  }
+
+  command error_t HalPXA27xDMAChannel.enableTargetFlowControl[uint8_t chnl](bool enable) {
+    uint32_t valDCMD;
+    valDCMD = call HplPXA27xDMAChnl.getDCMD[chnl]();
+    
+    valDCMD = (enable) ? (valDCMD | DCMD_FLOWTRG) : (valDCMD & ~DCMD_FLOWTRG);
+
+    call HplPXA27xDMAChnl.setDCMD[chnl](valDCMD);
+    return SUCCESS; 
+  }
+
+  command error_t HalPXA27xDMAChannel.setMaxBurstSize[uint8_t chnl](DMAMaxBurstSize_t size) {
+    uint32_t valDCMD;
+    valDCMD = call HplPXA27xDMAChnl.getDCMD[chnl]();
+    valDCMD &= ~DCMD_BURST32; // zero the bits first
+
+    switch(size) {
+    case DMA_BURST_SIZE_8BYTES:
+      valDCMD |= DCMD_BURST8;
+      break;
+    case DMA_BURST_SIZE_16BYTES:
+      valDCMD |= DCMD_BURST16;
+      break;
+    case DMA_BURST_SIZE_32BYTES:
+      valDCMD |= DCMD_BURST32;
+      break;
+    default:
+      return FAIL;
+    }
+    
+    call HplPXA27xDMAChnl.setDCMD[chnl](valDCMD);
+    return SUCCESS; 
+  }
+
+  command error_t HalPXA27xDMAChannel.setTransferLength[uint8_t chnl](uint16_t length) {
+    uint32_t valDCMD;
+    valDCMD = call HplPXA27xDMAChnl.getDCMD[chnl]();
+    
+    if(length > DCMD_MAXLEN)
+      return FAIL;
+
+    valDCMD &= ~DCMD_MAXLEN; // zero the bits first
+    valDCMD |= DCMD_LEN(length);
+    
+    call HplPXA27xDMAChnl.setDCMD[chnl](valDCMD);
+    return SUCCESS;
+  }
+
+  command error_t HalPXA27xDMAChannel.setTransferWidth[uint8_t chnl](DMATransferWidth_t width) {
+    uint32_t valDCMD;
+    valDCMD = call HplPXA27xDMAChnl.getDCMD[chnl]();
+    valDCMD &= ~DCMD_WIDTH4; // zero the bits first
+
+    switch(width) {
+    case DMA_WIDTH_1BYTE:
+      valDCMD |= DCMD_WIDTH1;
+      break;
+    case DMA_WIDTH_2BYTES:
+      valDCMD |= DCMD_WIDTH2;
+      break;
+    case DMA_WIDTH_4BYTES:
+      valDCMD |= DCMD_WIDTH4;
+      break;
+    default:
+      return FAIL;
+    }
+    
+    call HplPXA27xDMAChnl.setDCMD[chnl](valDCMD);
+    return SUCCESS;     
+  }
+
+  command error_t HalPXA27xDMAChannel.run[uint8_t chnl](bool InterruptEn) {
+    uint32_t valDCSR;
+    uint32_t valDCMD;
+    valDCSR = call HplPXA27xDMAChnl.getDCSR[chnl]();
+    valDCMD = call HplPXA27xDMAChnl.getDCMD[chnl]();
+
+    valDCMD = (InterruptEn) ? valDCMD | DCMD_ENDIRQEN : valDCSR & ~DCMD_ENDIRQEN;
+    
+    call HplPXA27xDMAChnl.setDCMD[chnl](valDCMD);
+    call HplPXA27xDMAChnl.setDCSR[chnl](valDCSR | DCSR_RUN | DCSR_NODESCFETCH);
+    return SUCCESS;
+  }
+
+  command error_t HalPXA27xDMAChannel.stop[uint8_t chnl]() {
+    uint32_t valDCSR;
+    valDCSR = call HplPXA27xDMAChnl.getDCSR[chnl]();
+    
+    call HplPXA27xDMAChnl.setDCSR[chnl](valDCSR & ~DCSR_RUN);
+    return SUCCESS;
+  }
+
+  async event void HplPXA27xDMAChnl.interruptDMA[uint8_t chnl]() {
+    // might want to clear interrupt first
+    // ...
+
+    signal HalPXA27xDMAChannel.Interrupt[chnl]();
+  }
+
+  default async event void HalPXA27xDMAChannel.Interrupt[uint8_t chnl]() { }
+  default event error_t HalPXA27xDMAChannel.requestChannelDone[uint8_t chnl]() { return FAIL; }
+}
diff --git a/tos/chips/pxa27x/dma/HplPXA27xDMAInfoC.nc b/tos/chips/pxa27x/dma/HplPXA27xDMAInfoC.nc
new file mode 100644 (file)
index 0000000..27edccc
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ *
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+// Example (STUART RX):
+// peripheral = 19 (Request to Channel Map register in PXA Dev Manual)
+// baseAddr = &STRBR (DMA address)
+
+// Example (STUART TX):
+// peripheral = 20
+// baseAddr = &STTHR
+
+generic module HplPXA27xDMAInfoC(uint8_t peripheral, uint32_t baseAddr) {
+  provides interface HplPXA27xDMAInfo;
+}
+
+implementation {
+  async command uint32_t HplPXA27xDMAInfo.getAddr() {
+    return baseAddr;
+  }
+
+  async command uint8_t HplPXA27xDMAInfo.getMapIndex() {
+    return peripheral;
+  }
+}
diff --git a/tos/chips/pxa27x/p30/Flash.nc b/tos/chips/pxa27x/p30/Flash.nc
new file mode 100644 (file)
index 0000000..7c997f3
--- /dev/null
@@ -0,0 +1,76 @@
+/*                                                                     tab:4
+ *  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.  By
+ *  downloading, copying, installing or using the software you agree to
+ *  this license.  If you do not agree to this license, do not download,
+ *  install, copy or use the software.
+ *
+ *  Intel Open Source License 
+ *
+ *  Copyright (c) 2002 Intel 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 Intel 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 INTEL 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.
+ * 
+ * 
+ */
+/**
+ * Interface for writing and erasing in flash memory
+ *
+ * Author:             Josh Herbach
+ * Revision:   1.0
+ * Date:               09/02/2005
+ */
+
+interface Flash
+{
+  /**
+   * Writes numBytes of the buffer data to the address in flash specified
+   * by addr. This function will only set bits low for the bytes it is 
+   * supposed to write to.If addr connot be written to for any reason returns
+   * FAIL, otherwise returns SUCCESS.
+   *
+   * @returns SUCCESS or FAIL.
+   */
+  command error_t write(uint32_t addr, uint8_t* data, uint32_t numBytes);
+
+  /**
+   * Erases the block of flash that contains addr, setting all bits to 1.
+   * If this function fails for any reason it will return FAIL, otherwise 
+   * SUCCESS.
+   *
+   * @returns SUCCESS or FAIL.
+   */
+  command error_t erase(uint32_t addr);
+
+  /**
+   * Reads len number of bytes into buf, starting at addr. If addr
+   * cannot be read for any reason returns FAIL, otherwise returns
+   * SUCCESS.
+  */
+  command error_t read(uint32_t addr, uint8_t* buf, uint32_t len);
+}
+
+
+
diff --git a/tos/chips/pxa27x/p30/FlashC.nc b/tos/chips/pxa27x/p30/FlashC.nc
new file mode 100644 (file)
index 0000000..5fbf140
--- /dev/null
@@ -0,0 +1,17 @@
+/* 
+ * Author:             Josh Herbach
+ * Revision:   1.0
+ * Date:               09/02/2005
+ */
+
+configuration FlashC {
+  provides interface Flash;
+}
+implementation {
+  components 
+    Main,
+    FlashM;
+
+  Main.StdControl -> FlashM;
+  Flash = FlashM;
+}
diff --git a/tos/chips/pxa27x/p30/HalP30C.nc b/tos/chips/pxa27x/p30/HalP30C.nc
new file mode 100644 (file)
index 0000000..7df5abf
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * 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
+ */
+
+/**
+ * P30 Hal component
+ * 
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+configuration HalP30C {
+  provides interface Flash;
+}
+
+implementation {
+  components HalP30P, HplP30P, MainC;
+
+  Flash = HalP30P;
+
+  MainC.SoftwareInit -> HalP30P;
+  HalP30P.HplP30 -> HplP30P;
+}
diff --git a/tos/chips/pxa27x/p30/HalP30P.nc b/tos/chips/pxa27x/p30/HalP30P.nc
new file mode 100644 (file)
index 0000000..5bd0f6c
--- /dev/null
@@ -0,0 +1,280 @@
+/* 
+ * Author:             Josh Herbach
+ * Revision:   1.0
+ * Date:               09/02/2005
+ */
+module HalP30P {
+  provides interface Init;
+  provides interface Flash; //does not allow writing into FLASH_PROTECTED_REGION
+  uses interface HplP30;
+}
+implementation {
+  
+#include <P30.h>
+
+  enum {
+    FLASH_STATE_READ_INACTIVE, 
+    FLASH_STATE_PROGRAM,
+    FLASH_STATE_ERASE,
+    FLASH_STATE_READ_ACTIVE
+  };
+
+  uint8_t FlashPartitionState[FLASH_PARTITION_COUNT];
+  uint8_t init = 0, programBufferSupported = 2, currBlock = 0;
+  
+  command error_t Init.init() {
+    int i = 0;
+    if(init != 0)
+      return SUCCESS;
+    init = 1;
+    for(i = 0; i < FLASH_PARTITION_COUNT; i++) 
+      FlashPartitionState[i] = FLASH_STATE_READ_INACTIVE;
+    
+    return SUCCESS;
+  }
+  
+  uint16_t writeHelper(uint32_t addr, uint8_t* data, uint32_t numBytes,
+                      uint8_t prebyte, uint8_t postbyte){
+    uint32_t i = 0, j = 0, k = 0;
+    error_t status;
+    uint16_t buffer[FLASH_PROGRAM_BUFFER_SIZE];
+    
+    if(numBytes == 0)
+      return FAIL;
+    
+    if(addr % 2 == 1){
+      status = call HplP30.progWord(addr - 1, prebyte | (data[i] << 8));
+      i++;
+      if(status != SUCCESS)
+       return FAIL;
+    }
+    
+    if(addr % 2 == numBytes % 2){
+      if(programBufferSupported == 1)
+       for(; i < numBytes; i = k){
+         for(j = 0, k = i; k < numBytes && 
+               j < FLASH_PROGRAM_BUFFER_SIZE; j++, k+=2)
+           buffer[j] = data[k] | (data[k + 1] << 8);
+         status = call HplP30.progBuffer(addr + i, buffer, j);
+         if(status != SUCCESS)
+           return FAIL;
+       }
+      else
+       for(; i < numBytes; i+=2){
+         status = call HplP30.progWord(addr + i, (data[i + 1] << 8) | data[i]);
+         if(status != SUCCESS)
+           return FAIL;
+       }
+    }
+    else{
+      if(programBufferSupported == 1)
+       for(; i < numBytes - 1; i = k){
+         for(j = 0, k = i; k < numBytes - 1 && 
+               j < FLASH_PROGRAM_BUFFER_SIZE; j++, k+=2)
+           buffer[j] = data[k] | (data[k + 1] << 8);
+         status = call HplP30.progBuffer(addr + i, buffer, j);
+         if(status != SUCCESS)
+           return FAIL;
+       }
+      else
+       for(; i < numBytes - 1; i+=2){
+         status = call HplP30.progWord(addr + i, (data[i + 1] << 8) | data[i]);
+         if(status != SUCCESS)
+           return FAIL;
+       }
+      status = call HplP30.progWord(addr + i, data[i] | (postbyte << 8));
+      if(status != SUCCESS)
+       return FAIL;
+    }
+    return SUCCESS;
+  }
+  
+  void writeExitHelper(uint32_t addr, uint32_t numBytes){
+    uint32_t i = 0;
+    for(i = addr / FLASH_PARTITION_SIZE;
+       i < (numBytes + addr) / FLASH_PARTITION_SIZE;
+       i++)
+      FlashPartitionState[i] = FLASH_STATE_READ_INACTIVE;
+  }
+  
+  command error_t Flash.write(uint32_t addr, uint8_t* data, uint32_t numBytes) {
+    uint32_t i;
+    uint16_t status;
+    uint8_t blocklen;
+    uint32_t blockAddr = (addr / P30_BLOCK_SIZE) * P30_BLOCK_SIZE;
+    
+    if(addr + numBytes > 0x02000000) //not in the flash memory space
+      return FAIL;
+    if(addr < FLASH_PROTECTED_REGION)
+      return FAIL;
+    
+    
+    for(i = 0; i < FLASH_PARTITION_COUNT; i++)
+      if(i != addr / FLASH_PARTITION_SIZE &&
+        FlashPartitionState[i] != FLASH_STATE_READ_INACTIVE &&
+        FlashPartitionState[i] != FLASH_STATE_READ_ACTIVE)
+       return FAIL;
+    
+    
+    for(i = addr / FLASH_PARTITION_SIZE;
+       i < (numBytes + addr) / FLASH_PARTITION_SIZE;
+       i++)
+      if(FlashPartitionState[i] != FLASH_STATE_READ_INACTIVE)
+       return FAIL;
+    
+    for(i = addr / FLASH_PARTITION_SIZE;
+       i < (numBytes + addr) / FLASH_PARTITION_SIZE;
+       i++)
+      FlashPartitionState[i] = FLASH_STATE_PROGRAM;
+
+    atomic{
+      for(blocklen = 0, i = blockAddr;
+         i < addr + numBytes;
+         i += P30_BLOCK_SIZE, blocklen++)
+       call HplP30.blkUnlock(i); //unlock(i);
+      
+      if(programBufferSupported == 2){
+       uint16_t testBuf[1];
+       
+       if(addr % 2 == 0){
+         testBuf[0] = data[0] | ((*((uint8_t *)(addr + 1))) << 8);
+         status = call HplP30.progBuffer(addr, testBuf, 1);
+       }
+       else{
+         testBuf[0] = *((uint8_t *)(addr - 1)) | (data[0] << 8);
+         status = call HplP30.progBuffer(addr - 1, testBuf, 1);
+       }      
+       if(status != SUCCESS)
+         programBufferSupported = 0;
+       else 
+         programBufferSupported = 1;
+      }
+    }
+    if(blocklen == 1){
+      atomic status = writeHelper(addr,data,numBytes,0xFF,0xFF);
+      if(status == FAIL){
+       writeExitHelper(addr, numBytes);
+       return FAIL;
+      }
+    }
+    else{
+      uint32_t bytesLeft = numBytes;
+      atomic status = writeHelper(addr,data, blockAddr + P30_BLOCK_SIZE - addr,0xFF,0xFF);
+      if(status == FAIL){
+       writeExitHelper(addr, numBytes);
+       return FAIL;
+      }
+      bytesLeft = numBytes - (P30_BLOCK_SIZE - (addr - blockAddr));
+      for(i = 1; i < blocklen - 1; i++){
+       atomic status = writeHelper(blockAddr + i * P30_BLOCK_SIZE, (uint8_t *)(data + numBytes - bytesLeft),
+                                   P30_BLOCK_SIZE,0xFF,0xFF);
+       bytesLeft -= P30_BLOCK_SIZE;
+       if(status == FAIL){
+         writeExitHelper(addr, numBytes);
+         return FAIL;
+       }
+      }
+      atomic status = writeHelper(blockAddr + i * P30_BLOCK_SIZE, data + (numBytes - bytesLeft), bytesLeft, 0xFF,0xFF);
+      if(status == FAIL){
+       writeExitHelper(addr, numBytes);
+       return FAIL;
+      }
+    }
+    
+    writeExitHelper(addr, numBytes);
+    return SUCCESS;
+  }
+  
+  command error_t Flash.erase(uint32_t addr){
+    uint16_t status, i;
+    uint32_t j;
+    
+    if(addr > 0x02000000) //not in the flash memory space
+      return FAIL;
+    if(addr < FLASH_PROTECTED_REGION)
+      return FAIL;
+    
+    addr = (addr / P30_BLOCK_SIZE) * P30_BLOCK_SIZE;
+    
+    for(i = 0; i < FLASH_PARTITION_COUNT; i++)
+      if(i != addr / FLASH_PARTITION_SIZE &&
+        FlashPartitionState[i] != FLASH_STATE_READ_INACTIVE &&
+        FlashPartitionState[i] != FLASH_STATE_READ_ACTIVE)
+       return FAIL;
+    
+    if(FlashPartitionState[addr / FLASH_PARTITION_SIZE] != FLASH_STATE_READ_INACTIVE)
+      return FAIL;
+    
+    FlashPartitionState[addr / FLASH_PARTITION_SIZE] = FLASH_STATE_ERASE;
+    
+    for(j = 0; j < P30_BLOCK_SIZE; j++){
+      uint32_t tempCheck = *(uint32_t *)(addr + j);
+      if(tempCheck != 0xFFFFFFFF)
+       break;
+      if(j == P30_BLOCK_SIZE - 1){
+       FlashPartitionState[addr / FLASH_PARTITION_SIZE] = FLASH_STATE_READ_INACTIVE;
+       return SUCCESS;
+      }
+    }
+    atomic{
+      call HplP30.blkUnlock(addr);
+      //      status = eraseFlash(addr);
+      status = call HplP30.blkErase(addr);
+    }
+    FlashPartitionState[addr / FLASH_PARTITION_SIZE] = FLASH_STATE_READ_INACTIVE;
+    if(status != SUCCESS)
+      return FAIL;
+    
+    return SUCCESS;
+  }
+
+  // WARNING: Check the endien of this
+  command error_t Flash.read(uint32_t addr, uint8_t* buf, uint32_t len) {
+    error_t status;
+
+    uint8_t databyte;
+    /*
+    uint16_t dataword;
+    
+    while(len > 1) {
+      atomic {
+       status = call HplP30.readWordBurst(addr, &dataword);
+      }
+      if(status != SUCCESS)
+       return FAIL;
+      
+      *((uint16_t*) buf) = dataword;
+
+      addr += 2;
+      buf += 2;
+      len -= 2;
+    }
+
+    if(len == 1) {
+      atomic {
+       status = call HplP30.readWordBurst(addr, &dataword);
+      }
+      if(status != SUCCESS)
+       return FAIL;
+
+      *buf = (uint8_t) dataword;
+    }
+    */
+
+    while(len > 0) {
+      atomic {
+       status = call HplP30.readByteBurst(addr, &databyte);
+      }
+      if(status != SUCCESS)
+       return FAIL;
+      
+      *buf = databyte;
+
+      addr += 1;
+      buf += 1;
+      len -= 1;
+    }
+
+    return SUCCESS;
+  }
+}
diff --git a/tos/chips/pxa27x/p30/HplP30.nc b/tos/chips/pxa27x/p30/HplP30.nc
new file mode 100644 (file)
index 0000000..692498a
--- /dev/null
@@ -0,0 +1,45 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Phil Buonadonna
+ */
+
+interface HplP30 {
+
+  async command error_t progWord(uint32_t addr, uint16_t word);
+  async command error_t progBuffer(uint32_t addr, uint16_t *data, uint8_t len);
+  async command error_t blkErase(uint32_t blkaddr);
+  async command error_t blkLock(uint32_t blkaddr);
+  async command error_t blkUnlock(uint32_t blkaddr);
+
+  async command error_t readByteBurst(uint32_t addr, uint8_t* bytex);
+  async command error_t readWordBurst(uint32_t addr, uint16_t* word);
+}
diff --git a/tos/chips/pxa27x/p30/HplP30P.nc b/tos/chips/pxa27x/p30/HplP30P.nc
new file mode 100644 (file)
index 0000000..0ab2b68
--- /dev/null
@@ -0,0 +1,179 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Phil Buonadonna
+ *
+ */
+#include <P30.h>
+module HplP30P {
+  provides interface HplP30;
+}
+
+implementation {
+
+  volatile uint16_t * devBaseAddress = (uint16_t *)(0x0);
+
+  async command error_t HplP30.progWord(uint32_t addr, uint16_t word) {
+    volatile uint16_t *blkAddress = (uint16_t *)addr;
+    uint32_t result;
+
+    *devBaseAddress = P30_READ_CLRSTATUS;
+    *blkAddress = P30_WRITE_WORDPRGSETUP;
+    *blkAddress = word;
+
+    do {
+      result = *blkAddress;
+    } while ((result & P30_SR_DWS) == 0);
+
+    *blkAddress = P30_READ_READARRAY;
+
+    if (result & (P30_SR_PS | P30_SR_VPPS | P30_SR_BLS)) {
+      return FAIL;
+    }
+
+    return SUCCESS;
+
+  }
+
+  async command error_t HplP30.progBuffer(uint32_t addr, uint16_t *data, uint8_t len) {
+    volatile uint16_t *blkAddress = (uint16_t *)addr;
+    uint32_t i,result;
+    error_t error = SUCCESS;
+
+    if (len <= 0) {
+      error = EINVAL;
+      goto done;
+    }
+
+    *devBaseAddress = P30_READ_CLRSTATUS;
+    *blkAddress = P30_WRITE_BUFPRG;
+
+    result = *blkAddress;
+    if ((result & P30_SR_DWS) == 0) {
+      error = FAIL;
+      goto cleanup;
+    }
+
+    *blkAddress = len-1;
+    
+    for (i=0;i<len;i++) {
+      blkAddress[i] = data[i];
+    }
+    
+    *blkAddress = P30_WRITE_BUFPRGCONFIRM;
+
+    do {
+      result = *blkAddress;
+    } while ((result & P30_SR_DWS) == 0);
+
+    if (result & (P30_SR_PS | P30_SR_VPPS)) {
+      error = FAIL;
+      goto done;
+    }
+  cleanup:
+    *blkAddress = P30_READ_READARRAY;
+  done:
+    return error;
+
+  }
+
+  async command error_t HplP30.blkErase(uint32_t blkaddr) {
+    volatile uint16_t *blkAddress = (uint16_t *)blkaddr;
+    uint32_t result;
+
+    *devBaseAddress = P30_READ_CLRSTATUS;
+    *blkAddress = P30_ERASE_BLKSETUP;
+    *blkAddress = P30_ERASE_BLKCONFIRM;
+
+    do {
+      result = *blkAddress;
+    } while ((result & P30_SR_DWS) == 0);
+
+    *blkAddress = P30_READ_READARRAY;
+
+    if (result & (P30_SR_ES | P30_SR_VPPS | P30_SR_BLS)) {
+      return FAIL;
+    }
+
+    return SUCCESS;
+
+  }
+
+  async command error_t HplP30.blkLock(uint32_t blkaddr) {
+    volatile uint16_t *blkAddress = (uint16_t*) blkaddr;
+
+    asm volatile (
+                 ".align 5\n\t"
+                 "strh %0,[%3]\n\t"
+                 "strh %1,[%3]\n\t"
+                 "strh %2,[%3]\n\t"
+                 : 
+                 :"r" (P30_LOCK_SETUP), 
+                 "r" (P30_LOCK_LOCK), 
+                 "r" (P30_READ_READARRAY),
+                 "r" (blkaddr)
+                 );
+
+    return SUCCESS;
+  }
+
+  async command error_t HplP30.blkUnlock(uint32_t blkaddr) {
+
+    asm volatile (
+                 ".align 5\n\t"
+                 "strh %0,[%3]\n\t"
+                 "strh %1,[%3]\n\t"
+                 "strh %2,[%3]\n\t"
+                 : 
+                 : "r" (P30_LOCK_SETUP), 
+                 "r" (P30_LOCK_UNLOCK), 
+                 "r" (P30_READ_READARRAY),
+                 "r" (blkaddr)
+                 );
+
+    return SUCCESS;
+
+  }
+
+  /* THIS FUNCTION IS UNTESTED, USE READBYTEBURST FOR NOW */
+  async command error_t HplP30.readWordBurst(uint32_t addr, uint16_t* word) {
+    volatile uint16_t *blkAddress = (uint16_t *)addr;
+    *word = *blkAddress;
+    return SUCCESS;
+  }
+
+  async command error_t HplP30.readByteBurst(uint32_t addr, uint8_t* bytex) {
+    volatile uint8_t *blkAddress = (uint8_t *)addr;
+    *bytex = *blkAddress;
+    return SUCCESS;
+  }
+
+}
diff --git a/tos/chips/pxa27x/p30/P30.h b/tos/chips/pxa27x/p30/P30.h
new file mode 100644 (file)
index 0000000..67de518
--- /dev/null
@@ -0,0 +1,90 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Phil Buonadonna
+ */
+
+#ifndef _P30_H
+#define _P30_H
+
+#define P30_READ_READARRAY     (0x00FF)
+#define P30_READ_RSR           (0x0070)
+#define P30_READ_RCR           (0x0090)
+#define P30_READ_QUERY         (0x0098)
+#define P30_READ_CLRSTATUS     (0x0050)
+
+#define P30_WRITE_WORDPRGSETUP (0x0040)
+#define P30_WRITE_ALTWORDPRGSETUP (0x0010)
+#define P30_WRITE_BUFPRG       (0x00E8)
+#define P30_WRITE_BUFPRGCONFIRM (0x00D0)
+#define P30_WRITE_BEFPSETUP    (0x0080)
+#define P30_WRITE_BEFPCONFIRM  (0x00D0)
+
+#define P30_ERASE_BLKSETUP     (0x0020)
+#define P30_ERASE_BLKCONFIRM   (0x00D0)
+
+#define P30_SUSPEND_SUSPEND    (0x00B0)
+#define P30_SUSPEND_RESUME     (0x00D0)
+
+#define P30_LOCK_SETUP         (0x0060)
+#define P30_LOCK_LOCK          (0x0001)
+#define P30_LOCK_LOCKDOWN      (0x002F)
+#define P30_LOCK_UNLOCK                (0x00D0)
+
+#define P30_PROT_PSRSETUP      (0x00C0)
+
+#define P30_CONFIG_RCRSETUP    (0x0060)
+#define P30_CONFIG_RCR         (0x0003)
+
+#define P30_SR_DWS             (1 << 7)
+#define P30_SR_ESS             (1 << 6)
+#define P30_SR_ES              (1 << 5)
+#define P30_SR_PS              (1 << 4)
+#define P30_SR_VPPS            (1 << 3)
+#define P30_SR_PSS             (1 << 2)
+#define P30_SR_BLS             (1 << 1)
+#define P30_SR_BWS             (1 << 0)
+
+#define P30_REGION_SIZE (0x100000)
+#define P30_BLOCK_SIZE (0x20000)
+
+typedef struct p30_volume_info_t {
+  uint8_t base; // base block
+  uint8_t size; // num blocks
+} p30_volume_info_t;
+
+#define FLASH_PARTITION_COUNT 16
+#define FLASH_PARTITION_SIZE 0x200000
+#define FLASH_PROTECTED_REGION 0x00200000
+#define FLASH_PROGRAM_BUFFER_SIZE 32
+  //#define FLASH_NOT_SUPPORTED 0x100
+
+#endif /* _P30_H */
diff --git a/tos/chips/pxa27x/p30/P30BlockC.nc b/tos/chips/pxa27x/p30/P30BlockC.nc
new file mode 100644 (file)
index 0000000..cdc65a3
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+configuration P30BlockC {
+  provides interface BlockWrite as Write[ storage_volume_t volume ];
+  provides interface BlockRead as Read[ storage_volume_t volume ];
+}
+
+implementation {
+  components P30BlockP;
+  P30BlockP = Write;
+  P30BlockP = Read;
+
+  components HalP30C;
+  P30BlockP.Flash -> HalP30C;
+}
diff --git a/tos/chips/pxa27x/p30/P30BlockP.nc b/tos/chips/pxa27x/p30/P30BlockP.nc
new file mode 100644 (file)
index 0000000..c75c5cb
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+#include <P30.h>
+#include <StorageVolumes.h>
+
+module P30BlockP {
+  provides interface BlockRead as Read[ storage_volume_t block ];
+  provides interface BlockWrite as Write[ storage_volume_t block ];
+
+  uses interface Leds;
+  uses interface Flash;
+}
+
+implementation {
+  typedef enum {
+    S_IDLE,
+    S_READ,
+    S_WRITE,
+    S_ERASE,
+    S_CRC,
+    S_SYNC,
+
+  } p30_block_state_t;
+  norace p30_block_state_t m_state = S_IDLE;
+  storage_volume_t clientId = 0xff;
+  storage_addr_t clientAddr;
+  void* clientBuf;
+  storage_len_t clientLen;
+  error_t clientResult;
+
+  /*
+   * This is a helper function to translate from the client address
+   * space to the underlying HalP30 address space. This is necessary
+   * because HAL provides a flat 32MB interface.
+   */
+  uint32_t xlateAddr(storage_volume_t b, storage_addr_t addr) {
+    return P30_VMAP[b].base * FLASH_PARTITION_SIZE + addr;
+  }
+
+  task void signalDoneTask() {
+    switch(m_state) {
+    case S_WRITE:
+      m_state = S_IDLE;
+      signal Write.writeDone[clientId](clientAddr, clientBuf, clientLen, clientResult);
+      break;
+   case S_SYNC:
+      m_state = S_IDLE;
+      signal Write.syncDone[clientId](SUCCESS);
+      break;
+    case S_ERASE:
+      m_state = S_IDLE;
+      signal Write.eraseDone[clientId](clientResult);
+      break;
+   case S_READ:
+      m_state = S_IDLE;
+      signal Read.readDone[clientId](clientAddr, clientBuf, clientLen, clientResult);
+      break;
+    default:
+      break;
+    }
+  }
+
+  /*
+   * Translate the address to a physical flash address and do the
+   * write.
+   */
+  command error_t Write.write[ storage_volume_t b ]( storage_addr_t addr, 
+                                                   void* buf, 
+                                                   storage_len_t len ) {
+    uint32_t physAddr;
+
+    if(m_state != S_IDLE)
+      return EBUSY;
+
+    // error check
+    if(addr + len > P30_VMAP[b].size * FLASH_PARTITION_SIZE)
+      return EINVAL;
+
+    clientId = b;
+    clientAddr = addr;
+    clientBuf = buf;
+    clientLen = len;
+
+    m_state = S_WRITE;
+
+    physAddr = xlateAddr(b, addr);
+
+    clientResult = call Flash.write(physAddr, (uint8_t*) buf, len);
+
+    post signalDoneTask();
+    return SUCCESS;
+  }
+  
+  /*
+   * Sync doesn't really do anything because Intel PXA is
+   * write-through.
+   */
+  command error_t Write.sync[ storage_volume_t b ]() {
+
+    m_state = S_SYNC;
+    clientId = b;
+
+    post signalDoneTask();
+    return SUCCESS;
+  }
+  
+  /*
+   * Because each 2MB partition is divided into 128k erasable pieces,
+   * we must go through and erase all of them.
+   */
+  command error_t Write.erase[ storage_volume_t b ]() {
+   uint32_t physAddr;
+   uint32_t blocks;
+
+    if(m_state != S_IDLE)
+      return EBUSY;
+
+    clientId = b;
+
+    m_state = S_ERASE;
+    physAddr = xlateAddr(b,0);
+    for(blocks = ((P30_VMAP[b].size)*FLASH_PARTITION_SIZE)/P30_BLOCK_SIZE;
+       blocks > 0;
+       blocks--) {
+      clientResult = call Flash.erase(physAddr);
+      if(clientResult != SUCCESS)
+       break;
+      physAddr += P30_BLOCK_SIZE;
+    }
+
+    post signalDoneTask();
+    return SUCCESS;
+  }
+
+  /*
+   * Translate the address to a physical flash address and do the
+   * read.
+   */
+  command error_t Read.read[ storage_volume_t b ]( storage_addr_t addr,
+                                                 void* buf,
+                                                 storage_len_t len ) {
+   uint32_t physAddr;
+
+    if(m_state != S_IDLE)
+      return FAIL;
+
+    clientId = b;
+    clientAddr = addr;
+    clientBuf = buf;
+    clientLen = len;
+
+    m_state = S_READ;
+    physAddr = xlateAddr(b,addr);
+
+    call Flash.read((uint32_t) physAddr, (uint8_t*) buf, (uint32_t) len);
+
+    post signalDoneTask();
+    return SUCCESS;
+  }
+  
+  
+  command error_t Read.computeCrc[ storage_volume_t b ]( storage_addr_t addr,
+                                                       storage_len_t len,
+                                                       uint16_t crc) {
+    m_state = S_CRC;
+    clientId = b;
+
+    post signalDoneTask();
+    return SUCCESS;
+  }
+
+  command storage_len_t Read.getSize[ storage_volume_t b]() {
+    return P30_VMAP[b].size * FLASH_PARTITION_SIZE;
+  }
+
+  default event void Write.writeDone[ storage_volume_t b ]( storage_addr_t addr, void* buf, storage_len_t len, error_t error ) {}
+  default event void Write.eraseDone[ storage_volume_t b ]( error_t error ) {}
+  default event void Write.syncDone[ storage_volume_t b ]( error_t error ) {}
+
+  default event void Read.readDone[ storage_volume_t b ]( storage_addr_t addr, void* buf, storage_len_t len, error_t error ) {}
+  default event void Read.computeCrcDone[ storage_volume_t b ]( storage_addr_t addr, storage_len_t len, uint16_t crc, error_t error ) {}
+
+}
diff --git a/tos/chips/pxa27x/p30/P30ConfigC.nc b/tos/chips/pxa27x/p30/P30ConfigC.nc
new file mode 100644 (file)
index 0000000..ffedef9
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+configuration P30ConfigC {
+  provides interface ConfigStorage[ storage_volume_t volume ];
+  provides interface Mount[ storage_volume_t volume ];
+}
+
+implementation {
+  components P30ConfigP, MainC;
+  ConfigStorage = P30ConfigP.Config;
+  Mount = P30ConfigP.Mount;
+
+  components HalP30C;
+  P30ConfigP.Flash -> HalP30C;
+}
diff --git a/tos/chips/pxa27x/p30/P30ConfigP.nc b/tos/chips/pxa27x/p30/P30ConfigP.nc
new file mode 100644 (file)
index 0000000..dbd239b
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+#include <P30.h>
+#include <StorageVolumes.h>
+
+module P30ConfigP {
+  provides interface ConfigStorage as Config[ storage_volume_t v ];
+  provides interface Mount[ storage_volume_t v ];
+
+  uses interface Flash;
+  uses interface Leds;
+}
+
+implementation {
+  /*
+   * These are some macros for convenience. Essentially it is cutting
+   * a 2MB chunk into a two pieces. The size of the two pieces is
+   * hardcoded by C_PARTITION_sIZE. It must be a multiple of
+   * P30_BLOCK_SIZE because that is the erasable size. The bigger you
+   * make the C_PARTITION_SIZE, the longer commits will take because
+   * it must erase all the blocks inside. On the other hand, a larger
+   * C_PARTITION_SIZE will give you a larger address space. v is the
+   * parameterized interface that is used in the context of these
+   * macros.
+   */
+#define C_PARTITION_SIZE (P30_BLOCK_SIZE*1)
+#define C_PARTITION_0 (P30_VMAP[v].base * FLASH_PARTITION_SIZE)
+#define C_PARTITION_1 (P30_VMAP[v].base * FLASH_PARTITION_SIZE + C_PARTITION_SIZE)
+  typedef uint32_t version_t;
+
+  enum {
+    /*
+     * WARNING: AT45DB has a RAM buffer that allows writes to occur
+     * without actually writing to flash. We simulate this because it
+     * makes rewrites a lot simpler. However, this essentially takes
+     * RAM overhead. However, Configstores are relatively small and
+     * the Intel PXA has a lot of main memory, so we do it anyway.
+     */
+    BUFFER_SIZE = 2048, 
+    INVALID_VERSION = 0xFFFFFFFF,
+    NUM_VOLS = _V_NUMVOLS_, //uniqueCount( "pxa27xp30.Volume" ),
+  };
+  
+  typedef enum {
+    S_IDLE,
+    S_MOUNT,
+    S_READ,
+    S_WRITE,
+    S_COMMIT,
+  } p30_config_state_t;
+  norace p30_config_state_t m_state = S_IDLE;
+
+  /*
+   * Each instantiation of a Configstore must keep certain state. This
+   * includes the current version of the page and the active address
+   * within that page since we are splitting it into two pieces. Each
+   * Configstore must also have its own RAM buffer for concurrent
+   * operations.
+   */ 
+  uint32_t currentVersion[NUM_VOLS];
+  uint32_t activeBaseAddr[NUM_VOLS];
+  uint8_t workBuf[BUFFER_SIZE*NUM_VOLS];
+
+  storage_volume_t clientId = 0xff;
+  storage_addr_t clientAddr;
+  void* clientBuf;
+  storage_len_t clientLen;
+  error_t clientResult;
+
+  task void signalDoneTask() {
+    switch(m_state) {
+    case S_MOUNT:
+      m_state = S_IDLE;
+      signal Mount.mountDone[clientId](clientResult);
+      break;
+    case S_WRITE:
+      m_state = S_IDLE;
+      signal Config.writeDone[clientId](clientAddr, clientBuf, clientLen, clientResult);
+      break;
+    case S_COMMIT:
+      m_state = S_IDLE;
+      signal Config.commitDone[clientId](SUCCESS);
+      break;
+    case S_READ:
+      m_state = S_IDLE;
+      signal Config.readDone[clientId](clientAddr, clientBuf, clientLen, clientResult);
+      break;
+    default:
+      break;
+    }
+  }
+
+  /* 
+   * Erase a config partition. It may be more than one P30 block size,
+   * so erase multiple times.
+   */
+  void eraseConfigPartition(uint32_t base) {
+    uint32_t blocks;
+    
+    for(blocks = C_PARTITION_SIZE / P30_BLOCK_SIZE;
+       blocks > 0;
+       blocks--) {
+      call Flash.erase(base);
+      base += P30_BLOCK_SIZE;
+    }
+  }
+
+  /*
+   * Read the data directly from the RAM buffer into the client
+   * buffer... Might be read from Flash depending on semantics
+   */
+  command error_t Config.read[storage_volume_t v](storage_addr_t addr,
+                                                         void* buf,
+                                                         storage_len_t len) {
+    uint32_t i;
+
+    clientId = v;
+    clientAddr = addr;
+    clientBuf = buf;
+    clientLen = len;
+
+    m_state = S_READ;
+
+    /*
+    for(i = addr; i < addr + len; i++) {
+      ((uint8_t*)buf)[i-addr] = workBuf[(v*BUFFER_SIZE)+i];
+    }
+    */
+    call Flash.read(activeBaseAddr[v] + addr,
+                   (uint8_t*) buf,
+                   len);
+    
+    post signalDoneTask();
+    
+    return SUCCESS;
+  }
+
+  /*
+   * Writes the client data into the given address in the RAM
+   * buffer. Data is not actually written to flash until the user
+   * commits.
+   */
+  command error_t Config.write[storage_volume_t v](storage_addr_t addr,
+                                                          void* buf,
+                                                          storage_len_t len) {
+    uint32_t i;
+
+    clientId = v;
+    clientAddr = addr;
+    clientBuf = buf;
+    clientLen = len;
+
+    // error check
+    if(addr + len > BUFFER_SIZE)
+      return FAIL; // out of my artificial bounds
+
+    m_state = S_WRITE;
+
+    for(i = addr; i < addr + len; i++)
+      workBuf[(v*BUFFER_SIZE)+i] = ((uint8_t*)buf)[i-addr];
+
+    clientResult = SUCCESS;
+    post signalDoneTask();
+    return SUCCESS;
+  }
+
+  /*
+   * Determine which partition to write to based on the current one
+   * that is active. Also update the version number. Version numbers
+   * are 0, 1, 2, or 3 and wraps around. Write the RAM buffer out
+   * first BEFORE writing the the new version number. After the
+   * version number is written, the active config is now atomically
+   * switched. Then update any other in memory metadata.
+   */
+  command error_t Config.commit[storage_volume_t v]() {
+    uint32_t destBaseAddr;
+
+    if(activeBaseAddr[v] == C_PARTITION_0)
+      destBaseAddr = C_PARTITION_1;
+    else
+      destBaseAddr = C_PARTITION_0;
+
+    m_state = S_COMMIT;
+
+    clientId = v;
+    clientResult = SUCCESS;
+
+    currentVersion[v] = (currentVersion[v] + 1) % 4;
+
+    // erase target flash area before writing to it
+    eraseConfigPartition(destBaseAddr);
+
+    // write RAM buffer out
+    call Flash.write(destBaseAddr,
+                    (uint8_t*) &workBuf[v*BUFFER_SIZE],
+                    BUFFER_SIZE);
+
+    call Flash.write(destBaseAddr + C_PARTITION_SIZE - sizeof(version_t),
+                    (uint8_t*) &currentVersion[v],
+                    sizeof(version_t));
+
+    activeBaseAddr[v] = destBaseAddr;
+
+    post signalDoneTask();
+    return SUCCESS;
+  }
+
+  /*
+   * The only metadata that needs to be saved is a version
+   * number. Thus you get the whole partition minus the version number
+   * in terms of space.
+   */
+  command storage_len_t Config.getSize[storage_volume_t v]() {
+    return C_PARTITION_SIZE - sizeof(version_t);
+  }
+
+  command bool Config.valid[storage_volume_t v]() {
+    return TRUE;
+  }
+
+  /*
+   * When a Configstore is mounted, it must do some initial
+   * book-keeping work. It first reads from the two pieces two
+   * determine, which one is the actual active one. Afterwards, we
+   * read from flash into the RAM buffer or else subsequent reads will
+   * not work.
+   */
+  command error_t Mount.mount[storage_volume_t v]() {
+    version_t v0;
+    version_t v1;
+
+    m_state = S_MOUNT;
+    clientResult = SUCCESS;
+    clientId = v;
+
+    currentVersion[v] = INVALID_VERSION;
+
+    // read version #s from both sectors and determine new one
+    // pick among 0 1 2 3 FFFF
+    call Flash.read(C_PARTITION_0 + C_PARTITION_SIZE - sizeof(version_t),
+                   (uint8_t*)&v0, sizeof(version_t));
+    call Flash.read(C_PARTITION_1 + C_PARTITION_SIZE - sizeof(version_t),
+                   (uint8_t*)&v1, sizeof(version_t));
+
+    // this logic in this could probably be simplified
+    if(v0 == INVALID_VERSION && v1 == INVALID_VERSION) {
+      // clean partition
+      activeBaseAddr[v] = C_PARTITION_0;
+      currentVersion[v] = 0;
+    }
+    else if(v1 == INVALID_VERSION) {
+      // use v0
+      activeBaseAddr[v] = C_PARTITION_0;
+      currentVersion[v] = v0;
+    }
+    else if(v0 == INVALID_VERSION) {
+      // use v1
+      activeBaseAddr[v] = C_PARTITION_1;
+      currentVersion[v] = v1;
+    }
+    else if((v0 + 1) % 4 == v1) {
+      // use v1
+      activeBaseAddr[v] = C_PARTITION_1;
+      currentVersion[v] = v1;
+    }
+    else if((v1 + 1) % 4 == v0) {
+      // use v0
+      activeBaseAddr[v] = C_PARTITION_0;
+      currentVersion[v] = v0;
+    }
+    else {
+      // corrupted? erase both, might want to improve this later
+      eraseConfigPartition(C_PARTITION_0);
+      eraseConfigPartition(C_PARTITION_1);
+      currentVersion[v] = 0;
+    }
+
+    // read into RAM buffer
+    call Flash.read(activeBaseAddr[v], (uint8_t*)&workBuf[v*BUFFER_SIZE], BUFFER_SIZE);
+
+    post signalDoneTask();
+    return SUCCESS;
+  }
+
+  default event void Config.readDone[storage_volume_t v](storage_addr_t addr, void* buf, storage_len_t len, error_t error) {}
+  default event void Config.writeDone[storage_volume_t v](storage_addr_t addr, void* buf, storage_len_t len, error_t error) {}
+  default event void Config.commitDone[storage_volume_t v](error_t error) {}
+  default event void Mount.mountDone[storage_volume_t v](error_t error) {}
+}
+
diff --git a/tos/chips/pxa27x/p30/P30LogC.nc b/tos/chips/pxa27x/p30/P30LogC.nc
new file mode 100644 (file)
index 0000000..e2d7d61
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+configuration P30LogC {
+
+  provides interface LogWrite as Write[ storage_volume_t volume ];
+  provides interface LogRead as Read[ storage_volume_t volume ];
+
+  uses interface Get<bool> as Circular[ storage_volume_t block ];
+}
+
+implementation {
+  components P30LogP;
+
+  P30LogP = Write;
+  P30LogP = Read;
+
+  P30LogP = Circular;
+
+  components HalP30C;
+  P30LogP.Flash -> HalP30C;
+}
diff --git a/tos/chips/pxa27x/p30/P30LogCircularP.nc b/tos/chips/pxa27x/p30/P30LogCircularP.nc
new file mode 100644 (file)
index 0000000..ac6b1f4
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+generic module P30LogCircularP( bool IS_CIRCULAR ) {
+
+  provides interface Get<bool> as Circular;
+
+}
+
+implementation {
+  
+  command bool Circular.get() {
+    return IS_CIRCULAR;
+  }
+
+}
diff --git a/tos/chips/pxa27x/p30/P30LogP.nc b/tos/chips/pxa27x/p30/P30LogP.nc
new file mode 100644 (file)
index 0000000..6754fdc
--- /dev/null
@@ -0,0 +1,584 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+#include <P30.h>
+#include <StorageVolumes.h>
+
+module P30LogP {
+  provides interface LogRead as Read[ storage_volume_t block ];
+  provides interface LogWrite as Write[ storage_volume_t block ];
+
+  uses interface Leds;
+  uses interface Flash;
+  uses interface Get<bool> as Circular[ storage_volume_t block ];
+}
+
+implementation {
+
+#define SEEK_BEGINNING (0x0)
+#define SEEK_EOL (0xFFFFFFFF)
+#define L_BASE_BLOCK(_x) (P30_VMAP[_x].base * FLASH_PARTITION_SIZE)
+#define L_PARTITIONS(_x) ((P30_VMAP[_x].size * FLASH_PARTITION_SIZE) / P30_BLOCK_SIZE)
+#define L_FULL_RECORD_SIZE (sizeof(record_data_t) + sizeof(record_meta_t))
+#define L_RECORD_DATA_SIZE 256
+#define L_MAX_RECORDS_PER_BLOCK (P30_BLOCK_SIZE / L_FULL_RECORD_SIZE) // page meta counts as one record
+  // _a = blockId (from parameterized interface), _b = page, _c = record
+#define L_RAW_OFFSET(_a,_b,_c) (L_BASE_BLOCK(_a) + (_b * P30_BLOCK_SIZE) + (_c * L_FULL_RECORD_SIZE))
+
+  enum {
+    INVALID_VERSION = 0xFFFFFFFF,
+    NUM_VOLS = _V_NUMVOLS_, //uniqueCount("pxa27xp30.Volume"),
+  };
+
+  enum {
+    PAGE_START = 0x0000,
+    PAGE_USED = 0xFFF0,
+    PAGE_AVAILABLE = 0xFFFF,
+  };
+  typedef struct page_meta_t {
+    uint16_t header;
+  } page_meta_t;
+
+  enum {
+    RECORD_VALID = 0x0000,
+    RECORD_INVALID = 0xFFF0,
+    RECORD_EMPTY = 0xFFFF,
+  };
+  typedef struct record_meta_t {
+    uint16_t status;
+    uint16_t length;
+  } record_meta_t;
+  typedef struct record_data_t {
+    uint8_t data[L_RECORD_DATA_SIZE];
+  } record_data_t;
+
+  typedef enum {
+    S_IDLE,
+    S_READ,
+    S_APPEND,
+    S_SYNC,
+    S_ERASE,
+    S_SEEK,
+  } p30_log_state_t;
+  norace p30_log_state_t m_state = S_IDLE;
+  storage_volume_t clientId = 0xff;
+  void* clientBuf;
+  storage_len_t clientLen;
+  error_t clientResult;
+
+  uint32_t firstBlock[NUM_VOLS]; // 0-15 for 2 MB
+  uint32_t lastBlock[NUM_VOLS]; // 0-15 for 2 MB
+  uint32_t nextFreeRecord[NUM_VOLS]; // 0-X depending on data size
+  storage_cookie_t readCookieOffset[NUM_VOLS]; // this is a raw offset
+  bool gbOverwriteOccured = FALSE;
+
+  /* This shuffles all the blocks when we run out of space. We have to
+   * do it in a special order so crash recovery is possible. We also
+   * have to write special bytes so we can rewrite to areas without
+   * doing a complete erase.
+   */
+  void shuffleBlocks(storage_volume_t block) {
+    page_meta_t pageMeta;
+    uint32_t pageCounter;
+    // 1. set the last block to USED, if it's already USED or START, then no effect
+    pageMeta.header = PAGE_USED;
+    call Flash.write(L_RAW_OFFSET(block, lastBlock[block], 0),
+                    (uint8_t*) &pageMeta,
+                    sizeof(page_meta_t));
+    // 2. if lastBlock + 1 is free, then set it as last block and the first record is free
+    pageCounter = (lastBlock[block] + 1) % L_PARTITIONS(block);
+    call Flash.read(L_RAW_OFFSET(block, pageCounter, 0),
+                   (uint8_t*) &pageMeta,
+                   sizeof(page_meta_t));
+    if(pageMeta.header == PAGE_AVAILABLE) {
+      nextFreeRecord[block] = 1;
+      lastBlock[block] = pageCounter;
+    }
+    else {
+      call Flash.erase(L_RAW_OFFSET(block, firstBlock[block], 0));
+      pageCounter = (firstBlock[block] + 1) % L_PARTITIONS(block);
+      pageMeta.header = PAGE_START;
+      call Flash.write(L_RAW_OFFSET(block, pageCounter, 0),
+                      (uint8_t*) &pageMeta,
+                      sizeof(page_meta_t));
+      nextFreeRecord[block] = 1;
+      lastBlock[block] = firstBlock[block];
+      firstBlock[block] = pageCounter;
+      gbOverwriteOccured = TRUE;
+    }
+  }
+
+  /*
+   * Converts a cookie to a page/record/offset tuple
+   */
+  void cookieToTuple(uint32_t cookie, storage_volume_t block,
+                    uint32_t *page, uint32_t *record, uint32_t *offset) {
+
+    uint32_t mypage;
+    uint32_t myrecord;
+    uint32_t myoffset;
+
+    mypage = (cookie - L_BASE_BLOCK(block)) / P30_BLOCK_SIZE;
+    cookie = (cookie - L_BASE_BLOCK(block)) % P30_BLOCK_SIZE;
+    myrecord = cookie / L_FULL_RECORD_SIZE;
+    myoffset = (cookie % L_FULL_RECORD_SIZE) - sizeof(record_meta_t);
+
+    *page = mypage;
+    *record = myrecord;
+    *offset = myoffset;
+  }
+
+  /*
+   * Ideally, Logstorage would require a mount too, but it doesn't so
+   * it's a total hack. Before any operation, we have to check if a
+   * mount occurred. Mount initializes the your logblock.
+   */
+  uint8_t mountBits[NUM_VOLS];
+  void myMount(storage_volume_t block) {
+    page_meta_t pageMeta;
+    record_meta_t recordMeta;
+    uint32_t pageCounter;
+    uint32_t recordCounter;
+
+    uint32_t freePages = 0;
+
+    if(mountBits[block] != 0)
+      return;
+
+    // scan all 128k pages for page meta
+
+    // annoying corner case of all free pages, write the first page as START
+    for(pageCounter = 0; pageCounter < L_PARTITIONS(block); pageCounter++) {
+      call Flash.read(L_RAW_OFFSET(block, pageCounter, 0),
+                     (uint8_t*)&pageMeta,
+                     sizeof(page_meta_t));
+      if(pageMeta.header == PAGE_AVAILABLE)
+       freePages++;
+    }
+    if(freePages == L_PARTITIONS(block)) {
+      pageMeta.header = PAGE_START;
+      call Flash.write(L_RAW_OFFSET(block, 0, 0), (uint8_t*) &pageMeta, sizeof(page_meta_t));
+    }
+
+    // if we find a START page, then we are done
+    for(pageCounter = 0; pageCounter < L_PARTITIONS(block); pageCounter++) {
+      call Flash.read(L_RAW_OFFSET(block, pageCounter, 0),
+                     (uint8_t*)&pageMeta,
+                     sizeof(page_meta_t));
+      if(pageMeta.header == PAGE_START) {
+       firstBlock[block] = pageCounter;
+       break;
+      }
+    }
+    // if we didn't find a START page, first page is right after AVAILABLE
+    if(pageCounter == L_PARTITIONS(block)) {
+      for(pageCounter = 0; pageCounter < L_PARTITIONS(block); pageCounter++) {
+       call Flash.read(L_RAW_OFFSET(block, pageCounter, 0),
+                       (uint8_t*)&pageMeta,
+                       sizeof(page_meta_t));
+       if(pageMeta.header == PAGE_AVAILABLE) {
+         pageCounter = (pageCounter + 1) % L_PARTITIONS(block);
+         firstBlock[block] = pageCounter;
+         // mark that block as a START block
+         pageMeta.header = PAGE_START;
+         call Flash.write(L_RAW_OFFSET(block, pageCounter, 0),
+                          (uint8_t*) &pageMeta,
+                          sizeof(page_meta_t));
+         break;
+       }
+      }
+    }
+    // now we scan for next free record location
+    pageCounter = firstBlock[block];
+    for(recordCounter = 1; recordCounter < L_MAX_RECORDS_PER_BLOCK; recordCounter++) {
+      call Flash.read(L_RAW_OFFSET(block, pageCounter, recordCounter),
+                     (uint8_t*) &recordMeta,
+                     sizeof(record_meta_t));
+      if(recordMeta.status == RECORD_EMPTY) {
+       nextFreeRecord[block] = recordCounter;
+       lastBlock[block] = pageCounter;
+       break;
+      }
+    }
+    // Didn't find a free record in the START block, search the first FREE block
+    if(recordCounter == L_MAX_RECORDS_PER_BLOCK) {
+      for(pageCounter = 0; pageCounter < L_PARTITIONS(block); pageCounter++) {
+       call Flash.read(L_RAW_OFFSET(block, pageCounter, 0),
+                       (uint8_t*)&pageMeta,
+                       sizeof(page_meta_t));
+       if(pageMeta.header == PAGE_AVAILABLE) {
+         for(recordCounter = 1; recordCounter < L_MAX_RECORDS_PER_BLOCK; recordCounter++) {
+           call Flash.read(L_RAW_OFFSET(block, pageCounter, recordCounter),
+                           (uint8_t*) &recordMeta,
+                           sizeof(record_meta_t));
+           if(recordMeta.status == RECORD_EMPTY) {
+             lastBlock[block] = pageCounter;
+             nextFreeRecord[block] = recordCounter;
+             goto mount_complete;
+           }
+         }
+       }
+      }
+      // if here, you didn't find the last block, it must be right before the START block
+      // special case the wrap around
+      if(firstBlock[block] == 0)
+       lastBlock[block] = L_PARTITIONS(block) - 1;
+      else
+       lastBlock[block] = firstBlock[block] - 1;
+      // that last block must be full, so shuffle it
+      shuffleBlocks(block);
+    }
+
+  mount_complete:
+    readCookieOffset[block] = SEEK_BEGINNING;
+    mountBits[block] = 1;
+  }
+
+  task void signalDoneTask() {
+    switch(m_state) {
+    case S_APPEND:
+      m_state = S_IDLE;
+      signal Write.appendDone[clientId](clientBuf, clientLen, gbOverwriteOccured, clientResult);
+      gbOverwriteOccured = FALSE;
+      break;
+    case S_SYNC:
+      m_state = S_IDLE;
+      signal Write.syncDone[clientId](SUCCESS);
+      break;
+    case S_ERASE:
+      m_state = S_IDLE;
+      signal Write.eraseDone[clientId](clientResult);
+      break;
+   case S_READ:
+      m_state = S_IDLE;
+      signal Read.readDone[clientId](clientBuf, clientLen, clientResult);
+      break;
+   case S_SEEK:
+      m_state = S_IDLE;
+      signal Read.seekDone[clientId](SUCCESS);
+      break;
+    default:
+      break;
+    }
+  }
+
+  /*
+   * Invariant should be that everytime after an append completes,
+   * nextFreeRecord should point to a valid free record slot. Uses
+   * nextFreeRecord to append.
+   */
+  command error_t Write.append[ storage_volume_t block ](void* buf, storage_len_t len) {
+    record_meta_t recordMeta;
+
+    myMount(block);
+    
+    // error check
+    if(len > L_RECORD_DATA_SIZE)
+      return EINVAL;
+
+    // if non circular log, fail
+    if((!call Circular.get[block]()) &&
+       (lastBlock[block] == (L_PARTITIONS(block) - 1)) &&
+       (nextFreeRecord[block] == (L_MAX_RECORDS_PER_BLOCK - 1)))
+      return FAIL;
+
+    m_state = S_APPEND;
+    clientId = block;
+    clientBuf = buf;
+    clientLen = len;
+
+    // if you try to log 0, just immediately succeed, this really shouldn't happen
+    if(len == 0) {
+      clientResult = SUCCESS;
+      post signalDoneTask();
+      return SUCCESS;
+    }
+
+    // if readCookie was on SEEK_EOL, adjust it back to here
+    if(readCookieOffset[block] == SEEK_EOL)
+      readCookieOffset[block] = L_RAW_OFFSET(block, lastBlock[block], nextFreeRecord[block]) + sizeof(record_meta_t);
+      
+    // use next free record, write the INVALID, write the data, write the VALID
+    recordMeta.status = RECORD_INVALID;
+    recordMeta.length = len;
+    call Flash.write(L_RAW_OFFSET(block, lastBlock[block], nextFreeRecord[block]),
+                    (uint8_t*) &recordMeta,
+                    sizeof(record_meta_t));
+    call Flash.write(L_RAW_OFFSET(block, lastBlock[block], nextFreeRecord[block]) +
+                    sizeof(record_meta_t),
+                    (uint8_t*) buf, len);
+    recordMeta.status = RECORD_VALID;
+    call Flash.write(L_RAW_OFFSET(block, lastBlock[block], nextFreeRecord[block]),
+                    (uint8_t*) &recordMeta,
+                    sizeof(record_meta_t));
+    nextFreeRecord[block]++;
+    // see if you need to adjust blocks or shuffle
+    if(nextFreeRecord[block] == L_MAX_RECORDS_PER_BLOCK)
+      shuffleBlocks(block);
+
+    clientResult = SUCCESS;
+    post signalDoneTask();
+    
+    return SUCCESS;
+  }
+
+  /*
+   * We use nextFreeRecord to get the cookie
+   */
+  command storage_cookie_t Write.currentOffset[ storage_volume_t block ]() {
+    myMount(block);
+
+    return L_RAW_OFFSET(block, lastBlock[block], nextFreeRecord[block]) +
+      sizeof(record_meta_t);
+  }
+
+  /*
+   * First we erase all the log data blocks so that they can be
+   * reused. Then we zero the cookies and then write them to our
+   * partitions like the append operation. If we crash in the middle,
+   * you may have to erase again. However, if an erase does fail, at
+   * least all your data will still be there, so that you can try
+   * again.
+   */
+  command error_t Write.erase[storage_volume_t block]() {
+    uint32_t i;
+
+    for(i = 0; i < L_PARTITIONS(block); i++) {
+      call Flash.erase(L_BASE_BLOCK(block) + (i * P30_BLOCK_SIZE));
+    }
+
+    mountBits[block] = 0;
+    myMount(block);
+
+    // ... starting block implicitly written by mount
+
+    m_state = S_ERASE;
+    clientId = block;
+    clientResult = SUCCESS;
+    post signalDoneTask();
+
+    return SUCCESS;
+  }
+
+  /*
+   * Sync does nothing really because unlike the AT45DB, Intel P30
+   * writes directly through.
+   */
+  command error_t Write.sync[storage_volume_t block]() {
+    myMount(block);
+
+    m_state = S_SYNC;
+    
+    clientId = block;
+    clientResult = SUCCESS;
+    
+    post signalDoneTask();
+    return SUCCESS;
+
+  }
+
+  /*
+   * Sanity check the read cookie and adjust for any other special
+   * cookies. Because you can seek to the byte, must it is saved in
+   * flash as records, you have to do a lot of tricky seeking, but
+   * it's done here. Also has to handle any pages that are spilled
+   * over.
+   */
+  command error_t Read.read[ storage_volume_t block ](void* buf, storage_len_t len) {
+    record_meta_t recordMeta;
+    uint32_t recordCounter;
+    uint32_t pageCounter;
+    uint32_t offset;
+
+    clientId = block;
+    clientBuf = buf;
+    clientResult = SUCCESS;
+
+    myMount(block);
+
+    m_state = S_READ;
+    
+    if(len == 0 || readCookieOffset[block] == SEEK_EOL) {
+      clientResult = SUCCESS;
+      clientLen = 0;
+      post signalDoneTask();
+      return SUCCESS;
+    }
+    
+    // adjust SEEK_BEGINNING to a real offset
+    if(readCookieOffset[block] == SEEK_BEGINNING) {
+      readCookieOffset[block] = L_RAW_OFFSET(block, firstBlock[block], 1) +
+       sizeof(record_meta_t);
+    }
+    
+    // convert the cookie to something useful
+    cookieToTuple(readCookieOffset[block], block, &pageCounter, &recordCounter, &offset);
+    // sanity check readCookie
+    call Flash.read(L_RAW_OFFSET(block, pageCounter, recordCounter),
+                   (uint8_t*) &recordMeta,
+                   sizeof(record_meta_t));
+    if((recordMeta.status == RECORD_VALID) && (offset > len)) {
+      readCookieOffset[block] = L_RAW_OFFSET(block, firstBlock[block], 0) + sizeof(record_meta_t);
+      cookieToTuple(readCookieOffset[block], block, &pageCounter, &recordCounter, &offset);
+    }
+
+    clientLen = 0; // reset how much actually read and count up
+
+    
+    while(len != 0) {
+      call Flash.read(L_RAW_OFFSET(block, pageCounter, recordCounter),
+                     (uint8_t*) &recordMeta,
+                     sizeof(record_meta_t));
+      if(recordMeta.status == RECORD_INVALID) {
+       goto advance_counter;
+      }
+      if(recordMeta.status == RECORD_EMPTY) {
+       readCookieOffset[block] = SEEK_EOL;
+       post signalDoneTask();
+       return SUCCESS;
+      }
+      // read partial block and finish
+      if(len < recordMeta.length + offset) {
+       call Flash.read(L_RAW_OFFSET(block, pageCounter, recordCounter) +
+                       offset + sizeof(record_meta_t),
+                       buf,
+                       len);
+       offset = len;
+       buf = buf + len;
+       len = 0;
+      }
+      else {
+       call Flash.read(L_RAW_OFFSET(block, pageCounter, recordCounter) + 
+                       offset + sizeof(record_meta_t),
+                       buf,
+                       recordMeta.length - offset);
+       clientLen = clientLen + recordMeta.length - offset;
+       len -= recordMeta.length - offset;
+       buf = buf + recordMeta.length - offset;
+       offset = 0;
+      
+      advance_counter:
+       recordCounter++;
+       if((recordCounter >= L_MAX_RECORDS_PER_BLOCK) && (pageCounter == lastBlock[block])) {
+         readCookieOffset[block] = SEEK_EOL;
+         post signalDoneTask();
+         return SUCCESS;
+       }
+       // need to adjust page possibly if spills
+       // also need to check if reached end of log (lastBlock[block] or RECORD_AVAILABLE)
+       if(recordCounter >= L_MAX_RECORDS_PER_BLOCK) {
+         pageCounter = (pageCounter + 1) % L_PARTITIONS(block);
+         recordCounter = 1;
+       }
+      }
+    }
+
+    readCookieOffset[block] = L_RAW_OFFSET(block, pageCounter, recordCounter) +
+      sizeof(record_meta_t) + offset;
+    post signalDoneTask();
+    return SUCCESS;
+  }
+    
+  command storage_cookie_t Read.currentOffset[ storage_volume_t block ]() {
+    myMount(block);
+    return readCookieOffset[block];
+  }
+
+  /*
+   * Just set the cookie. If you seek into an invalid area, just set
+   * it at SEEK_BEGINNING.
+   */
+  command error_t Read.seek[ storage_volume_t block ](storage_cookie_t offset) {
+    uint32_t page;
+    uint32_t record;
+    uint32_t recordOffset;
+    record_meta_t recordMeta;
+    myMount(block);
+
+    clientId = block;
+    clientResult = SUCCESS;
+
+    m_state = S_SEEK;
+
+    readCookieOffset[block] = offset;
+
+    post signalDoneTask();      
+    
+    return SUCCESS;
+  }
+
+  /*
+   * Go through all the pages, if it's a free page, count whatever is
+   * available left. Add them all up.
+   */
+  command storage_len_t Read.getSize[ storage_volume_t block ]() {
+    storage_len_t len = 0;
+    uint32_t i;
+    uint32_t j;
+    page_meta_t pageMeta;
+    record_meta_t recordMeta;
+    
+    myMount(block);
+    
+    for(i = 0; i < L_PARTITIONS(block); i++) {
+      call Flash.read(L_RAW_OFFSET(block, i, j),
+                     (uint8_t*) &pageMeta,
+                     sizeof(page_meta_t));
+      if(pageMeta.header != PAGE_AVAILABLE) {
+       len = len + (sizeof(record_data_t) * L_MAX_RECORDS_PER_BLOCK);
+       continue;
+      }
+      for(j = 1; j < L_MAX_RECORDS_PER_BLOCK; j++) {
+       call Flash.read(L_RAW_OFFSET(block, i, j),
+                       (uint8_t*) &recordMeta,
+                       sizeof(record_meta_t));
+       if(recordMeta.status == RECORD_EMPTY) {
+         len = len + ((L_MAX_RECORDS_PER_BLOCK - j) * sizeof(record_meta_t));
+         break;
+       }
+      }
+    }
+    
+    return len;
+  }
+
+  default event void Read.readDone[ storage_volume_t block ](void* buf, storage_len_t len, error_t error) {}
+  default event void Read.seekDone[ storage_volume_t block ](error_t error) {}
+  default event void Write.appendDone[ storage_volume_t block ](void* buf, storage_len_t len, bool recordsLost, error_t error) {}
+
+  default event void Write.eraseDone[ storage_volume_t block ](error_t error) {}
+  default event void Write.syncDone[ storage_volume_t block ](error_t error) {}
+
+  default command bool Circular.get[ uint8_t id ]() { return FALSE; }
+}
diff --git a/tos/chips/pxa27x/p30/Storage_chip.h b/tos/chips/pxa27x/p30/Storage_chip.h
new file mode 100644 (file)
index 0000000..da59ca4
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * 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
+ *
+ * @author Phil Buonadonna
+ * @version $Revision$ $Date$
+ */
+
+#ifndef __STORAGE_CHIP_H__
+#define __STORAGE_CHIP_H__
+
+typedef uint8_t storage_volume_t;
+typedef uint8_t storage_block_t;
+typedef uint8_t storage_log_t;
+typedef uint8_t storage_config_t;
+
+#endif
diff --git a/tos/chips/pxa27x/ssp/HalPXA27xPSPDMAC.nc b/tos/chips/pxa27x/ssp/HalPXA27xPSPDMAC.nc
new file mode 100644 (file)
index 0000000..e57af30
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * 
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+generic configuration HalPXA27xSpiDMAC(uint8_t valSCR,
+                                      uint8_t valDSS,
+                                      bool enableRWOT)
+{
+  provides interface Init;
+  provides interface SpiByte;
+  provides interface SpiPacket[uint8_t instance];
+  provides interface HalPXA27xSSPCntl;
+
+  uses {
+    interface HplPXA27xSSP as SSP;
+    interface HplPXA27xDMAChnl as RxDMA;
+    interface HplPXA27xDMAChnl as TxDMA;
+    interface HplPXA27xDMAInfo as SSPRxDMAInfo;
+    interface HplPXA27xDMAInfo as SSPTxDMAInfo;
+  }
+}
+
+implementation {
+  components new HalPXA27xSpiDMAM(3, valSCR, valDSS, enableRWOT);
+  components HalPXA27xSSPControlP;
+
+  Init = HalPXA27xSpiSSPM;
+  SpiByte = HalPXA27xSpiSSPM;
+  SpiPacket = HalPXA27xSpiSSPM;
+  HalPXA27xSSPCntl = HalPXA27xSSPControlP;
+
+  SSP = HalPXA27xSpiSSPM;
+  SSP = HalPXA27xSSPControlP;
+  RxDMA = HalPXA27xSpiDMAM;
+  TxDMA = HalPXA27xSpiDMAM;
+  SSPRxDMAInfo = HalPXA27xSpiDMAM;
+  SSPTxDMAInfo = HalPXA27xSpiDMAM;
+
+}
diff --git a/tos/chips/pxa27x/ssp/HalPXA27xPSPPioC.nc b/tos/chips/pxa27x/ssp/HalPXA27xPSPPioC.nc
new file mode 100644 (file)
index 0000000..d8d6818
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * 
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+generic configuration HalPXA27xSpiPioC(uint8_t valSCR,
+                                      uint8_t valDSS,
+                                      bool enableRWOT)
+{
+  provides interface Init;
+  provides interface SpiByte;
+  provides interface SpiPacket[uint8_t instance];
+  provides interface HalPXA27xSSPCntl;
+
+  uses interface HplPXA27xSSP as SSP;
+}
+
+implementation {
+  components new HalPXA27xSpiPioM(3, valSCR, valDSS, enableRWOT);
+  components HalPXA27xSSPControlP;
+
+  Init = HalPXA27xSpiPioM;
+  SpiByte = HalPXA27xSpiPioM;
+  SpiPacket = HalPXA27xSpiPioM;
+  HalPXA27xSSPCntl = HalPXA27xSSPControlP;
+
+  SSP = HalPXA27xSpiPioM;
+  SSP = HalPXA27xSSPControlP;
+}
diff --git a/tos/chips/pxa27x/ssp/HalPXA27xSSPDMAC.nc b/tos/chips/pxa27x/ssp/HalPXA27xSSPDMAC.nc
new file mode 100644 (file)
index 0000000..096f47c
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * 
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+generic configuration HalPXA27xSpiDMAC(uint8_t valSCR,
+                                      uint8_t valDSS,
+                                      bool enableRWOT)
+{
+  provides interface Init;
+  provides interface SpiByte;
+  provides interface SpiPacket[uint8_t instance];
+  provides interface HalPXA27xSSPCntl;
+
+  uses {
+    interface HplPXA27xSSP as SSP;
+    interface HplPXA27xDMAChnl as RxDMA;
+    interface HplPXA27xDMAChnl as TxDMA;
+    interface HplPXA27xDMAInfo as SSPRxDMAInfo;
+    interface HplPXA27xDMAInfo as SSPTxDMAInfo;
+  }
+}
+
+implementation {
+  components new HalPXA27xSpiDMAM(1, valSCR, valDSS, enableRWOT);
+  components HalPXA27xSSPControlP;
+
+  Init = HalPXA27xSpiDMAM;
+  SpiByte = HalPXA27xSpiDMAM;
+  SpiPacket = HalPXA27xSpiDMAM;
+  HalPXA27xSSPCntl = HalPXA27xSSPControlP;
+
+  SSP = HalPXA27xSpiDMAM;
+  SSP = HalPXA27xSSPControlP;
+  RxDMA = HalPXA27xSpiDMAM;
+  TxDMA = HalPXA27xSpiDMAM;
+  SSPRxDMAInfo = HalPXA27xSpiDMAM;
+  SSPTxDMAInfo = HalPXA27xSpiDMAM;
+
+}
diff --git a/tos/chips/pxa27x/ssp/HalPXA27xSSPPioC.nc b/tos/chips/pxa27x/ssp/HalPXA27xSSPPioC.nc
new file mode 100644 (file)
index 0000000..0a54cf0
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * 
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+generic configuration HalPXA27xSpiPioC(uint8_t valSCR,
+                                      uint8_t valDSS,
+                                      bool enableRWOT)
+{
+  provides interface Init;
+  provides interface SpiByte;
+  provides interface SpiPacket[uint8_t instance];
+  provides interface HalPXA27xSSPCntl;
+
+  uses interface HplPXA27xSSP as SSP;
+}
+
+implementation {
+  components new HalPXA27xSpiPioM(1, valSCR, valDSS, enableRWOT);
+  components HalPXA27xSSPControlP;
+
+  Init = HalPXA27xSpiPioM;
+  SpiByte = HalPXA27xSpiPioM;
+  SpiPacket = HalPXA27xSpiPioM;
+  HalPXA27xSSPCntl = HalPXA27xSSPControlP;
+
+  SSP = HalPXA27xSpiPioM;
+  SSP = HalPXA27xSSPControlP;
+}
diff --git a/tos/chips/pxa27x/ssp/HalPXA27xSpiDMAC.nc b/tos/chips/pxa27x/ssp/HalPXA27xSpiDMAC.nc
new file mode 100644 (file)
index 0000000..02fc995
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * 
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+generic configuration HalPXA27xSpiDMAC(uint8_t valSCR,
+                                      uint8_t valDSS,
+                                      bool enableRWOT)
+{
+  provides interface Init;
+  provides interface SpiByte;
+  provides interface SpiPacket[uint8_t instance];
+  provides interface HalPXA27xSSPCntl;
+
+  uses {
+    interface HplPXA27xSSP as SSP;
+    interface HplPXA27xDMAChnl as RxDMA;
+    interface HplPXA27xDMAChnl as TxDMA;
+    interface HplPXA27xDMAInfo as SSPRxDMAInfo;
+    interface HplPXA27xDMAInfo as SSPTxDMAInfo;
+  }
+}
+
+implementation {
+  components new HalPXA27xSpiDMAM(0, valSCR, valDSS, enableRWOT);
+  components HalPXA27xSSPControlP;
+
+  Init = HalPXA27xSpiDMAM;
+  SpiByte = HalPXA27xSpiDMAM;
+  SpiPacket = HalPXA27xSpiDMAM;
+  HalPXA27xSSPCntl = HalPXA27xSSPControlP;
+
+  SSP = HalPXA27xSpiDMAM;
+  SSP = HalPXA27xSSPControlP;
+  RxDMA = HalPXA27xSpiDMAM.RxDMA;
+  TxDMA = HalPXA27xSpiDMAM.TxDMA;
+  SSPRxDMAInfo = HalPXA27xSpiDMAM.SSPRxDMAInfo;
+  SSPTxDMAInfo = HalPXA27xSpiDMAM.SSPTxDMAInfo;
+
+}
diff --git a/tos/chips/pxa27x/ssp/HalPXA27xuWireDMAC.nc b/tos/chips/pxa27x/ssp/HalPXA27xuWireDMAC.nc
new file mode 100644 (file)
index 0000000..7789744
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * 
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+generic configuration HalPXA27xSpiDMAC(uint8_t valSCR,
+                                      uint8_t valDSS,
+                                      bool enableRWOT)
+{
+  provides interface Init;
+  provides interface SpiByte;
+  provides interface SpiPacket[uint8_t instance];
+  provides interface HalPXA27xSSPCntl;
+
+  uses {
+    interface HplPXA27xSSP as SSP;
+    interface HplPXA27xDMAChnl as RxDMA;
+    interface HplPXA27xDMAChnl as TxDMA;
+    interface HplPXA27xDMAInfo as SSPRxDMAInfo;
+    interface HplPXA27xDMAInfo as SSPTxDMAInfo;
+  }
+}
+
+implementation {
+  components new HalPXA27xSpiDMAM(2, valSCR, valDSS, enableRWOT);
+  components HalPXA27xSSPControlP;
+
+  Init = HalPXA27xSpiDMAM;
+  SpiByte = HalPXA27xSpiDMAM;
+  SpiPacket = HalPXA27xSpiDMAM;
+  HalPXA27xSSPCntl = HalPXA27xSSPControlP;
+
+  SSP = HalPXA27xSpiDMAM;
+  SSP = HalPXA27xSSPControlP;
+  RxDMA = HalPXA27xSpiDMAM;
+  TxDMA = HalPXA27xSpiDMAM;
+  SSPRxDMAInfo = HalPXA27xSpiDMAM;
+  SSPTxDMAInfo = HalPXA27xSpiDMAM;
+
+}
diff --git a/tos/chips/pxa27x/ssp/HalPXA27xuWirePioC.nc b/tos/chips/pxa27x/ssp/HalPXA27xuWirePioC.nc
new file mode 100644 (file)
index 0000000..ba4947e
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * 
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+generic configuration HalPXA27xSpiPioC(uint8_t valSCR,
+                                      uint8_t valDSS,
+                                      bool enableRWOT)
+{
+  provides interface Init;
+  provides interface SpiByte;
+  provides interface SpiPacket[uint8_t instance];
+  provides interface HalPXA27xSSPCntl;
+
+  uses interface HplPXA27xSSP as SSP;
+}
+
+implementation {
+  components new HalPXA27xSpiPioM(2, valSCR, valDSS, enableRWOT);
+  components HalPXA27xSSPControlP;
+
+  Init = HalPXA27xSpiPioM;
+  SpiByte = HalPXA27xSpiPioM;
+  SpiPacket = HalPXA27xSpiPioM;
+  HalPXA27xSSPCntl = HalPXA27xSSPControlP;
+
+  SSP = HalPXA27xSpiPioM;
+  SSP = HalPXA27xSSPControlP;
+}
diff --git a/tos/chips/pxa27x/timer/HalPXA27xSleep.nc b/tos/chips/pxa27x/timer/HalPXA27xSleep.nc
new file mode 100644 (file)
index 0000000..614b127
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ *
+ * This interfaces provides HAL level sleep functionality for the PXA27x. 
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+
+interface HalPXA27xSleep {
+  /**
+   * Sleep for a given number of milliseconds. This function supports
+   * sleep times up to 65534ms.  Larger sleep durations must
+   * use one of the other methods.
+   *
+   * @param time Sleep duration in milliseconds up to 65534.
+   * 
+   */
+  async command void sleepMillis(uint16_t time);
+
+  /**
+   * Sleep for a given number of seconds up to 62859 sec.
+   * If the function is passed a value greater than 62859, it
+   * will default to the maximum.
+   *
+   * @param time Sleep duration in seconds.
+   *
+   */
+  async command void sleepSeconds(uint32_t time);
+
+  /**
+   * Sleep for a given number of minutes up to 1439 min.
+   * If the function is passed a value greater than 1439, it
+   * will default to the maximum.
+   *
+   * @param time Sleep duration in minutes.
+   */
+  async command void sleepMinutes(uint32_t time);
+
+  /**
+   * Sleep for a given number of hours up to 23 hours
+   * If the function is passed a value greater than 23, it
+   * will default to the maximum.
+   *
+   * @param time Sleep duration in hours
+   */
+  async command void sleepHours(uint16_t time);
+}
diff --git a/tos/chips/pxa27x/timer/HalPXA27xSleepC.nc b/tos/chips/pxa27x/timer/HalPXA27xSleepC.nc
new file mode 100644 (file)
index 0000000..a220656
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+
+configuration HalPXA27xSleepC {
+  provides interface HalPXA27xSleep;
+}
+
+implementation {
+  components HalPXA27xSleepM;
+
+  HalPXA27xSleep = HalPXA27xSleepM;
+
+  components HplPXA27xRTCM, HplPXA27xPowerM;
+  HalPXA27xSleepM.HplPXA27xRTC -> HplPXA27xRTCM;
+  HalPXA27xSleepM.HplPXA27xPower -> HplPXA27xPowerM;
+
+  components LedsC;
+  HalPXA27xSleepM.Leds -> LedsC;
+}
diff --git a/tos/chips/pxa27x/timer/HalPXA27xSleepM.nc b/tos/chips/pxa27x/timer/HalPXA27xSleepM.nc
new file mode 100644 (file)
index 0000000..f65e8d7
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+
+module HalPXA27xSleepM {
+  provides interface HalPXA27xSleep;
+  uses interface HplPXA27xRTC;
+  uses interface HplPXA27xPower;
+
+  uses interface Leds;
+}
+
+implementation {
+
+  void doSleep(uint32_t swRegVal) {
+    int i;
+    call HplPXA27xPower.setPWER(PWER_WERTC);
+    // let it wrap around itself if necessary
+    call HplPXA27xRTC.setSWCR(0);
+    call HplPXA27xRTC.setSWAR1(swRegVal); // minutes
+    call HplPXA27xRTC.setSWAR2(0x00FFFFFF);
+    for(i = 0; i < 10; i++); // spin for a bit
+    call HplPXA27xRTC.setRTSR(RTSR_SWCE);
+    for(i = 0; i < 5000; i++); // spin for a bit
+
+    call HplPXA27xPower.setPWRMode(PWRMODE_M_SLEEP);
+    // this call never returns
+  }
+
+   
+  async command void HalPXA27xSleep.sleepMillis(uint16_t time) {
+    int i;
+    call HplPXA27xPower.setPWER(PWER_WERTC);
+    // let it wrap around itself if necessary
+    call HplPXA27xRTC.setPIAR(time); // implicitly resets RTCPICR
+    for(i = 0; i < 10; i++); // spin for a bit
+    call HplPXA27xRTC.setRTSR(RTSR_PICE);
+    for(i = 0; i < 5000; i++); // spin for a bit
+
+    call HplPXA27xPower.setPWRMode(PWRMODE_M_SLEEP);
+    // this call never returns
+  }
+
+  async command void HalPXA27xSleep.sleepSeconds(uint32_t time) {
+    uint32_t hrs = time / 3600;
+    uint32_t mins = (time / 60) % 60;
+    uint32_t secs = time % 60;
+    uint32_t swReg;
+
+      if (hrs > 23) {
+       hrs = 23;
+       mins = 59;
+       secs = 59;
+      }
+
+    swReg = ((hrs << 19) | (mins << 13) | (secs << 7));
+    doSleep(swReg);
+    return;
+  }
+
+  async command void HalPXA27xSleep.sleepMinutes(uint32_t time) {
+    uint32_t hrs = time / 60;
+    uint32_t mins = time % 60;
+    uint32_t swReg;
+
+    if (hrs > 23) {
+      hrs = 23;
+      mins = 59;
+    }
+    swReg = ((hrs << 19) | (mins << 13));
+
+    doSleep(swReg);
+    return;
+  }
+
+  async command void HalPXA27xSleep.sleepHours(uint16_t time) {
+    uint32_t hrs = time;
+    uint32_t swReg;
+
+    if (hrs > 23) {
+      hrs = 23;
+    }
+    swReg = (hrs << 19);
+
+    doSleep(swReg);
+    return;
+  }
+}
diff --git a/tos/chips/pxa27x/timer/HalPXA27xWatchdog.nc b/tos/chips/pxa27x/timer/HalPXA27xWatchdog.nc
new file mode 100644 (file)
index 0000000..c642bff
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ *
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+interface HalPXA27xWatchdog {
+
+  /** 
+   * Enable the watchdog resource with the given timeout interval. 
+   * This function may be called multiple times to reset the timeout
+   * interval. However, the watchdog function itself is sticky and
+   * will remain enabled until system reset.
+   *
+   * @param interval The timeout interval in untis of 3.25MHZ clock cycle
+   * ticks.
+   *
+   */
+  async command void enable(uint32_t interval);
+
+  /**
+   * Tickle/reset the watchdog counter. This function must be 
+   * called on a regular basis to prevent the watchdog from resetting the
+   * system.
+   *
+   */
+  async command void tickle();
+}
diff --git a/tos/chips/pxa27x/timer/HalPXA27xWatchdogC.nc b/tos/chips/pxa27x/timer/HalPXA27xWatchdogC.nc
new file mode 100644 (file)
index 0000000..dca0851
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ *
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+module HalPXA27xWatchdogC {
+  provides interface HalPXA27xWatchdog;
+}
+
+implementation {
+  components HplPXA27xOSTimerC;
+  components HalPXA27xWatchdogM;
+
+  HalPXA27xWatchdog = HalPXA27xWatchdogM;
+
+  HalPXA27xWatchdogM.HplPXA27xOSTimerWatchdog -> HplPXA27xOSTimerC.OSTWDCntl;
+  HalPXA27xWatchdogM.HplPXA27xOSTimer -> HplPXA27xOSTimerC.OST0M3;
+
+}
diff --git a/tos/chips/pxa27x/timer/HalPXA27xWatchdogM.nc b/tos/chips/pxa27x/timer/HalPXA27xWatchdogM.nc
new file mode 100644 (file)
index 0000000..ec5fa62
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ *
+ *
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ */
+
+module HalPXA27xWatchdogM {
+  provides interface HalPXA27xWatchdog;
+  uses interface HplPXA27xOSTimerWatchdog;
+  uses interface HplPXA27xOSTimer;
+}
+
+implementation {
+  uint32_t gResetInterval;
+
+  async command void HalPXA27xWatchdog.enable(uint32_t interval) {
+    uint32_t curMatch;
+    atomic {
+      gResetInterval = interval;
+      curMatch = call HplPXA27xOSTimer.getOSCR();
+      curMatch = (curMatch + gResetInterval) % 0xFFFFFFFF;
+      call HplPXA27xOSTimer.setOSMR(curMatch);
+      call HplPXA27xOSTimerWatchdog.enableWatchdog();
+    }
+  }
+
+  async command void HalPXA27xWatchdog.tickle() {
+    uint32_t curMatch;
+    atomic {
+      curMatch = call HplPXA27xOSTimer.getOSCR();
+      curMatch = (curMatch + gResetInterval) % 0xFFFFFFFF;
+      call HplPXA27xOSTimer.setOSMR(curMatch);
+    }
+  }
+
+  // This won't ever get called. Rather, the system will reset.
+  async event void HplPXA27xOSTimer.fired() {}
+
+}
diff --git a/tos/chips/pxa27x/timer/HplPXA27xPower.nc b/tos/chips/pxa27x/timer/HplPXA27xPower.nc
new file mode 100644 (file)
index 0000000..3bb5b15
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+
+/*
+ * Code to access some power management registers
+ */
+
+interface HplPXA27xPower {
+  async command void setPWER(uint32_t val);
+  async command void setPWRMode(uint8_t val);
+}
diff --git a/tos/chips/pxa27x/timer/HplPXA27xPowerM.nc b/tos/chips/pxa27x/timer/HplPXA27xPowerM.nc
new file mode 100644 (file)
index 0000000..daa217c
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+
+module HplPXA27xPowerM {
+  provides interface HplPXA27xPower;
+}
+
+implementation {
+  async command void HplPXA27xPower.setPWER(uint32_t val) {
+    PWER = val;
+  }
+
+  async command void HplPXA27xPower.setPWRMode(uint8_t val) {
+    val = val & 0xF;
+    asm volatile (
+                 "mcr p14,0,%0,c7,c0,0"
+                 : 
+                 : "r" (val)
+                 );
+    __nesc_enable_interrupt();
+    __nesc_disable_interrupt();
+  }
+}
diff --git a/tos/chips/pxa27x/timer/HplPXA27xRTC.nc b/tos/chips/pxa27x/timer/HplPXA27xRTC.nc
new file mode 100644 (file)
index 0000000..14daeea
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+
+/*
+ * Code to access some RTC registers
+ */
+
+interface HplPXA27xRTC {
+  async command void setRTCPICR(uint16_t val);
+  async command uint16_t getRTCPICR();
+  async command void setPIAR(uint16_t val);
+  async command uint16_t getPIAR();
+  async command void setRTSR(uint16_t val);
+  async command void setSWAR1(uint32_t val);
+  async command void setSWAR2(uint32_t val);
+  async command void setSWCR(uint32_t val);
+}
diff --git a/tos/chips/pxa27x/timer/HplPXA27xRTCM.nc b/tos/chips/pxa27x/timer/HplPXA27xRTCM.nc
new file mode 100644 (file)
index 0000000..8e873e7
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+
+module HplPXA27xRTCM {
+  provides interface HplPXA27xRTC;
+}
+
+implementation {
+  async command void HplPXA27xRTC.setRTCPICR(uint16_t val) { RTCPICR = val; }
+  async command uint16_t HplPXA27xRTC.getRTCPICR() { return RTCPICR; }
+  async command void HplPXA27xRTC.setPIAR(uint16_t val) { PIAR = val; }
+  async command uint16_t HplPXA27xRTC.getPIAR() { return PIAR; }
+  async command void HplPXA27xRTC.setRTSR(uint16_t val) { RTSR = val; }
+  async command void HplPXA27xRTC.setSWAR1(uint32_t val) { SWAR1 = val; }
+  async command void HplPXA27xRTC.setSWAR2(uint32_t val) { SWAR2 = val; }
+  async command void HplPXA27xRTC.setSWCR(uint32_t val) { SWCR = val; }
+}
diff --git a/tos/chips/pxa27x/uart/HalPXA27xSerialCntl.nc b/tos/chips/pxa27x/uart/HalPXA27xSerialCntl.nc
new file mode 100644 (file)
index 0000000..9ba18fa
--- /dev/null
@@ -0,0 +1,65 @@
+/* $Id$ */\r
+/*\r
+ * Copyright (c) 2005 Arch Rock Corporation \r
+ * All rights reserved. \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *     Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ *     Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *  \r
+ *   Neither the name of the Arch Rock Corporation nor the names of its\r
+ * contributors may be used to endorse or promote products derived from\r
+ * this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ARCHED\r
+ * ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\r
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\r
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\r
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ */\r
+\r
+/**\r
+ * @author Phil Buonadonna\r
+ */\r
+\r
+#include "pxa27x_serial.h"\r
+\r
+interface HalPXA27xSerialCntl\r
+{\r
+  /** \r
+   * Modify runtime port parameters\r
+   *\r
+   * @param baudrate The integer value of baudrate\r
+   * @param databits The Number of data bits\r
+   * @param partiy Values of EVEN,ODD or NONE\r
+   * @param stopbits Values of 1 or 2\r
+   * @param flow_cntl TRUE to enable hardware flow control\r
+   *\r
+   * @return SUCCESS if parameters successfully applied. FAIL otherwise\r
+   */\r
+  async command error_t configPort(uint32_t baudrate, \r
+                                   uint8_t databits, \r
+                                   uart_parity_t parity, \r
+                                   uint8_t stopbits, \r
+                                   bool flow_cntl);\r
+    \r
+  /**\r
+   * Flush the port FIFOs\r
+   *\r
+   * @return SUCCESS if flushed, FAIL otherwise.\r
+   */\r
+  async command error_t flushPort();\r
+\r
+}\r
+\r
diff --git a/tos/chips/pxa27x/uart/HalPXA27xSerialPacket.nc b/tos/chips/pxa27x/uart/HalPXA27xSerialPacket.nc
new file mode 100644 (file)
index 0000000..3ea9874
--- /dev/null
@@ -0,0 +1,92 @@
+/* $Id$ */\r
+/*\r
+ * Copyright (c) 2005 Arch Rock Corporation \r
+ * All rights reserved. \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *     Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ *     Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *  \r
+ *   Neither the name of the Arch Rock Corporation nor the names of its\r
+ * contributors may be used to endorse or promote products derived from\r
+ * this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ARCHED\r
+ * ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\r
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\r
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\r
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ */\r
+\r
+/**\r
+ * @author Phil Buonadonna\r
+ */\r
+\r
+#include "pxa27x_serial.h"\r
+\r
+interface HalPXA27xSerialPacket\r
+{\r
+  /**\r
+   * Begin transmission of a UART stream. If SUCCESS is returned,\r
+   * <code>sendDone</code> will be signalled when transmission is\r
+   * complete.\r
+   *\r
+   * @param buf Buffer for bytes to send.\r
+   * @param len Number of bytes to send.\r
+   * @return SUCCESS if request was accepted, FAIL otherwise.\r
+   */\r
+  async command error_t send(uint8_t *buf, uint16_t len);\r
+  \r
+  /**\r
+   * Signal completion of sending a stream.\r
+   *\r
+   * @param buf Bytes sent.\r
+   * @param len Number of bytes sent.\r
+   * @param status UART error status.\r
+   *\r
+   * @return buf A pointer to a new buffer of equal length\r
+   * as in the original <code>send</code> call that is to be transmitted (chained\r
+   * send). Set to NULL to end further transmissions.\r
+   */\r
+  async event uint8_t *sendDone(uint8_t *buf, uint16_t len, uart_status_t status);\r
+\r
+  /**\r
+   * Begin reception of a UART stream. If SUCCESS is returned,\r
+   * <code>receiveDone</code> will be signalled when reception is\r
+   * complete.\r
+   *\r
+   * @param buf Buffer for received bytes.\r
+   * @param len Number of bytes to receive.\r
+   * @param timeout Timeout, in milliseconds, for receive operation\r
+   *\r
+   * @return SUCCESS if request was accepted, FAIL otherwise.\r
+   */\r
+  async command error_t receive(uint8_t *buf, uint16_t len, uint16_t timeout);\r
+\r
+   /**\r
+   * Signal completion of receiving a stream.\r
+   *\r
+   * @param buf Buffer for bytes received.\r
+   * @param len Number of bytes received.\r
+   * @param status UART error status\r
+   *\r
+   * @return buf A pointer to a new buffer of equal or greater length \r
+   * as in the original <code>receive</code> call in which it intiate a\r
+   * new packet reception (chained receive). Set to NULL to terminate further\r
+   * reception. \r
+   */\r
+  async event uint8_t *receiveDone(uint8_t *buf, uint16_t len, uart_status_t status);\r
+  \r
+}\r
+\r
diff --git a/tos/chips/pxa27x/uart/HplPXA27xBTUARTC.nc b/tos/chips/pxa27x/uart/HplPXA27xBTUARTC.nc
new file mode 100644 (file)
index 0000000..5f1d0d4
--- /dev/null
@@ -0,0 +1,52 @@
+/* $Id$ */\r
+/*\r
+ * Copyright (c) 2005 Arch Rock Corporation \r
+ * All rights reserved. \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *     Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ *     Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *  \r
+ *   Neither the name of the Arch Rock Corporation nor the names of its\r
+ * contributors may be used to endorse or promote products derived from\r
+ * this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ARCHED\r
+ * ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\r
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\r
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\r
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ */\r
+/**\r
+ *\r
+ * @author Phil Buonadonna\r
+ */\r
+\r
+configuration HplPXA27xBTUARTC \r
+{\r
+  provides interface Init;\r
+  provides interface HplPXA27xUART as BTUART;\r
+}\r
+\r
+implementation \r
+{\r
+  components new HplPXA27xUARTP((uint32_t)&BTRBR);\r
+  components HplPXA27xInterruptM;\r
+\r
+  Init = HplPXA27xUARTP;\r
+  BTUART = HplPXA27xUARTP.UART;\r
+\r
+  HplPXA27xUARTP.UARTIrq -> HplPXA27xInterruptM.PXA27xIrq[PPID_BTUART];\r
+\r
+}\r
diff --git a/tos/chips/pxa27x/uart/HplPXA27xFFUARTC.nc b/tos/chips/pxa27x/uart/HplPXA27xFFUARTC.nc
new file mode 100644 (file)
index 0000000..f55947c
--- /dev/null
@@ -0,0 +1,52 @@
+/* $Id$ */\r
+/*\r
+ * Copyright (c) 2005 Arch Rock Corporation \r
+ * All rights reserved. \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *     Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ *     Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *  \r
+ *   Neither the name of the Arch Rock Corporation nor the names of its\r
+ * contributors may be used to endorse or promote products derived from\r
+ * this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ARCHED\r
+ * ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\r
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\r
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\r
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ */\r
+/**\r
+ *\r
+ * @author Phil Buonadonna\r
+ */\r
+\r
+configuration HplPXA27xFFUARTC \r
+{\r
+  provides interface Init;\r
+  provides interface HplPXA27xUART as FFUART;\r
+}\r
+\r
+implementation \r
+{\r
+  components new HplPXA27xUARTP((uint32_t)&FFRBR);\r
+  components HplPXA27xInterruptM;\r
+\r
+  Init = HplPXA27xUARTP;\r
+  FFUART = HplPXA27xUARTP.UART;\r
+\r
+  HplPXA27xUARTP.UARTIrq -> HplPXA27xInterruptM.PXA27xIrq[PPID_FFUART];\r
+\r
+}\r
diff --git a/tos/chips/pxa27x/uart/HplPXA27xUARTP.nc b/tos/chips/pxa27x/uart/HplPXA27xUARTP.nc
new file mode 100644 (file)
index 0000000..0ecd79d
--- /dev/null
@@ -0,0 +1,143 @@
+/* $Id$ */\r
+/*\r
+ * Copyright (c) 2005 Arched Rock Corporation \r
+ * All rights reserved. \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *     Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ *     Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *  \r
+ *   Neither the name of the Arched Rock Corporation nor the names of its\r
+ * contributors may be used to endorse or promote products derived from\r
+ * this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ARCHED\r
+ * ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\r
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\r
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\r
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ */\r
+/**\r
+ * Provides low-level initialization, 1st level interrupt dispatch and register\r
+ * access for the different uarts.  It is a generic that's bound to \r
+ * the particular UART upon creation.\r
+ *\r
+ * @param baseaddr. The base address of the associated uart. One of \r
+ * &FFRBR, &BTRBR or &STRBR.\r
+ * This component automatically handles setting of the DLAB bit for\r
+ * divisor register access (DLL and DLH) \r
+ *\r
+ * @author Phil Buonadonna\r
+ */\r
+\r
+#include "PXA27X_UARTREG.h"\r
+\r
+generic module HplPXA27xUARTP(uint32_t base_addr)\r
+{\r
+  provides interface Init;\r
+  provides interface HplPXA27xUART as UART;\r
+  uses interface HplPXA27xInterrupt as UARTIrq;\r
+}\r
+\r
+implementation\r
+{\r
+  bool m_fInit = FALSE;\r
+\r
+  command error_t Init.init() {\r
+    bool isInited;\r
+\r
+    atomic {\r
+      isInited = m_fInit;\r
+      m_fInit = TRUE;\r
+    }\r
+\r
+    if (!isInited) {\r
+      switch (base_addr) {\r
+      case (0x40100000):\r
+       CKEN |= CKEN6_FFUART;\r
+       break;\r
+      case (0x40200000):\r
+       CKEN |= CKEN7_BTUART;\r
+       break;\r
+      case (0x40700000):\r
+       CKEN |= CKEN5_STUART;\r
+       break;\r
+      default:\r
+       break;\r
+      }\r
+      call UARTIrq.allocate();\r
+      call UARTIrq.enable();\r
+      UARTLCR(base_addr) |= LCR_DLAB;\r
+      UARTDLL(base_addr) = 0x04;\r
+      UARTDLH(base_addr) = 0x00;\r
+      UARTLCR(base_addr) &= ~LCR_DLAB;\r
+    }\r
+\r
+    return SUCCESS;\r
+  }\r
+\r
+  async command uint32_t UART.getRBR() { return UARTRBR(base_addr); }\r
+  async command void UART.setTHR(uint32_t val) { UARTTHR(base_addr) = val; }\r
+  async command void UART.setDLL(uint32_t val) { \r
+    UARTLCR(base_addr) |= LCR_DLAB;\r
+    UARTDLL(base_addr) = val; \r
+    UARTLCR(base_addr) &= ~LCR_DLAB;\r
+  }\r
+  async command uint32_t UART.getDLL() { \r
+    uint32_t val;\r
+    UARTLCR(base_addr) |= LCR_DLAB;\r
+    val = UARTDLL(base_addr); \r
+    UARTLCR(base_addr) &= ~LCR_DLAB;\r
+    return val;\r
+  }\r
+  async command void UART.setDLH(uint32_t val) { \r
+    UARTLCR(base_addr) |= LCR_DLAB;\r
+    UARTDLH(base_addr) = val; \r
+    UARTLCR(base_addr) &= ~LCR_DLAB;\r
+  }\r
+  async command uint32_t UART.getDLH() { \r
+    uint32_t val;\r
+    UARTLCR(base_addr) |= LCR_DLAB;\r
+    val = UARTDLH(base_addr);\r
+    UARTLCR(base_addr) &= ~LCR_DLAB;\r
+    return val;\r
+  }\r
+  async command void UART.setIER(uint32_t val) { UARTIER(base_addr) = val; }\r
+  async command uint32_t UART.getIER() { return UARTIER(base_addr); }\r
+  async command uint32_t UART.getIIR() { return UARTIIR(base_addr); }\r
+  async command void UART.setFCR(uint32_t val) { UARTFCR(base_addr) = val; }\r
+  async command void UART.setLCR(uint32_t val) { UARTLCR(base_addr) = val; }\r
+  async command uint32_t UART.getLCR() { return UARTLCR(base_addr); }\r
+  async command void UART.setMCR(uint32_t val) { UARTMCR(base_addr) = val; }\r
+  async command uint32_t UART.getMCR() { return UARTMCR(base_addr); }\r
+  async command uint32_t UART.getLSR() { return UARTLSR(base_addr); }\r
+  async command uint32_t UART.getMSR() { return UARTMSR(base_addr); }\r
+  async command void UART.setSPR(uint32_t val) { UARTSPR(base_addr) = val; }\r
+  async command uint32_t UART.getSPR() { return UARTSPR(base_addr); }\r
+  async command void UART.setISR(uint32_t val) { UARTISR(base_addr) = val; }\r
+  async command uint32_t UART.getISR() { return UARTISR(base_addr); }\r
+  async command void UART.setFOR(uint32_t val) { UARTFOR(base_addr) = val; }\r
+  async command uint32_t UART.getFOR() { return UARTFOR(base_addr); }\r
+  async command void UART.setABR(uint32_t val) { UARTABR(base_addr) = val; }\r
+  async command uint32_t UART.getABR() { return UARTABR(base_addr); }\r
+  async command uint32_t UART.getACR() { return UARTACR(base_addr); }\r
+\r
+  async event void UARTIrq.fired () {\r
+\r
+    signal UART.interruptUART();\r
+  }\r
+\r
+  default async event void UART.interruptUART() { return; }\r
+  \r
+}\r
diff --git a/tos/chips/pxa27x/uart/PXA27X_UARTREG.h b/tos/chips/pxa27x/uart/PXA27X_UARTREG.h
new file mode 100644 (file)
index 0000000..5dea0f1
--- /dev/null
@@ -0,0 +1,58 @@
+/* $Id$ */\r
+/*\r
+ * Copyright (c) 2005 Arch Rock Corporation \r
+ * All rights reserved. \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *     Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ *     Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *  \r
+ *   Neither the name of the Arched Rock Corporation nor the names of its\r
+ * contributors may be used to endorse or promote products derived from\r
+ * this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ARCHED\r
+ * ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\r
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\r
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\r
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ */\r
+\r
+/* \r
+ * Helper macros to make programming the HplPXA27xUARTP component easier\r
+ */\r
+\r
+#ifndef _PXA27X_UARTREG_H\r
+#define _PXA27X_UARTREG_H\r
+\r
+#define UARTRBR(_base) _PXAREG_OFFSET(_base,0)\r
+#define UARTTHR(_base) _PXAREG_OFFSET(_base,0)\r
+#define UARTIER(_base) _PXAREG_OFFSET(_base,0x04)\r
+#define UARTIIR(_base) _PXAREG_OFFSET(_base,0x08)\r
+#define UARTFCR(_base) _PXAREG_OFFSET(_base,0x08)\r
+#define UARTLCR(_base) _PXAREG_OFFSET(_base,0x0C)\r
+#define UARTMCR(_base) _PXAREG_OFFSET(_base,0x10)\r
+#define UARTLSR(_base) _PXAREG_OFFSET(_base,0x14)\r
+#define UARTMSR(_base) _PXAREG_OFFSET(_base,0x18)\r
+#define UARTSPR(_base) _PXAREG_OFFSET(_base,0x1C)\r
+#define UARTISR(_base) _PXAREG_OFFSET(_base,0x20)\r
+#define UARTFOR(_base) _PXAREG_OFFSET(_base,0x24)\r
+#define UARTABR(_base) _PXAREG_OFFSET(_base,0x28)\r
+#define UARTACR(_base) _PXAREG_OFFSET(_base,0x2C)\r
+\r
+#define UARTDLL(_base) _PXAREG_OFFSET(_base,0)\r
+#define UARTDLH(_base) _PXAREG_OFFSET(_base,0x04)\r
+\r
+#endif /* _PXA27X_UARTREG_H */\r
+\r
diff --git a/tos/chips/pxa27x/uart/pxa27x_serial.h b/tos/chips/pxa27x/uart/pxa27x_serial.h
new file mode 100644 (file)
index 0000000..b7e03f2
--- /dev/null
@@ -0,0 +1,44 @@
+/* $Id$ */\r
+/*\r
+ * Copyright (c) 2005 Arched Rock Corporation \r
+ * All rights reserved. \r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *     Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ *     Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *  \r
+ *   Neither the name of the Arched Rock Corporation nor the names of its\r
+ * contributors may be used to endorse or promote products derived from\r
+ * this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ARCHED\r
+ * ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\r
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\r
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\r
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
+ * DAMAGE.\r
+ */\r
+\r
+\r
+#ifndef _pxa27x_serial_h\r
+#define _pxa27x_serial_h\r
+\r
+typedef uint8_t uart_status_t; // ??? if this is supposed to be a uint8_t\r
+\r
+typedef enum {\r
+  EVEN,\r
+  ODD,\r
+  NONE\r
+} uart_parity_t;\r
+\r
+#endif /* _pxa27x_serial_h */\r
diff --git a/tos/chips/tda5250/HplTda5250DataC.nc b/tos/chips/tda5250/HplTda5250DataC.nc
new file mode 100644 (file)
index 0000000..87d2744
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+* Copyright (c) 2004, Technische Universitat Berlin
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+*   notice, this list of conditions and the following disclaimer in the
+*   documentation and/or other materials provided with the distribution.
+* - Neither the name of the Technische Universitat Berlin nor the names
+*   of its contributors may be used to endorse or promote products derived
+*   from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+* - Revision -------------------------------------------------------------
+* $Revision$
+* $Date$
+* ========================================================================
+*/
+
+
+/**
+ * Controlling the TDA5250 at the HPL layer.
+ * 
+ * @author Kevin Klues (klues@tkn.tu-berlin.de)
+ */
+configuration HplTda5250DataC {
+  provides {
+    interface Init;
+    interface HplTda5250Data;
+               interface HplTda5250DataControl;
+    interface ResourceRequested;
+    interface Resource as Resource;
+  }
+}
+implementation {
+
+  components HplTda5250DataP,
+      Tda5250RadioIOC,
+                       HplTda5250DataIOC;
+
+  Init = HplTda5250DataP;
+  Resource = HplTda5250DataP.Resource;
+  ResourceRequested = HplTda5250DataP.ResourceRequested;
+  HplTda5250Data = HplTda5250DataP;
+  HplTda5250DataControl = HplTda5250DataP;
+
+  HplTda5250DataP.DATA -> Tda5250RadioIOC.Tda5250RadioDATA;
+       HplTda5250DataP.Uart -> HplTda5250DataIOC.UartStream;
+  HplTda5250DataP.UartDataControl -> HplTda5250DataIOC.UartDataControl;
+       HplTda5250DataP.UartResource -> HplTda5250DataIOC.Resource;
+       HplTda5250DataP.UartResourceRequested -> HplTda5250DataIOC.ResourceRequested;
+
+}
diff --git a/tos/chips/tda5250/HplTda5250DataControl.nc b/tos/chips/tda5250/HplTda5250DataControl.nc
new file mode 100644 (file)
index 0000000..fb4a82d
--- /dev/null
@@ -0,0 +1,29 @@
+ /**
+ * Interface for controlling the data interface of the TDA5250 Radio.
+ * This interface lets you switch between Tx and Rx.
+ * In conjunction to this the HplTda5250Data interface 
+ * is used for the actual receiving and sending of data.
+ *
+ * @see HplTda5250Data
+ * @author Philipp Huppertz (huppertz@tkn.tu-berlin.de)
+ */
+interface HplTda5250DataControl {  
+
+/**
+   * Sets the radio to transmit. 
+   * 
+   * @return SUCCESS on success
+   *         FAIL otherwise.
+       */
+  async command error_t setToTx();
+
+
+  /**
+   * Sets the radio to receive.
+   *
+   * @return SUCCESS on success
+   *         FAIL otherwise.
+       */
+  async command error_t setToRx();
+  
+}
diff --git a/tos/interfaces/AdcConfigure.nc b/tos/interfaces/AdcConfigure.nc
new file mode 100644 (file)
index 0000000..a9713eb
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+/** 
+ * This interface is intended to be provided by an ADC client and used by the
+ * ADC subsystem to retrieve the client's ADC configuration. 
+ * 
+ * @author Jan Hauer 
+ * @see  Please refer to TEP 101 for more information about this interface and
+ * its intended use.
+ */
+
+interface AdcConfigure<adc_config_t> 
+{
+
+  /** 
+   * Returns the configuration of an ADC client.  <code>adc_config_t</code> is
+   * a hardware specific data type that contains all information necessary to
+   * configure the respective ADC hardware for the client. A client MUST always
+   * return the same configuration and, if configuration data is passed as a
+   * pointer, the ADC subsystem (HIL component) MUST NOT reference it after the
+   * return of this command.
+   *  
+   * @return chip specific configuration.
+   */
+  async command adc_config_t getConfiguration(); 
+}
diff --git a/tos/interfaces/ResourceQueue.nc b/tos/interfaces/ResourceQueue.nc
new file mode 100644 (file)
index 0000000..3b135b8
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON 
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+
+/**
+ *  A queue interface for managing client ids when performing resource 
+ *  arbitration. A single slot in the queue is guaranteed to each resource
+ *  client, with the actual queing policy determined by the implementation
+ *  of the interface.
+ *
+ *  @author Kevin Klues <klueska@cs.wustl.edu>
+ *  @date   $Date$
+ */
+#include "Resource.h"
+   
+interface ResourceQueue {
+       
+  /**
+   * Check to see if the queue is empty.
+   *
+   * @return TRUE  if the queue is empty. <br>
+   *         FALSE if there is at least one entry in the queue
+   */
+  async command bool isEmpty();
+  
+  /**
+   * Check to see if a given cleint id has already been enqueued
+   * and is waiting to be processed.
+   *
+   * @return TRUE  if the client id is in the queue. <br>
+   *         FALSE if it does not
+   */
+  async command bool isEnqueued(resource_client_id_t id);
+  
+  /**
+   * Retreive the cleint id of the next resource in the queue. 
+   * If the queue is empty, the return value is undefined.
+   *
+   * @return The cleint id at the head of the queue.
+   */
+  async command resource_client_id_t dequeue();
+
+  /**
+   * Enqueue a cleint id
+   *
+   * @param cleintId - the cleint id to enqueue
+   * @return SUCCESS if the client id was enqueued successfully <br>
+   *         EBUSY   if it has already been enqueued.
+   */
+  async command error_t enqueue(resource_client_id_t id);
+}
diff --git a/tos/interfaces/ResourceRequested.nc b/tos/interfaces/ResourceRequested.nc
new file mode 100644 (file)
index 0000000..771a38d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON 
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/**
+ * Please refer to TEP 108 for more information about this interface and its
+ * intended use.<br><br>
+ *
+ * The ResourceRequested interface can be used in conjunction with the 
+ * Resource interface in order to receive events based on other users
+ * requests.
+ * 
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+
+interface ResourceRequested {
+  /**
+   * This event is signalled whenever the user of this interface
+   * currently has control of the resource, and another user requests
+   * it through the Resource.request() command. You may want to
+   * consider releasing a resource based on this event
+  */
+  async event void requested();
+
+  /**
+  * This event is signalled whenever the user of this interface
+  * currently has control of the resource, and another user requests
+  * it through the Resource.immediateRequest() command. You may
+  * want to consider releasing a resource based on this event
+  */
+  async event void immediateRequested();
+}
diff --git a/tos/interfaces/UartByte.nc b/tos/interfaces/UartByte.nc
new file mode 100644 (file)
index 0000000..e534c23
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+interface UartByte {
+
+  /**
+   * Send a single uart byte. The call blocks until it is ready to
+   * accept another byte for sending.
+   *
+   * @param byte The byte to send.
+   * @return SUCCESS if byte was sent, FAIL otherwise.
+   */
+  async command error_t send( uint8_t byte );
+
+  /**
+   * Receive a single uart byte. The call blocks until a byte is
+   * received.
+   *
+   * @param byte Where to place received byte.
+   * @param timeout How long in byte times to wait.
+   * @return SUCCESS if a byte was received, FAIL if timed out.
+   */
+  async command error_t receive( uint8_t* byte, uint8_t timeout );
+
+}
diff --git a/tos/interfaces/UartStream.nc b/tos/interfaces/UartStream.nc
new file mode 100644 (file)
index 0000000..6f4e320
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+interface UartStream {
+
+  /**
+   * Begin transmission of a UART stream. If SUCCESS is returned,
+   * <code>sendDone</code> will be signalled when transmission is
+   * complete.
+   *
+   * @param buf Buffer for bytes to send.
+   * @param len Number of bytes to send.
+   * @return SUCCESS if request was accepted, FAIL otherwise.
+   */
+  async command error_t send( uint8_t* buf, uint16_t len );
+
+  /**
+   * Signal completion of sending a stream.
+   *
+   * @param buf Bytes sent.
+   * @param len Number of bytes sent.
+   * @param error SUCCESS if the transmission was successful, FAIL otherwise.
+   */
+  async event void sendDone( uint8_t* buf, uint16_t len, error_t error );
+
+  /**
+   * Enable the receive byte interrupt. The <code>receive</code> event
+   * is signalled each time a byte is received.
+   *
+   * @return SUCCESS if interrupt was enabled, FAIL otherwise.
+   */
+  async command error_t enableReceiveInterrupt();
+
+  /**
+   * Disable the receive byte interrupt.
+   *
+   * @return SUCCESS if interrupt was disabled, FAIL otherwise.
+   */
+  async command error_t disableReceiveInterrupt();
+
+  /**
+   * Signals the receipt of a byte.
+   *
+   * @param byte The byte received.
+   */
+  async event void receivedByte( uint8_t byte );
+
+  /**
+   * Begin reception of a UART stream. If SUCCESS is returned,
+   * <code>receiveDone</code> will be signalled when reception is
+   * complete.
+   *
+   * @param buf Buffer for received bytes.
+   * @param len Number of bytes to receive.
+   * @return SUCCESS if request was accepted, FAIL otherwise.
+   */
+  async command error_t receive( uint8_t* buf, uint16_t len );
+
+  /**
+   * Signal completion of receiving a stream.
+   *
+   * @param buf Buffer for bytes received.
+   * @param len Number of bytes received.
+   * @param error SUCCESS if the reception was successful, FAIL otherwise.
+   */
+  async event void receiveDone( uint8_t* buf, uint16_t len, error_t error );
+
+}
diff --git a/tos/lib/byte_radio/PacketAck.h b/tos/lib/byte_radio/PacketAck.h
new file mode 100644 (file)
index 0000000..fd5dd5f
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES {} LOSS OF USE, DATA,
+ * OR PROFITS {} OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Description ---------------------------------------------------------
+ * provide constants for packet ack interface
+ * - Author --------------------------------------------------------------
+ * @author: Andreas Koepke (koepke@tkn.tu-berlin.de)
+ * ========================================================================
+ */
+
+#ifndef PACKET_ACK_H
+#define PACKET_ACK_H
+/*
+#define NO_ACK_REQUESTED  1
+#define WAS_ACKED  2 
+#define ACK_REQUESTED 128
+*/
+typedef enum {
+    NO_ACK_REQUESTED = 1,
+    WAS_ACKED,
+    WAS_NOT_ACKED,
+    ACK_REQUESTED = 128U
+} packet_ack_t;
+
+
+#endif
diff --git a/tos/lib/net/CollectionDebug.nc b/tos/lib/net/CollectionDebug.nc
new file mode 100644 (file)
index 0000000..23d5fcb
--- /dev/null
@@ -0,0 +1,69 @@
+/* $Id$*/
+/*
+ * "Copyright (c) 2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/** 
+ *  The CollectionDebug is an interface for sending debugging events to
+ *  a logging infrastructure. An implementer can choose to send the event
+ *  information to different destinations. Primary examples can include:
+ *  <ul>
+ *    <li> logging to the UART, in case of a testbed of network-connected
+ *         nodes;
+ *    <li> logging to flash, if the logs are to be retrieved later
+ *    <li> logging to the standard output, in the case of TOSSIM.
+ *  </ul>
+ *  
+ *  The interface does not specify in what format the log is to be produced,
+ *  or if other information, like timestamps, should be added, and this is
+ *  up to the implementer.
+ * 
+ *  Some commands are generic, like Event, EventSimple, and EventDbg, while others
+ *  are for more specific events related to collection, like EventRoute and EventMsg.
+ *
+ * @author Rodrigo Fonseca
+ * @author Kyle Jamieson
+ * @date   $Date$
+ */
+
+interface CollectionDebug {
+    /* Log the occurrence of an event of type type */
+    command error_t logEvent(uint8_t type);
+
+    /* Log the occurrence of an event and a single parameter */
+    command error_t logEventSimple(uint8_t type, uint16_t arg);
+
+    /* Log the occurrence of an event and 3 16bit parameters */
+    command error_t logEventDbg(uint8_t type, uint16_t arg1, uint16_t arg2, uint16_t arg3);
+
+    /* Log the occurrence of an event related to forwarding a message.
+     * This is intended to allow following the same message as it goes from one
+     * hop to the next 
+     */
+    command error_t logEventMsg(uint8_t type, uint16_t msg, am_addr_t origin, am_addr_t node);
+
+    /* Log the occurrence of an event related to a route update message, 
+     * such as a node receiving a route, updating its own route information,
+     * or looking at a particular entry in its routing table.
+     */
+    command error_t logEventRoute(uint8_t type, am_addr_t parent, uint8_t hopcount, uint16_t metric);
+}
diff --git a/tos/lib/net/CollectionDebugMsg.h b/tos/lib/net/CollectionDebugMsg.h
new file mode 100644 (file)
index 0000000..e666979
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef _COLLECTION_UART_MSG
+#define _COLLECTION_UART_MSG
+
+#include "AM.h"
+
+//Comment format ->   :meaning:args
+enum {
+    NET_C_DEBUG_STARTED = 0xDE,
+
+    NET_C_FE_MSG_POOL_EMPTY = 0x10,    //::no args
+    NET_C_FE_SEND_QUEUE_FULL = 0x11,   //::no args
+    NET_C_FE_NO_ROUTE = 0x12,          //::no args
+    NET_C_FE_SUBSEND_OFF = 0x13,
+    NET_C_FE_SUBSEND_BUSY = 0x14,
+    NET_C_FE_BAD_SENDDONE = 0x15,
+    NET_C_FE_QENTRY_POOL_EMPTY = 0x16,
+    NET_C_FE_SUBSEND_SIZE = 0x17,
+    NET_C_FE_LOOP_DETECTED = 0x18,
+    NET_C_FE_SEND_BUSY = 0x19,
+
+    NET_C_FE_SENDQUEUE_EMPTY = 0x50,
+    NET_C_FE_PUT_MSGPOOL_ERR = 0x51,
+    NET_C_FE_PUT_QEPOOL_ERR = 0x52,
+    NET_C_FE_GET_MSGPOOL_ERR = 0x53,
+    NET_C_FE_GET_QEPOOL_ERR = 0x54,
+
+    NET_C_FE_SENT_MSG = 0x20,  //:app. send       :msg uid, origin, next_hop
+    NET_C_FE_RCV_MSG =  0x21,  //:next hop receive:msg uid, origin, last_hop
+    NET_C_FE_FWD_MSG =  0x22,  //:fwd msg         :msg uid, origin, next_hop
+    NET_C_FE_DST_MSG =  0x23,  //:base app. recv  :msg_uid, origin, last_hop
+    NET_C_FE_SENDDONE_FAIL = 0x24,
+    NET_C_FE_SENDDONE_WAITACK = 0x25,
+    NET_C_FE_SENDDONE_FAIL_ACK_SEND = 0x26,
+    NET_C_FE_SENDDONE_FAIL_ACK_FWD  = 0x27,
+    NET_C_FE_DUPLICATE_CACHE = 0x28,  //dropped duplicate packet seen in cache
+    NET_C_FE_DUPLICATE_QUEUE = 0x29,  //dropped duplicate packet seen in queue
+    NET_C_FE_DUPLICATE_CACHE_AT_SEND = 0x2A,  //dropped duplicate packet seen in cache
+
+
+    NET_C_TREE_NO_ROUTE   = 0x30,   //:        :no args
+    NET_C_TREE_NEW_PARENT = 0x31,   //:        :parent_id, hopcount, metric
+    NET_C_TREE_ROUTE_INFO = 0x32,   //:periodic:parent_id, hopcount, metric
+    NET_C_TREE_SENT_BEACON = 0x33,
+    NET_C_TREE_RCV_BEACON = 0x34,
+
+    NET_C_DBG_1 = 0x40,             //:any     :uint16_t a
+    NET_C_DBG_2 = 0x41,             //:any     :uint16_t a, b, c
+    NET_C_DBG_3 = 0x42,             //:any     :uint16_t a, b, c
+};
+
+typedef nx_struct CollectionDebugMsg {
+    nx_uint8_t type;
+    nx_union {
+        nx_uint16_t arg;
+        nx_struct {
+            nx_uint16_t msg_uid;   
+            nx_am_addr_t origin;
+            nx_am_addr_t other_node;
+        } msg;
+        nx_struct {
+            nx_am_addr_t parent;
+            nx_uint8_t hopcount;
+            nx_uint16_t metric;
+        } route_info;
+        nx_struct {
+            nx_uint16_t a;
+            nx_uint16_t b;
+            nx_uint16_t c;
+        } dbg;
+    } data;
+    nx_uint16_t seqno;
+} CollectionDebugMsg;
+
+#endif
diff --git a/tos/lib/net/CollectionId.nc b/tos/lib/net/CollectionId.nc
new file mode 100644 (file)
index 0000000..5e3a967
--- /dev/null
@@ -0,0 +1,47 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2006 Massachusetts Institute of Technology (MIT).
+ * 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 Massachusetts Institute of Technology 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
+ * MASSACHUSETTS INSITIUTE OF TECHNOLOGY 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.
+ */
+
+/**
+ *  Interface for fetching the collection ID associated with a
+ *  collection sender instance.
+ *
+ *  @author Kyle Jamieson
+ *  @date   $Date$
+ */
+
+#include "Collection.h"
+
+interface CollectionId {
+  command collection_id_t fetch();
+}
diff --git a/tos/lib/net/CollectionIdP.nc b/tos/lib/net/CollectionIdP.nc
new file mode 100644 (file)
index 0000000..03be05d
--- /dev/null
@@ -0,0 +1,53 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2006 Massachusetts Institute of Technology (MIT).
+ * 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 Massachusetts Institute of Technology 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
+ * MASSACHUSETTS INSITIUTE OF TECHNOLOGY 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.
+ */
+
+/**
+ *  Interface for fetching the collection ID associated with a
+ *  collection sender instance.
+ *
+ *  @author Kyle Jamieson
+ *  @date   $Date$
+ */
+
+#include "Collection.h"
+
+generic module CollectionIdP(collection_id_t collectid) {
+  provides interface CollectionId;
+}
+
+implementation {
+  command collection_id_t CollectionId.fetch() {
+    return collectid;
+  }
+}
diff --git a/tos/lib/net/CollectionPacket.nc b/tos/lib/net/CollectionPacket.nc
new file mode 100644 (file)
index 0000000..62bf3a3
--- /dev/null
@@ -0,0 +1,52 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  @author Philip Levis
+ *  @author Kyle Jamieson
+ *  @date   $Date$
+ */
+
+#include <AM.h>
+#include <Collection.h>
+
+interface CollectionPacket {
+  command am_addr_t getOrigin(message_t* msg);
+  command void setOrigin(message_t* msg, am_addr_t addr);
+  
+  command collection_id_t getType(message_t* msg);
+  command void setType(message_t* msg, collection_id_t id);
+  
+  command uint8_t getSequenceNumber(message_t* msg);
+  command void setSequenceNumber(message_t* msg, uint8_t seqno);
+}
+
diff --git a/tos/lib/net/NeighborTableEviction.nc b/tos/lib/net/NeighborTableEviction.nc
new file mode 100644 (file)
index 0000000..4eaeda5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * "Copyright (c) 2006 The Regents of the University  of California.  
+ * 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 University of California 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
+ * REGENTS OF THE UNVERSITY OF CALIFORNIA 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.
+ */
+
+/**
+ * Notify when a neighbor has been evicted from the neighbor table.
+ *
+ * @author Rodrigo Fonseca
+ */
+
+interface NeighborTableEviction {
+
+  /**
+   * Signals to users that the neighbor has been evicted from the table
+   */
+  event void evicted(uint16_t neighbor)
+}
+
diff --git a/tos/lib/net/README b/tos/lib/net/README
new file mode 100644 (file)
index 0000000..4906a85
--- /dev/null
@@ -0,0 +1,7 @@
+This directory contains network protocols that are part of
+the TinyOS core distribution. They are:
+
+ctp: Collection Tree Protocol (TEP 123)
+dip: DIssemination Protocol (TEP 1xx)
+rstp: Root Sequenced Tree Protocol (TEP 124)
+
diff --git a/tos/lib/net/RootControl.nc b/tos/lib/net/RootControl.nc
new file mode 100644 (file)
index 0000000..387f627
--- /dev/null
@@ -0,0 +1,44 @@
+/* $Id$ */
+/*
+ * "Copyright (c) 2006 The Regents of the University  of California.  
+ * 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 University of California 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
+ * REGENTS OF THE UNVERSITY OF CALIFORNIA 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.
+ */
+
+/** Controls whether the current node is a root of the tree
+ *  @author Rodrigo Fonseca
+ *  @date   $Date$
+ */
+
+interface RootControl {
+    command error_t setRoot();
+    command error_t unsetRoot();
+    command bool isRoot();
+}
diff --git a/tos/lib/net/UARTDebugSenderP.nc b/tos/lib/net/UARTDebugSenderP.nc
new file mode 100644 (file)
index 0000000..b339d87
--- /dev/null
@@ -0,0 +1,202 @@
+#include <CollectionDebugMsg.h>
+module UARTDebugSenderP {
+    provides {
+        interface CollectionDebug;
+    }
+    uses {
+        interface Boot;
+        interface Pool<message_t> as MessagePool;
+        interface Queue<message_t*> as SendQueue;
+        interface AMSend as UARTSend;
+    }
+} 
+implementation {
+    message_t uartPacket;
+    bool sending;
+    uint8_t len;
+    uint16_t statLogReceived = 0;
+    uint16_t statEnqueueFail = 0;
+    uint16_t statSendFail = 0;
+    uint16_t statSendDoneFail = 0;
+    uint16_t statSendDoneOk = 0;
+    uint16_t statSendDoneBug = 0;
+
+    event void Boot.booted() {
+        sending = FALSE;
+        len = sizeof(CollectionDebugMsg);
+        statSendFail = 0;
+        statLogReceived = 0;
+        statEnqueueFail = 0;
+        statSendDoneOk = 0;
+        statSendDoneFail = 0;
+        statSendDoneBug = 0;
+    }
+
+    task void sendTask() {
+        if (sending) {
+            return;
+        } else if (call SendQueue.empty()) {
+            return;
+        } else {
+            message_t* smsg = call SendQueue.head();
+            error_t eval = call UARTSend.send(AM_BROADCAST_ADDR, smsg, len);
+            if (eval == SUCCESS) {
+                sending = TRUE;
+                return;
+            } else {
+                //Drop packet. Don't retry.
+                statSendFail++;
+                call SendQueue.dequeue();
+                call MessagePool.put(smsg);
+                if (! call SendQueue.empty())
+                    post sendTask();
+            }
+        }
+    }
+
+    event void UARTSend.sendDone(message_t *msg, error_t error) {
+        message_t* qh = call SendQueue.head();
+        if (qh == NULL || qh != msg) {
+            //bad mojo
+            statSendDoneBug++;
+        } else {
+            call SendQueue.dequeue();
+            call MessagePool.put(msg);  
+            if (error == SUCCESS) 
+                statSendDoneOk++;
+            else 
+                statSendDoneFail++;
+        }
+        sending = FALSE;
+        if (!call SendQueue.empty()) 
+            post sendTask();
+    }
+
+    command error_t CollectionDebug.logEvent(uint8_t type) {
+        statLogReceived++;
+        if (call MessagePool.empty()) {
+            return FAIL;
+        } else {
+            message_t* msg = call MessagePool.get();
+            CollectionDebugMsg* dbg_msg = call UARTSend.getPayload(msg);
+            memset(dbg_msg, 0, len);
+
+            dbg_msg->type = type;
+            dbg_msg->seqno = statLogReceived;
+
+            if (call SendQueue.enqueue(msg) == SUCCESS) {
+                post sendTask();
+                return SUCCESS;
+            } else {
+                statEnqueueFail++;
+                call MessagePool.put(msg);
+                return FAIL;
+            }
+        }
+    }
+    /* Used for FE_SENT_MSG, FE_RCV_MSG, FE_FWD_MSG, FE_DST_MSG */
+    command error_t CollectionDebug.logEventMsg(uint8_t type, uint16_t msg_id, am_addr_t origin, am_addr_t node) {
+        statLogReceived++;
+        if (call MessagePool.empty()) {
+            return FAIL;
+        } else {
+            message_t* msg = call MessagePool.get();
+            CollectionDebugMsg* dbg_msg = call UARTSend.getPayload(msg);
+            memset(dbg_msg, 0, len);
+
+            dbg_msg->type = type;
+            dbg_msg->data.msg.msg_uid = msg_id;
+            dbg_msg->data.msg.origin = origin;
+            dbg_msg->data.msg.other_node = node;
+            dbg_msg->seqno = statLogReceived;
+
+            if (call SendQueue.enqueue(msg) == SUCCESS) {
+                post sendTask();
+                return SUCCESS;
+            } else {
+                statEnqueueFail++;
+                call MessagePool.put(msg);
+                return FAIL;
+            }
+        }
+    }
+    /* Used for TREE_NEW_PARENT, TREE_ROUTE_INFO */
+    command error_t CollectionDebug.logEventRoute(uint8_t type, am_addr_t parent, uint8_t hopcount, uint16_t metric) {
+        statLogReceived++;
+        if (call MessagePool.empty()) {
+            return FAIL;
+        } else {
+            message_t* msg = call MessagePool.get();
+            CollectionDebugMsg* dbg_msg = call UARTSend.getPayload(msg);
+            memset(dbg_msg, 0, len);
+
+            dbg_msg->type = type;
+            dbg_msg->data.route_info.parent = parent;
+            dbg_msg->data.route_info.hopcount = hopcount;
+            dbg_msg->data.route_info.metric = metric;
+            dbg_msg->seqno = statLogReceived;
+
+            if (call SendQueue.enqueue(msg) == SUCCESS) {
+                post sendTask();
+                return SUCCESS;
+            } else {
+                statEnqueueFail++;
+                call MessagePool.put(msg);
+                return FAIL;
+            }
+        }
+    }
+    /* Used for DBG_1 */ 
+    command error_t CollectionDebug.logEventSimple(uint8_t type, uint16_t arg) {
+        statLogReceived++;
+        if (call MessagePool.empty()) {
+            return FAIL;
+        } else {
+            message_t* msg = call MessagePool.get();
+            CollectionDebugMsg* dbg_msg = call UARTSend.getPayload(msg);
+            memset(dbg_msg, 0, len);
+
+            dbg_msg->type = type;
+            dbg_msg->data.arg = arg;
+            dbg_msg->seqno = statLogReceived;
+
+            if (call SendQueue.enqueue(msg) == SUCCESS) {
+                post sendTask();
+                return SUCCESS;
+            } else {
+                statEnqueueFail++;
+                call MessagePool.put(msg);
+                return FAIL;
+            }
+        }
+    }
+    /* Used for DBG_2, DBG_3 */
+    command error_t CollectionDebug.logEventDbg(uint8_t type, uint16_t arg1, uint16_t arg2, uint16_t arg3) {
+        statLogReceived++;
+        if (call MessagePool.empty()) {
+            return FAIL;
+        } else {
+            message_t* msg = call MessagePool.get();
+            CollectionDebugMsg* dbg_msg = call UARTSend.getPayload(msg);
+            memset(dbg_msg, 0, len);
+
+            dbg_msg->type = type;
+            dbg_msg->data.dbg.a = arg1;
+            dbg_msg->data.dbg.b = arg2;
+            dbg_msg->data.dbg.c = arg3;
+            dbg_msg->seqno = statLogReceived;
+
+            if (call SendQueue.enqueue(msg) == SUCCESS) {
+                post sendTask();
+                return SUCCESS;
+            } else {
+                statEnqueueFail++;
+                call MessagePool.put(msg);
+                return FAIL;
+            }
+        }
+    }
+
+}
+    
diff --git a/tos/lib/net/UnicastNameFreeRouting.nc b/tos/lib/net/UnicastNameFreeRouting.nc
new file mode 100644 (file)
index 0000000..db21a29
--- /dev/null
@@ -0,0 +1,54 @@
+/* $Id$ */
+/*
+ * "Copyright (c) 2006 The Regents of the University  of California.  
+ * 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 University of California 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
+ * REGENTS OF THE UNVERSITY OF CALIFORNIA 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.
+ */
+
+/**
+ *  Provides a single next hop on a name-free protocol.
+ *
+ *  @author Philip Levis
+ *  @date   $Date$
+ */
+interface UnicastNameFreeRouting {
+
+  /**
+   * Get the address of the best next hop set to the destination.
+   * If there is not best next hop, the address is the local address.
+   * @return : The next best hop, or the local address if there is no route.
+   */
+  command am_addr_t nextHop();
+  command bool hasRoute();
+  
+  event void routeFound();
+  event void noRoute();
+}
+
diff --git a/tos/lib/net/ctp/.cvsignore b/tos/lib/net/ctp/.cvsignore
new file mode 100644 (file)
index 0000000..a01ee28
--- /dev/null
@@ -0,0 +1 @@
+.*.swp
diff --git a/tos/lib/net/ctp/Collection.h b/tos/lib/net/ctp/Collection.h
new file mode 100644 (file)
index 0000000..e20da69
--- /dev/null
@@ -0,0 +1,40 @@
+/* $Id$ */
+/*
+ * "Copyright (c) 2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/*
+ *  @author Rodrigo Fonseca
+ *  @date   $Date$
+ */
+#ifndef COLLECTION_H
+#define COLLECTION_H
+
+enum {
+    AM_COLLECTION_DATA = 20,
+    AM_COLLECTION_CONTROL = 21,
+    AM_COLLECTION_DEBUG = 22,
+};
+
+typedef uint8_t collection_id_t;
+typedef nx_uint8_t nx_collection_id_t;
+
+#endif
diff --git a/tos/lib/net/ctp/CollectionC.nc b/tos/lib/net/ctp/CollectionC.nc
new file mode 100644 (file)
index 0000000..bca0c79
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "Ctp.h"
+
+/**
+ * A data collection service that uses a tree routing protocol
+ * to deliver data to collection roots, following TEP 119.
+ *
+ * @author Rodrigo Fonseca
+ * @author Omprakash Gnawali
+ * @author Kyle Jamieson
+ * @author Philip Levis
+ */
+
+
+configuration CollectionC {
+  provides {
+    interface StdControl;
+    interface Send[uint8_t client];
+    interface Receive[collection_id_t id];
+    interface Receive as Snoop[collection_id_t];
+    interface Intercept[collection_id_t id];
+
+    interface Packet;
+    interface CollectionPacket;
+    interface CtpPacket;
+
+    interface CtpInfo;
+    interface CtpCongestion;
+    interface RootControl;    
+  }
+
+  uses {
+    interface CollectionId[uint8_t client];
+    interface CollectionDebug;
+  }
+}
+
+implementation {
+  components CtpP;
+
+  StdControl = CtpP;
+  Send = CtpP;
+  Receive = CtpP.Receive;
+  Snoop = CtpP.Snoop;
+  Intercept = CtpP;
+
+  Packet = CtpP;
+  CollectionPacket = CtpP;
+  CtpPacket = CtpP;
+
+  CtpInfo = CtpP;
+  CtpCongestion = CtpP;
+  RootControl = CtpP;
+
+  CollectionId = CtpP;
+  CollectionDebug = CtpP;
+}
+
diff --git a/tos/lib/net/ctp/CollectionSenderC.nc b/tos/lib/net/ctp/CollectionSenderC.nc
new file mode 100644 (file)
index 0000000..9fae7b1
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * The virtualized collection sender abstraction.
+ *
+ * @author Kyle Jamieson
+ * @author Philip Levis
+ * @date April 25 2006
+ * @see TinyOS Net2-WG
+ */
+
+#include <Collection.h>
+
+generic configuration CollectionSenderC(collection_id_t collectid) {
+  provides {
+    interface Send;
+    interface Packet;
+  }
+}
+implementation {
+  components new CollectionSenderP(collectid, unique(UQ_CTP_CLIENT));
+  Send = CollectionSenderP;
+  Packet = CollectionSenderP;
+}
diff --git a/tos/lib/net/ctp/CollectionSenderP.nc b/tos/lib/net/ctp/CollectionSenderP.nc
new file mode 100644 (file)
index 0000000..9ca2279
--- /dev/null
@@ -0,0 +1,18 @@
+#include "Collection.h"
+
+generic configuration 
+CollectionSenderP(collection_id_t collectid, uint8_t clientid) {
+  provides {
+    interface Send;
+    interface Packet;
+  }
+}
+
+implementation {
+  components CollectionC as Collector;
+  components new CollectionIdP(collectid);
+  
+  Send = Collector.Send[clientid];
+  Packet = Collector.Packet;
+  Collector.CollectionId[clientid] -> CollectionIdP;
+}
diff --git a/tos/lib/net/ctp/Ctp.h b/tos/lib/net/ctp/Ctp.h
new file mode 100644 (file)
index 0000000..5ba6a0b
--- /dev/null
@@ -0,0 +1,82 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  Header file that declares the AM types, message formats, and
+ *  constants for the TinyOS reference implementation of the
+ *  Collection Tree Protocol (CTP), as documented in TEP 123.
+ *
+ *  @author Philip Levis
+ *  @date   $Date$
+ */
+
+#ifndef CTP_H
+#define CTP_H
+
+#include <Collection.h>
+#include <AM.h>
+
+#define UQ_CTP_CLIENT "CtpSenderC.CollectId"
+
+enum {
+    // AM types:
+    AM_CTP_DATA    = 23,
+    AM_CTP_ROUTING = 24,
+    AM_CTP_DEBUG   = 25,
+
+    // CTP Options:
+    CTP_OPT_PULL      = 0x80, // TEP 123: P field
+    CTP_OPT_ECN       = 0x40, // TEP 123: C field
+};
+
+typedef nx_uint8_t nx_ctp_options_t;
+typedef uint8_t ctp_options_t;
+
+typedef nx_struct {
+  nx_ctp_options_t    options;
+  nx_uint8_t          thl;
+  nx_uint16_t         etx;
+  nx_am_addr_t        origin;
+  nx_uint8_t          originSeqNo;
+  nx_collection_id_t  type;
+  nx_uint8_t          data[0];
+} ctp_data_header_t;
+
+typedef nx_struct {
+  nx_ctp_options_t    options;
+  nx_am_addr_t        parent;
+  nx_uint16_t         etx;
+  nx_uint8_t          data[0];
+} ctp_routing_header_t;
+
+#endif
diff --git a/tos/lib/net/ctp/CtpCongestion.nc b/tos/lib/net/ctp/CtpCongestion.nc
new file mode 100644 (file)
index 0000000..a1561e8
--- /dev/null
@@ -0,0 +1,15 @@
+interface CtpCongestion {
+
+    /* Returns the current state of congestion from the provider. Ctp may be
+     * congested because its internal queue is congested or because the receive
+     * client called isCongested with TRUE. */
+
+    command bool isCongested();
+
+    /* Idempotent call to let the provider know whether a client is congested.
+     * If not previously congested, Ctp will take measures to slow down.
+     * Ctp has an internal congested condition as well. The result of isCongested
+     * is a logical OR with the parameter set here and the internal congestion.
+     */
+    command void setClientCongested(bool congested);
+}
diff --git a/tos/lib/net/ctp/CtpDebug.nc b/tos/lib/net/ctp/CtpDebug.nc
new file mode 100644 (file)
index 0000000..23d5fcb
--- /dev/null
@@ -0,0 +1,69 @@
+/* $Id$*/
+/*
+ * "Copyright (c) 2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/** 
+ *  The CollectionDebug is an interface for sending debugging events to
+ *  a logging infrastructure. An implementer can choose to send the event
+ *  information to different destinations. Primary examples can include:
+ *  <ul>
+ *    <li> logging to the UART, in case of a testbed of network-connected
+ *         nodes;
+ *    <li> logging to flash, if the logs are to be retrieved later
+ *    <li> logging to the standard output, in the case of TOSSIM.
+ *  </ul>
+ *  
+ *  The interface does not specify in what format the log is to be produced,
+ *  or if other information, like timestamps, should be added, and this is
+ *  up to the implementer.
+ * 
+ *  Some commands are generic, like Event, EventSimple, and EventDbg, while others
+ *  are for more specific events related to collection, like EventRoute and EventMsg.
+ *
+ * @author Rodrigo Fonseca
+ * @author Kyle Jamieson
+ * @date   $Date$
+ */
+
+interface CollectionDebug {
+    /* Log the occurrence of an event of type type */
+    command error_t logEvent(uint8_t type);
+
+    /* Log the occurrence of an event and a single parameter */
+    command error_t logEventSimple(uint8_t type, uint16_t arg);
+
+    /* Log the occurrence of an event and 3 16bit parameters */
+    command error_t logEventDbg(uint8_t type, uint16_t arg1, uint16_t arg2, uint16_t arg3);
+
+    /* Log the occurrence of an event related to forwarding a message.
+     * This is intended to allow following the same message as it goes from one
+     * hop to the next 
+     */
+    command error_t logEventMsg(uint8_t type, uint16_t msg, am_addr_t origin, am_addr_t node);
+
+    /* Log the occurrence of an event related to a route update message, 
+     * such as a node receiving a route, updating its own route information,
+     * or looking at a particular entry in its routing table.
+     */
+    command error_t logEventRoute(uint8_t type, am_addr_t parent, uint8_t hopcount, uint16_t metric);
+}
diff --git a/tos/lib/net/ctp/CtpDebugMsg.h b/tos/lib/net/ctp/CtpDebugMsg.h
new file mode 100644 (file)
index 0000000..7f42826
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef _COLLECTION_UART_MSG
+#define _COLLECTION_UART_MSG
+
+#include "AM.h"
+
+//Comment format ->   :meaning:args
+enum {
+    NET_C_DEBUG_STARTED = 0xDE,
+
+    NET_C_FE_MSG_POOL_EMPTY = 0x10,    //::no args
+    NET_C_FE_SEND_QUEUE_FULL = 0x11,   //::no args
+    NET_C_FE_NO_ROUTE = 0x12,          //::no args
+    NET_C_FE_SUBSEND_OFF = 0x13,
+    NET_C_FE_SUBSEND_BUSY = 0x14,
+    NET_C_FE_BAD_SENDDONE = 0x15,
+    NET_C_FE_QENTRY_POOL_EMPTY = 0x16,
+    NET_C_FE_SUBSEND_SIZE = 0x17,
+    NET_C_FE_LOOP_DETECTED = 0x18,
+    NET_C_FE_SEND_BUSY = 0x19,
+
+    NET_C_FE_SENDQUEUE_EMPTY = 0x50,
+    NET_C_FE_PUT_MSGPOOL_ERR = 0x51,
+    NET_C_FE_PUT_QEPOOL_ERR = 0x52,
+    NET_C_FE_GET_MSGPOOL_ERR = 0x53,
+    NET_C_FE_GET_QEPOOL_ERR = 0x54,
+
+    NET_C_FE_SENT_MSG = 0x20,  //:app. send       :msg uid, origin, next_hop
+    NET_C_FE_RCV_MSG =  0x21,  //:next hop receive:msg uid, origin, last_hop
+    NET_C_FE_FWD_MSG =  0x22,  //:fwd msg         :msg uid, origin, next_hop
+    NET_C_FE_DST_MSG =  0x23,  //:base app. recv  :msg_uid, origin, last_hop
+    NET_C_FE_SENDDONE_FAIL = 0x24,
+    NET_C_FE_SENDDONE_WAITACK = 0x25,
+    NET_C_FE_SENDDONE_FAIL_ACK_SEND = 0x26,
+    NET_C_FE_SENDDONE_FAIL_ACK_FWD  = 0x27,
+    NET_C_FE_DUPLICATE_CACHE = 0x28,  //dropped duplicate packet seen in cache
+    NET_C_FE_DUPLICATE_QUEUE = 0x29,  //dropped duplicate packet seen in queue
+    NET_C_FE_DUPLICATE_CACHE_AT_SEND = 0x2A,  //dropped duplicate packet seen in cache
+    NET_C_FE_CONGESTION_SENDWAIT = 0x2B, // sendTask deferring for congested parent
+    NET_C_FE_CONGESTION_BEGIN = 0x2C, // 
+    NET_C_FE_CONGESTION_END = 0x2D, // congestion over: reason is arg;
+                                    //  arg=1 => overheard parent's
+                                    //           ECN cleared.
+                                    //  arg=0 => timeout.
+    NET_C_TREE_NO_ROUTE   = 0x30,   //:        :no args
+    NET_C_TREE_NEW_PARENT = 0x31,   //:        :parent_id, hopcount, metric
+    NET_C_TREE_ROUTE_INFO = 0x32,   //:periodic:parent_id, hopcount, metric
+    NET_C_TREE_SENT_BEACON = 0x33,
+    NET_C_TREE_RCV_BEACON = 0x34,
+
+    NET_C_DBG_1 = 0x40,             //:any     :uint16_t a
+    NET_C_DBG_2 = 0x41,             //:any     :uint16_t a, b, c
+    NET_C_DBG_3 = 0x42,             //:any     :uint16_t a, b, c
+};
+
+typedef nx_struct CollectionDebugMsg {
+    nx_uint8_t type;
+    nx_union {
+        nx_uint16_t arg;
+        nx_struct {
+            nx_uint16_t msg_uid;   
+            nx_am_addr_t origin;
+            nx_am_addr_t other_node;
+        } msg;
+        nx_struct {
+            nx_am_addr_t parent;
+            nx_uint8_t hopcount;
+            nx_uint16_t metric;
+        } route_info;
+        nx_struct {
+            nx_uint16_t a;
+            nx_uint16_t b;
+            nx_uint16_t c;
+        } dbg;
+    } data;
+    nx_uint16_t seqno;
+} CollectionDebugMsg;
+
+#endif
diff --git a/tos/lib/net/ctp/CtpForwardingEngine.h b/tos/lib/net/ctp/CtpForwardingEngine.h
new file mode 100644 (file)
index 0000000..f79f672
--- /dev/null
@@ -0,0 +1,118 @@
+#ifndef FORWARDING_ENGINE_H
+#define FORWARDING_ENGINE_H
+
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <AM.h>
+#include <message.h>
+
+/**
+ * Author: Philip Levis
+ * Author: Kyle Jamieson 
+ * Author: Omprakash Gnawali
+ * Author: Rodrigo Fonseca
+ */
+
+/* 
+ * These timings are in milliseconds, and are used by
+ * ForwardingEngineP. Each pair of values represents a range of
+ * [OFFSET - (OFFSET + WINDOW)]. The ForwardingEngine uses these
+ * values to determine when to send the next packet after an
+ * event. FAIL refers to a send fail (an error from the radio below),
+ * NOACK refers to the previous packet not being acknowledged,
+ * OK refers to an acknowledged packet, and LOOPY refers to when
+ * a loop is detected.
+ *
+ * These timings are defined in terms of packet times. Currently,
+ * two values are defined: for CC2420-based platforms (4ms) and
+ * all other platfoms (32ms). 
+ */
+
+enum {
+#if PLATFORM_MICAZ || PLATFORM_TELOSA || PLATFORM_TELOSB || PLATFORM_TMOTE
+  FORWARD_PACKET_TIME = 4,
+#else
+  FORWARD_PACKET_TIME = 32,
+#endif
+};
+
+enum {
+  SENDDONE_FAIL_OFFSET      =                       512,
+  SENDDONE_NOACK_OFFSET     = FORWARD_PACKET_TIME  << 2,
+  SENDDONE_OK_OFFSET        = FORWARD_PACKET_TIME  << 2,
+  LOOPY_OFFSET              = FORWARD_PACKET_TIME  << 4,
+  SENDDONE_FAIL_WINDOW      = SENDDONE_FAIL_OFFSET  - 1,
+  LOOPY_WINDOW              = LOOPY_OFFSET          - 1,
+  SENDDONE_NOACK_WINDOW     = SENDDONE_NOACK_OFFSET - 1,
+  SENDDONE_OK_WINDOW        = SENDDONE_OK_OFFSET    - 1,
+  CONGESTED_WAIT_OFFSET     = FORWARD_PACKET_TIME  << 2,
+  CONGESTED_WAIT_WINDOW     = CONGESTED_WAIT_OFFSET - 1,
+};
+
+
+/* 
+ * The number of times the ForwardingEngine will try to 
+ * transmit a packet before giving up if the link layer
+ * supports acknowledgments. If the link layer does
+ * not support acknowledgments it sends the packet once.
+ */
+enum {
+  MAX_RETRIES = 30
+};
+
+/*
+ * The network header that the ForwardingEngine introduces.
+ * This header will change for the TinyOS 2.0 full release 
+ * (it needs several optimizations).
+ */
+typedef nx_struct {
+  nx_uint8_t control;
+  nx_am_addr_t origin;
+  nx_uint8_t seqno;
+  nx_uint8_t collectid;
+  nx_uint16_t gradient;
+} network_header_t;
+
+/*
+ * An element in the ForwardingEngine send queue.
+ * The client field keeps track of which send client 
+ * submitted the packet or if the packet is being forwarded
+ * from another node (client == 255). Retries keeps track
+ * of how many times the packet has been transmitted.
+ */
+typedef struct {
+  message_t *msg;
+  uint8_t client;
+  uint8_t retries;
+} fe_queue_entry_t;
+
+#endif
diff --git a/tos/lib/net/ctp/CtpForwardingEngineP.nc b/tos/lib/net/ctp/CtpForwardingEngineP.nc
new file mode 100644 (file)
index 0000000..f62ac97
--- /dev/null
@@ -0,0 +1,1014 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ *  The ForwardingEngine is responsible for queueing and scheduling outgoing
+ *  packets in a collection protocol. It maintains a pool of forwarding messages 
+ *  and a packet send 
+ *  queue. A ForwardingEngine with a forwarding message pool of size <i>F</i> 
+ *  and <i>C</i> CollectionSenderC clients has a send queue of size
+ *  <i>F + C</i>. This implementation has a large number of configuration
+ *  constants, which can be found in <code>ForwardingEngine.h</code>.
+ *
+ *  <p>Packets in the send queue are sent in FIFO order, with head-of-line
+ *  blocking. Because this is a tree collection protocol, all packets are going
+ *  to the same destination, and so the ForwardingEngine does not distinguish
+ *  packets from one another: packets from CollectionSenderC clients are
+ *  treated identically to forwarded packets.</p>
+ *
+ *  <p>If ForwardingEngine is on top of a link layer that supports
+ *  synchronous acknowledgments, it enables them and retransmits packets
+ *  when they are not acked. It transmits a packet up to MAX_RETRIES times
+ *  before giving up and dropping the packet.</p> 
+ *
+ *  <p>The ForwardingEngine detects routing loops and tries to correct
+ *  them. It assumes that the collection tree is based on a gradient,
+ *  such as hop count or estimated transmissions. When the ForwardingEngine
+ *  sends a packet to the next hop, it puts the local gradient value in
+ *  the packet header. If a node receives a packet to forward whose
+ *  gradient value is less than its own, then the gradient is not monotonically
+ *  decreasing and there may be a routing loop. When the ForwardingEngine
+ *  receives such a packet, it tells the RoutingEngine to advertise its
+ *  gradient value soon, with the hope that the advertisement will update
+ *  the node who just sent a packet and break the loop.
+ *  
+ *  <p>ForwardingEngine times its packet transmissions. It differentiates
+ *  between four transmission cases: forwarding, success, ack failure, 
+ *  and loop detection. In each case, the
+ *  ForwardingEngine waits a randomized period of time before sending the next
+ *  packet. This approach assumes that the network is operating at low
+ *  utilization; its goal is to prevent correlated traffic -- such as 
+ *  nodes along a route forwarding packets -- from interfering with itself.
+ *
+ *  <table>
+ *    <tr>
+ *      <td><b>Case</b></td>
+ *      <td><b>CC2420 Wait (ms)</b></td>
+ *      <td><b>Other Wait (ms)</b></td>
+ *      <td><b>Description</b></td>
+ *    </tr>
+ *    <tr>
+ *      <td>Forwarding</td>
+ *      <td>Immediate</td>
+ *      <td>Immediate</td>
+ *      <td>When the ForwardingEngine receives a packet to forward and it is not
+ *          already sending a packet (queue is empty). In this case, it immediately
+ *          forwards the packet.</td>
+ *    </tr>
+ *    <tr>
+ *      <td>Success</td>
+ *      <td>16-31</td>
+ *      <td>128-255</td>
+ *      <td>When the ForwardingEngine successfully sends a packet to the next
+ *          hop, it waits this long before sending the next packet in the queue.
+ *          </td>
+ *    </tr>
+ *    <tr>
+ *      <td>Ack Failure</td>
+ *      <td>8-15</td>
+ *      <td>128-255</td>
+ *      <td>If the link layer supports acks and the ForwardingEngine did not
+ *          receive an acknowledgment from the next hop, it waits this long before
+ *          trying a retransmission. If the packet has exceeded the retransmission
+ *          count, ForwardingEngine drops the packet and uses the Success timer instead. </td>
+ *    </tr>
+ *    <tr>
+ *      <td>Loop Detection</td>
+ *      <td>32-63</td>
+ *      <td>512-1023</td>
+ *      <td>If the ForwardingEngine is asked to forward a packet from a node that
+ *          believes it is closer to the root, the ForwardingEngine pauses its
+ *          transmissions for this interval and triggers the RoutingEngine to 
+ *          send an update. The goal is to let the gradient become consistent before
+ *          sending packets, in order to prevent routing loops from consuming
+ *          bandwidth and energy.</td>
+ *    </tr>
+ *  </table>  
+ *
+ *  <p>The times above are all for CC2420-based platforms. The timings for
+ *  other platforms depend on their bit rates, as they are based on packet
+ *  transmission times.</p>
+
+ *  @author Philip Levis
+ *  @author Kyle Jamieson
+ *  @date   $Date$
+ */
+
+#include <CtpForwardingEngine.h>
+#include <CtpDebugMsg.h>
+   
+generic module CtpForwardingEngineP() {
+  provides {
+    interface Init;
+    interface StdControl;
+    interface Send[uint8_t client];
+    interface Receive[collection_id_t id];
+    interface Receive as Snoop[collection_id_t id];
+    interface Intercept[collection_id_t id];
+    interface Packet;
+    interface CollectionPacket;
+    interface CtpPacket;
+    interface CtpCongestion;
+  }
+  uses {
+    interface AMSend as SubSend;
+    interface Receive as SubReceive;
+    interface Receive as SubSnoop;
+    interface Packet as SubPacket;
+    interface UnicastNameFreeRouting;
+    interface SplitControl as RadioControl;
+    interface Queue<fe_queue_entry_t*> as SendQueue;
+    interface Pool<fe_queue_entry_t> as QEntryPool;
+    interface Pool<message_t> as MessagePool;
+    interface Timer<TMilli> as RetxmitTimer;
+
+    interface LinkEstimator;
+
+    // Counts down from the last time we heard from our parent; used
+    // to expire local state about parent congestion.
+    interface Timer<TMilli> as CongestionTimer;
+
+    interface Cache<message_t*> as SentCache;
+    interface CtpInfo;
+    interface PacketAcknowledgements;
+    interface Random;
+    interface RootControl;
+    interface CollectionId[uint8_t client];
+    interface AMPacket;
+    interface CollectionDebug;
+    interface Leds;
+  }
+}
+implementation {
+  /* Helper functions to start the given timer with a random number
+   * masked by the given mask and added to the given offset.
+   */
+  static void startRetxmitTimer(uint16_t mask, uint16_t offset);
+  static void startCongestionTimer(uint16_t mask, uint16_t offset);
+
+  /* Indicates whether our client is congested */
+  bool clientCongested = FALSE;
+
+  /* Tracks our parent's congestion state. */
+  bool parentCongested = FALSE;
+
+  /* Keeps track of whether the routing layer is running; if not,
+   * it will not send packets. */
+  bool running = FALSE;
+
+  /* Keeps track of whether the radio is on; no sense sending packets
+   * if the radio is off. */
+  bool radioOn = FALSE;
+
+  /* Keeps track of whether an ack is pending on an outgoing packet,
+   * so that the engine can work unreliably when the data-link layer
+   * does not support acks. */
+  bool ackPending = FALSE;
+
+  /* Keeps track of whether the packet on the head of the queue
+   * is being used, and control access to the data-link layer.*/
+  bool sending = FALSE;
+
+  /* Keep track of the last parent address we sent to, so that
+     unacked packets to an old parent are not incorrectly attributed
+     to a new parent. */
+  am_addr_t lastParent;
+  
+  /* Network-level sequence number, so that receivers
+   * can distinguish retransmissions from different packets. */
+  uint8_t seqno;
+
+  enum {
+    CLIENT_COUNT = uniqueCount(UQ_CTP_CLIENT)
+  };
+
+  /* Each sending client has its own reserved queue entry.
+     If the client has a packet pending, its queue entry is in the 
+     queue, and its clientPtr is NULL. If the client is idle,
+     its queue entry is pointed to by clientPtrs. */
+
+  fe_queue_entry_t clientEntries[CLIENT_COUNT];
+  fe_queue_entry_t* clientPtrs[CLIENT_COUNT];
+
+  /* The loopback message is for when a collection roots calls
+     Send.send. Since Send passes a pointer but Receive allows
+     buffer swaps, the forwarder copies the sent packet into 
+     the loopbackMsgPtr and performs a buffer swap with it.
+     See sendTask(). */
+     
+  message_t loopbackMsg;
+  message_t* loopbackMsgPtr;
+
+  command error_t Init.init() {
+    int i;
+    for (i = 0; i < CLIENT_COUNT; i++) {
+      clientPtrs[i] = clientEntries + i;
+      dbg("Forwarder", "clientPtrs[%hhu] = %p\n", i, clientPtrs[i]);
+    }
+    loopbackMsgPtr = &loopbackMsg;
+    lastParent = call AMPacket.address();
+    seqno = 0;
+    return SUCCESS;
+  }
+
+  command error_t StdControl.start() {
+    running = TRUE;
+    return SUCCESS;
+  }
+
+  command error_t StdControl.stop() {
+    running = FALSE;
+    return SUCCESS;
+  }
+
+  /* sendTask is where the first phase of all send logic
+   * exists (the second phase is in SubSend.sendDone()). */
+  task void sendTask();
+  
+  /* ForwardingEngine keeps track of whether the underlying
+     radio is powered on. If not, it enqueues packets;
+     when it turns on, it then starts sending packets. */ 
+  event void RadioControl.startDone(error_t err) {
+    if (err == SUCCESS) {
+      radioOn = TRUE;
+      if (!call SendQueue.empty()) {
+        post sendTask();
+      }
+    }
+  }
+  /* 
+   * If the ForwardingEngine has stopped sending packets because
+   * these has been no route, then as soon as one is found, start
+   * sending packets.
+   */ 
+  event void UnicastNameFreeRouting.routeFound() {
+    post sendTask();
+  }
+
+  event void UnicastNameFreeRouting.noRoute() {
+    // Depend on the sendTask to take care of this case;
+    // if there is no route the component will just resume
+    // operation on the routeFound event
+  }
+  
+  event void RadioControl.stopDone(error_t err) {
+    if (err == SUCCESS) {
+      radioOn = FALSE;
+    }
+  }
+
+  ctp_data_header_t* getHeader(message_t* m) {
+    return (ctp_data_header_t*)call SubPacket.getPayload(m, NULL);
+  }
+  /*
+   * The send call from a client. Return EBUSY if the client is busy
+   * (clientPtrs is NULL), otherwise configure its queue entry
+   * and put it in the send queue. If the ForwardingEngine is not
+   * already sending packets (the RetxmitTimer isn't running), post
+   * sendTask. It could be that the engine is running and sendTask
+   * has already been posted, but the post-once semantics make this
+   * not matter.
+   */ 
+  command error_t Send.send[uint8_t client](message_t* msg, uint8_t len) {
+    ctp_data_header_t* hdr;
+    fe_queue_entry_t *qe;
+    dbg("Forwarder", "%s: sending packet from client %hhu: %x, len %hhu\n", __FUNCTION__, client, msg, len);
+    if (!running) {return EOFF;}
+    if (len > call Send.maxPayloadLength[client]()) {return ESIZE;}
+    
+    call Packet.setPayloadLength(msg, len);
+    hdr = getHeader(msg);
+    hdr->origin = TOS_NODE_ID;
+    hdr->originSeqNo  = seqno++;
+    hdr->type = call CollectionId.fetch[client]();
+    hdr->thl = 0;
+
+    if (clientPtrs[client] == NULL) {
+      dbg("Forwarder", "%s: send failed as client is busy.\n", __FUNCTION__);
+      return EBUSY;
+    }
+
+    qe = clientPtrs[client];
+    qe->msg = msg;
+    qe->client = client;
+    qe->retries = MAX_RETRIES;
+    dbg("Forwarder", "%s: queue entry for %hhu is %hhu deep\n", __FUNCTION__, client, call SendQueue.size());
+    if (call SendQueue.enqueue(qe) == SUCCESS) {
+      if (radioOn && !call RetxmitTimer.isRunning()) {
+        post sendTask();
+      }
+      clientPtrs[client] = NULL;
+      return SUCCESS;
+    }
+    else {
+      dbg("Forwarder", 
+          "%s: send failed as packet could not be enqueued.\n", 
+          __FUNCTION__);
+      
+      // send a debug message to the uart
+      call CollectionDebug.logEvent(NET_C_FE_SEND_QUEUE_FULL);
+
+      // Return the pool entry, as it's not for me...
+      return FAIL;
+    }
+  }
+
+  command error_t Send.cancel[uint8_t client](message_t* msg) {
+    // cancel not implemented. will require being able
+    // to pull entries out of the queue.
+    return FAIL;
+  }
+
+  command uint8_t Send.maxPayloadLength[uint8_t client]() {
+    return call Packet.maxPayloadLength();
+  }
+
+  command void* Send.getPayload[uint8_t client](message_t* msg) {
+    return call Packet.getPayload(msg, NULL);
+  }
+
+  /*
+   * These is where all of the send logic is. When the ForwardingEngine
+   * wants to send a packet, it posts this task. The send logic is
+   * independent of whether it is a forwarded packet or a packet from
+   * a send client. 
+   *
+   * The task first checks that there is a packet to send and that
+   * there is a valid route. It then marshals the relevant arguments
+   * and prepares the packet for sending. If the node is a collection
+   * root, it signals Receive with the loopback message. Otherwise,
+   * it sets the packet to be acknowledged and sends it. It does not
+   * remove the packet from the send queue: while sending, the 
+   * packet being sent is at the head of the queue; a packet is dequeued
+   * in the sendDone handler, either due to retransmission failure
+   * or to a successful send.
+   */
+
+  task void sendTask() {
+    dbg("Forwarder", "%s: Trying to send a packet. Queue size is %hhu.\n", __FUNCTION__, call SendQueue.size());
+    if (sending) {
+      dbg("Forwarder", "%s: busy, don't send\n", __FUNCTION__);
+      call CollectionDebug.logEvent(NET_C_FE_SEND_BUSY);
+      return;
+    }
+    else if (call SendQueue.empty()) {
+      dbg("Forwarder", "%s: queue empty, don't send\n", __FUNCTION__);
+      call CollectionDebug.logEvent(NET_C_FE_SENDQUEUE_EMPTY);
+      return;
+    }
+    else if (!call RootControl.isRoot() && 
+             !call UnicastNameFreeRouting.hasRoute()) {
+      dbg("Forwarder", "%s: no route, don't send, start retry timer\n", __FUNCTION__);
+      call RetxmitTimer.startOneShot(10000);
+
+      // send a debug message to the uart
+      call CollectionDebug.logEvent(NET_C_FE_NO_ROUTE);
+
+      return;
+    }
+    /*
+    else if (parentCongested) {
+      // Do nothing; the congestion timer is necessarily set which
+      // will clear parentCongested and repost sendTask().
+      dbg("Forwarder", "%s: sendTask deferring for congested parent\n",
+          __FUNCTION__);
+      call CollectionDebug.logEvent(NET_C_FE_CONGESTION_SENDWAIT);
+    }
+    */
+    else {
+      error_t subsendResult;
+      fe_queue_entry_t* qe = call SendQueue.head();
+      uint8_t payloadLen = call SubPacket.payloadLength(qe->msg);
+      am_addr_t dest = call UnicastNameFreeRouting.nextHop();
+      uint16_t gradient;
+
+      if (call CtpInfo.isNeighborCongested(dest)) {
+        // Our parent is congested. We should wait.
+        // Don't repost the task, CongestionTimer will do the job
+        if (! parentCongested ) {
+          parentCongested = TRUE;
+          call CollectionDebug.logEvent(NET_C_FE_CONGESTION_BEGIN);
+        }
+        if (! call CongestionTimer.isRunning()) {
+          startCongestionTimer(CONGESTED_WAIT_WINDOW, CONGESTED_WAIT_OFFSET);
+        } 
+        dbg("Forwarder", "%s: sendTask deferring for congested parent\n",
+            __FUNCTION__);
+        //call CollectionDebug.logEvent(NET_C_FE_CONGESTION_SENDWAIT);
+        return;
+      } 
+      if (parentCongested) {
+        parentCongested = FALSE;
+        call CollectionDebug.logEvent(NET_C_FE_CONGESTION_END);
+      } 
+      // Once we are here, we have decided to send the packet.
+      if (call SentCache.lookup(qe->msg)) {
+        call CollectionDebug.logEvent(NET_C_FE_DUPLICATE_CACHE_AT_SEND);
+        call SendQueue.dequeue();
+        post sendTask();
+        return;
+      }
+      /* If our current parent is not the same as the last parent
+         we sent do, then reset the count of unacked packets: don't
+         penalize a new parent for the failures of a prior one.*/
+      if (dest != lastParent) {
+        qe->retries = MAX_RETRIES;
+        lastParent = dest;
+      }
+      dbg("Forwarder", "Sending queue entry %p\n", qe);
+      if (call RootControl.isRoot()) {
+        collection_id_t collectid = getHeader(qe->msg)->type;
+        memcpy(loopbackMsgPtr, qe->msg, sizeof(message_t));
+        ackPending = FALSE;
+       
+        dbg("Forwarder", "%s: I'm a root, so loopback and signal receive.\n", __FUNCTION__);
+        loopbackMsgPtr = signal Receive.receive[collectid](loopbackMsgPtr,
+                                                         call Packet.getPayload(loopbackMsgPtr, NULL), 
+                                                         call Packet.payloadLength(loopbackMsgPtr));
+        signal SubSend.sendDone(qe->msg, SUCCESS);
+        return;
+      }
+      
+      // Loop-detection functionality:
+      if (call CtpInfo.getEtx(&gradient) != SUCCESS) {
+        // If we have no metric, set our gradient conservatively so
+        // that other nodes don't automatically drop our packets.
+        gradient = 0;
+      }
+      call CtpPacket.setEtx(qe->msg, gradient);
+      
+      ackPending = (call PacketAcknowledgements.requestAck(qe->msg) == SUCCESS);
+
+      // Set or clear the congestion bit on *outgoing* packets.
+      if (call CtpCongestion.isCongested())
+        call CtpPacket.setOption(qe->msg, CTP_OPT_ECN);
+      else
+        call CtpPacket.clearOption(qe->msg, CTP_OPT_ECN);
+      
+      subsendResult = call SubSend.send(dest, qe->msg, payloadLen);
+      if (subsendResult == SUCCESS) {
+        // Successfully submitted to the data-link layer.
+        sending = TRUE;
+        dbg("Forwarder", "%s: subsend succeeded with %p.\n", __FUNCTION__, qe->msg);
+        if (qe->client < CLIENT_COUNT) {
+               dbg("Forwarder", "%s: client packet.\n", __FUNCTION__);
+        }
+        else {
+               dbg("Forwarder", "%s: forwarded packet.\n", __FUNCTION__);
+        }
+        return;
+      }
+      else if (subsendResult == EOFF) {
+       // The radio has been turned off underneath us. Assume that
+       // this is for the best. When the radio is turned back on, we'll
+       // handle a startDone event and resume sending.
+        radioOn = FALSE;
+       dbg("Forwarder", "%s: subsend failed from EOFF.\n", __FUNCTION__);
+        // send a debug message to the uart
+       call CollectionDebug.logEvent(NET_C_FE_SUBSEND_OFF);
+      }
+      else if (subsendResult == EBUSY) {
+       // This shouldn't happen, as we sit on top of a client and
+        // control our own output; it means we're trying to
+        // double-send (bug). This means we expect a sendDone, so just
+        // wait for that: when the sendDone comes in, // we'll try
+        // sending this packet again.  
+       dbg("Forwarder", "%s: subsend failed from EBUSY.\n", __FUNCTION__);
+        // send a debug message to the uart
+        call CollectionDebug.logEvent(NET_C_FE_SUBSEND_BUSY);
+      }
+      else if (subsendResult == ESIZE) {
+       dbg("Forwarder", "%s: subsend failed from ESIZE: truncate packet.\n", __FUNCTION__);
+       call Packet.setPayloadLength(qe->msg, call Packet.maxPayloadLength());
+       post sendTask();
+       call CollectionDebug.logEvent(NET_C_FE_SUBSEND_SIZE);
+      }
+    }
+  }
+
+  void sendDoneBug() {
+    // send a debug message to the uart
+    call CollectionDebug.logEvent(NET_C_FE_BAD_SENDDONE);
+  }
+
+  /*
+   * The second phase of a send operation; based on whether the transmission was
+   * successful, the ForwardingEngine either stops sending or starts the
+   * RetxmitTimer with an interval based on what has occured. If the send was
+   * successful or the maximum number of retransmissions has been reached, then
+   * the ForwardingEngine dequeues the current packet. If the packet is from a
+   * client it signals Send.sendDone(); if it is a forwarded packet it returns
+   * the packet and queue entry to their respective pools.
+   * 
+   */
+
+  event void SubSend.sendDone(message_t* msg, error_t error) {
+    fe_queue_entry_t *qe = call SendQueue.head();
+    dbg("Forwarder", "%s to %hu and %hhu\n", __FUNCTION__, call AMPacket.destination(msg), error);
+    if (qe == NULL || qe->msg != msg) {
+      dbg("Forwarder", "%s: BUG: not our packet (%p != %p)!\n", __FUNCTION__, msg, qe->msg);
+      sendDoneBug();      // Not our packet, something is very wrong...
+      return;
+    }
+    else if (error != SUCCESS) {
+      // Immediate retransmission is the worst thing to do.
+      dbg("Forwarder", "%s: send failed\n", __FUNCTION__);
+      call CollectionDebug.logEventMsg(NET_C_FE_SENDDONE_FAIL, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
+      startRetxmitTimer(SENDDONE_FAIL_WINDOW, SENDDONE_FAIL_OFFSET);
+    }
+    else if (ackPending && !call PacketAcknowledgements.wasAcked(msg)) {
+      // AckPending is for case when DL cannot support acks.
+      call LinkEstimator.txNoAck(call AMPacket.destination(msg));
+      call CtpInfo.recomputeRoutes();
+      if (--qe->retries) { 
+        dbg("Forwarder", "%s: not acked\n", __FUNCTION__);
+        call CollectionDebug.logEventMsg(NET_C_FE_SENDDONE_WAITACK, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
+        startRetxmitTimer(SENDDONE_NOACK_WINDOW, SENDDONE_NOACK_OFFSET);
+      } else {
+        //max retries, dropping packet
+        if (qe->client < CLIENT_COUNT) {
+            clientPtrs[qe->client] = qe;
+            signal Send.sendDone[qe->client](msg, FAIL);
+            call CollectionDebug.logEventMsg(NET_C_FE_SENDDONE_FAIL_ACK_SEND, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
+        } else {
+           if (call MessagePool.put(qe->msg) != SUCCESS)
+             call CollectionDebug.logEvent(NET_C_FE_PUT_MSGPOOL_ERR);
+           if (call QEntryPool.put(qe) != SUCCESS)
+             call CollectionDebug.logEvent(NET_C_FE_PUT_QEPOOL_ERR);
+           call CollectionDebug.logEventMsg(NET_C_FE_SENDDONE_FAIL_ACK_FWD, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
+        }
+        call SendQueue.dequeue();
+        sending = FALSE;
+        startRetxmitTimer(SENDDONE_OK_WINDOW, SENDDONE_OK_OFFSET);
+      }
+    }
+    else if (qe->client < CLIENT_COUNT) {
+      ctp_data_header_t* hdr;
+      uint8_t client = qe->client;
+      dbg("Forwarder", "%s: our packet for client %hhu, remove %p from queue\n", 
+          __FUNCTION__, client, qe);
+      call CollectionDebug.logEventMsg(NET_C_FE_SENT_MSG, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
+      call LinkEstimator.txAck(call AMPacket.destination(msg));
+      clientPtrs[client] = qe;
+      hdr = getHeader(qe->msg);
+      call SendQueue.dequeue();
+      signal Send.sendDone[client](msg, SUCCESS);
+      sending = FALSE;
+      startRetxmitTimer(SENDDONE_OK_WINDOW, SENDDONE_OK_OFFSET);
+    }
+    else if (call MessagePool.size() < call MessagePool.maxSize()) {
+      // A successfully forwarded packet.
+      dbg("Forwarder,Route", "%s: successfully forwarded packet (client: %hhu), message pool is %hhu/%hhu.\n", __FUNCTION__, qe->client, call MessagePool.size(), call MessagePool.maxSize());
+      call CollectionDebug.logEventMsg(NET_C_FE_FWD_MSG, 
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
+      call LinkEstimator.txAck(call AMPacket.destination(msg));
+      call SentCache.insert(qe->msg);
+      call SendQueue.dequeue();
+      if (call MessagePool.put(qe->msg) != SUCCESS)
+        call CollectionDebug.logEvent(NET_C_FE_PUT_MSGPOOL_ERR);
+      if (call QEntryPool.put(qe) != SUCCESS)
+        call CollectionDebug.logEvent(NET_C_FE_PUT_QEPOOL_ERR);
+      sending = FALSE;
+      startRetxmitTimer(SENDDONE_OK_WINDOW, SENDDONE_OK_OFFSET);
+      call Leds.led2Toggle();
+    }
+    else {
+      dbg("Forwarder", "%s: BUG: we have a pool entry, but the pool is full, client is %hhu.\n", __FUNCTION__, qe->client);
+      sendDoneBug();    // It's a forwarded packet, but there's no room the pool;
+      // someone has double-stored a pointer somewhere and we have nowhere
+      // to put this, so we have to leak it...
+    }
+  }
+
+  /*
+   * Function for preparing a packet for forwarding. Performs
+   * a buffer swap from the message pool. If there are no free
+   * message in the pool, it returns the passed message and does not
+   * put it on the send queue.
+   */
+  message_t* forward(message_t* m) {
+    if (call MessagePool.empty()) {
+      dbg("Route", "%s cannot forward, message pool empty.\n", __FUNCTION__);
+      // send a debug message to the uart
+      call CollectionDebug.logEvent(NET_C_FE_MSG_POOL_EMPTY);
+    }
+    else if (call QEntryPool.empty()) {
+      dbg("Route", "%s cannot forward, queue entry pool empty.\n", 
+          __FUNCTION__);
+      // send a debug message to the uart
+      call CollectionDebug.logEvent(NET_C_FE_QENTRY_POOL_EMPTY);
+    }
+    else {
+      message_t* newMsg;
+      fe_queue_entry_t *qe;
+      uint16_t gradient;
+      
+      qe = call QEntryPool.get();
+      if (qe == NULL) {
+        call CollectionDebug.logEvent(NET_C_FE_GET_MSGPOOL_ERR);
+        return m;
+      }
+
+      newMsg = call MessagePool.get();
+      if (newMsg == NULL) {
+        call CollectionDebug.logEvent(NET_C_FE_GET_QEPOOL_ERR);
+        return m;
+      }
+
+      memset(newMsg, 0, sizeof(message_t));
+      memset(m->metadata, 0, sizeof(message_metadata_t));
+      
+      qe->msg = m;
+      qe->client = 0xff;
+      qe->retries = MAX_RETRIES;
+
+      
+      if (call SendQueue.enqueue(qe) == SUCCESS) {
+        dbg("Forwarder,Route", "%s forwarding packet %p with queue size %hhu\n", __FUNCTION__, m, call SendQueue.size());
+        // Loop-detection code:
+        if (call CtpInfo.getEtx(&gradient) == SUCCESS) {
+          // We only check for loops if we know our own metric
+          if (call CtpPacket.getEtx(m) < gradient) {
+            // The incoming packet's metric (gradient) is less than our
+            // own gradient.  Trigger a route update and backoff.
+            call CtpInfo.triggerImmediateRouteUpdate();
+            startRetxmitTimer(LOOPY_WINDOW, LOOPY_OFFSET);
+            call CollectionDebug.logEventMsg(NET_C_FE_LOOP_DETECTED,
+                                        call CollectionPacket.getSequenceNumber(m), 
+                                        call CollectionPacket.getOrigin(m), 
+                                         call AMPacket.destination(m));
+          }
+        }
+
+        if (!call RetxmitTimer.isRunning()) {
+          // sendTask is only immediately posted if we don't detect a
+          // loop.
+          post sendTask();
+        }
+        
+        // Successful function exit point:
+        return newMsg;
+      } else {
+        // There was a problem enqueuing to the send queue.
+        if (call MessagePool.put(newMsg) != SUCCESS)
+          call CollectionDebug.logEvent(NET_C_FE_PUT_MSGPOOL_ERR);
+        if (call QEntryPool.put(qe) != SUCCESS)
+          call CollectionDebug.logEvent(NET_C_FE_PUT_QEPOOL_ERR);
+      }
+    }
+
+    // NB: at this point, we have a resource acquistion problem.
+    // Trigger an immediate route update, log the event, and drop the
+    // packet on the floor.
+    call CtpInfo.triggerImmediateRouteUpdate();
+    call CollectionDebug.logEvent(NET_C_FE_SEND_QUEUE_FULL);
+    return m;
+  }
+  /*
+   * Received a message to forward. Check whether it is a duplicate by
+   * checking the packets currently in the queue as well as the 
+   * send history cache (in case we recently forwarded this packet).
+   * The cache is important as nodes immediately forward packets
+   * but wait a period before retransmitting after an ack failure.
+   * If this node is a root, signal receive.
+   */ 
+  event message_t* 
+  SubReceive.receive(message_t* msg, void* payload, uint8_t len) {
+    uint8_t netlen;
+    collection_id_t collectid;
+    bool duplicate = FALSE;
+    fe_queue_entry_t* qe;
+    uint8_t i, thl;
+
+
+    collectid = call CtpPacket.getType(msg);
+
+    // Update the THL here, since it has lived another hop, and so
+    // that the root sees the correct THL.
+    thl = call CtpPacket.getThl(msg);
+    thl++;
+    call CtpPacket.setThl(msg, thl);
+
+    call CollectionDebug.logEventMsg(NET_C_FE_RCV_MSG,
+                                        call CollectionPacket.getSequenceNumber(msg), 
+                                        call CollectionPacket.getOrigin(msg), 
+                                         call AMPacket.destination(msg));
+    if (len > call SubSend.maxPayloadLength()) {
+      return msg;
+    }
+
+    //See if we remember having seen this packet
+    //We look in the sent cache ...
+    if (call SentCache.lookup(msg)) {
+        call CollectionDebug.logEvent(NET_C_FE_DUPLICATE_CACHE);
+        return msg;
+    }
+    //... and in the queue for duplicates
+    if (call SendQueue.size() > 0) {
+      for (i = call SendQueue.size(); --i;) {
+       qe = call SendQueue.element(i);
+       if (call CtpPacket.matchInstance(qe->msg, msg)) {
+         duplicate = TRUE;
+         break;
+       }
+      }
+    }
+    
+    if (duplicate) {
+        call CollectionDebug.logEvent(NET_C_FE_DUPLICATE_QUEUE);
+        return msg;
+    }
+
+    // If I'm the root, signal receive. 
+    else if (call RootControl.isRoot())
+      return signal Receive.receive[collectid](msg, 
+                        call Packet.getPayload(msg, &netlen), 
+                        call Packet.payloadLength(msg));
+    // I'm on the routing path and Intercept indicates that I
+    // should not forward the packet.
+    else if (!signal Intercept.forward[collectid](msg, 
+                        call Packet.getPayload(msg, &netlen), 
+                        call Packet.payloadLength(msg)))
+      return msg;
+    else {
+      dbg("Route", "Forwarding packet from %hu.\n", getHeader(msg)->origin);
+      return forward(msg);
+    }
+  }
+
+  command void* 
+  Receive.getPayload[collection_id_t id](message_t* msg, uint8_t* len) {
+    return call Packet.getPayload(msg, NULL);
+  }
+
+  command uint8_t
+  Receive.payloadLength[collection_id_t id](message_t *msg) {
+    return call Packet.payloadLength(msg);
+  }
+
+  command void *
+  Snoop.getPayload[collection_id_t id](message_t *msg, uint8_t *len) {
+    return call Packet.getPayload(msg, NULL);
+  }
+
+  command uint8_t Snoop.payloadLength[collection_id_t id](message_t *msg) {
+    return call Packet.payloadLength(msg);
+  }
+
+  event message_t* 
+  SubSnoop.receive(message_t* msg, void *payload, uint8_t len) {
+    //am_addr_t parent = call UnicastNameFreeRouting.nextHop();
+    am_addr_t proximalSrc = call AMPacket.source(msg);
+
+    // Check for the pull bit (P) [TEP123] and act accordingly.  This
+    // check is made for all packets, not just ones addressed to us.
+    if (call CtpPacket.option(msg, CTP_OPT_PULL))
+      call CtpInfo.triggerRouteUpdate();
+
+    call CtpInfo.setNeighborCongested(proximalSrc, call CtpPacket.option(msg, CTP_OPT_ECN));
+    return signal Snoop.receive[call CtpPacket.getType(msg)] 
+      (msg, payload + sizeof(ctp_data_header_t), 
+       len - sizeof(ctp_data_header_t));
+  }
+  
+  event void RetxmitTimer.fired() {
+    sending = FALSE;
+    post sendTask();
+  }
+
+  event void CongestionTimer.fired() {
+    //parentCongested = FALSE;
+    //call CollectionDebug.logEventSimple(NET_C_FE_CONGESTION_END, 0);
+    post sendTask();
+  }
+  
+
+  command bool CtpCongestion.isCongested() {
+    // A simple predicate for now to determine congestion state of
+    // this node.
+    bool congested = (call SendQueue.size() + 2 >= call SendQueue.maxSize()) ? 
+      TRUE : FALSE;
+    return ((congested || clientCongested)?TRUE:FALSE);
+  }
+
+  command void CtpCongestion.setClientCongested(bool congested) {
+    bool wasCongested = call CtpCongestion.isCongested();
+    clientCongested = congested;
+    if (!wasCongested && congested) {
+      call CtpInfo.triggerImmediateRouteUpdate();
+    } else if (wasCongested && ! (call CtpCongestion.isCongested())) {
+      call CtpInfo.triggerRouteUpdate();
+    }
+  }
+
+  command void Packet.clear(message_t* msg) {
+    call SubPacket.clear(msg);
+  }
+  
+  command uint8_t Packet.payloadLength(message_t* msg) {
+    return call SubPacket.payloadLength(msg) - sizeof(ctp_data_header_t);
+  }
+
+  command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
+    call SubPacket.setPayloadLength(msg, len + sizeof(ctp_data_header_t));
+  }
+  
+  command uint8_t Packet.maxPayloadLength() {
+    return call SubPacket.maxPayloadLength() - sizeof(ctp_data_header_t);
+  }
+
+  command void* Packet.getPayload(message_t* msg, uint8_t* len) {
+    uint8_t* payload = call SubPacket.getPayload(msg, len);
+    if (len != NULL) {
+      *len -= sizeof(ctp_data_header_t);
+    }
+    return payload + sizeof(ctp_data_header_t);
+  }
+
+  command am_addr_t       CollectionPacket.getOrigin(message_t* msg) {return getHeader(msg)->origin;}
+
+  command collection_id_t CollectionPacket.getType(message_t* msg) {return getHeader(msg)->type;}
+  command uint8_t         CollectionPacket.getSequenceNumber(message_t* msg) {return getHeader(msg)->originSeqNo;}
+  command void CollectionPacket.setOrigin(message_t* msg, am_addr_t addr) {getHeader(msg)->origin = addr;}
+  command void CollectionPacket.setType(message_t* msg, collection_id_t id) {getHeader(msg)->type = id;}
+  command void CollectionPacket.setSequenceNumber(message_t* msg, uint8_t _seqno) {getHeader(msg)->originSeqNo = _seqno;}
+  
+  //command ctp_options_t CtpPacket.getOptions(message_t* msg) {return getHeader(msg)->options;}
+
+  command uint8_t       CtpPacket.getType(message_t* msg) {return getHeader(msg)->type;}
+  command am_addr_t     CtpPacket.getOrigin(message_t* msg) {return getHeader(msg)->origin;}
+  command uint16_t      CtpPacket.getEtx(message_t* msg) {return getHeader(msg)->etx;}
+  command uint8_t       CtpPacket.getSequenceNumber(message_t* msg) {return getHeader(msg)->originSeqNo;}
+  command uint8_t       CtpPacket.getThl(message_t* msg) {return getHeader(msg)->thl;}
+  
+  command void CtpPacket.setThl(message_t* msg, uint8_t thl) {getHeader(msg)->thl = thl;}
+  command void CtpPacket.setOrigin(message_t* msg, am_addr_t addr) {getHeader(msg)->origin = addr;}
+  command void CtpPacket.setType(message_t* msg, uint8_t id) {getHeader(msg)->type = id;}
+
+  command bool CtpPacket.option(message_t* msg, ctp_options_t opt) {
+    return ((getHeader(msg)->options & opt) == opt) ? TRUE : FALSE;
+  }
+
+  command void CtpPacket.setOption(message_t* msg, ctp_options_t opt) {
+    getHeader(msg)->options |= opt;
+  }
+
+  command void CtpPacket.clearOption(message_t* msg, ctp_options_t opt) {
+    getHeader(msg)->options &= ~opt;
+  }
+
+  command void CtpPacket.setEtx(message_t* msg, uint16_t e) {getHeader(msg)->etx = e;}
+  command void CtpPacket.setSequenceNumber(message_t* msg, uint8_t _seqno) {getHeader(msg)->originSeqNo = _seqno;}
+
+  // A CTP packet ID is based on the origin and the THL field, to
+  // implement duplicate suppression as described in TEP 123.
+
+  command bool CtpPacket.matchInstance(message_t* m1, message_t* m2) {
+    return (call CtpPacket.getOrigin(m1) == call CtpPacket.getOrigin(m2) &&
+           call CtpPacket.getSequenceNumber(m1) == call CtpPacket.getSequenceNumber(m2) &&
+           call CtpPacket.getThl(m1) == call CtpPacket.getThl(m2) &&
+           call CtpPacket.getType(m1) == call CtpPacket.getType(m2));
+  }
+
+  command bool CtpPacket.matchPacket(message_t* m1, message_t* m2) {
+    return (call CtpPacket.getOrigin(m1) == call CtpPacket.getOrigin(m2) &&
+           call CtpPacket.getSequenceNumber(m1) == call CtpPacket.getSequenceNumber(m2) &&
+           call CtpPacket.getType(m1) == call CtpPacket.getType(m2));
+  }
+
+  default event void
+  Send.sendDone[uint8_t client](message_t *msg, error_t error) {
+  }
+
+  default event bool
+  Intercept.forward[collection_id_t collectid](message_t* msg, void* payload, 
+                                               uint16_t len) {
+    return TRUE;
+  }
+
+  default event message_t *
+  Receive.receive[collection_id_t collectid](message_t *msg, void *payload,
+                                             uint8_t len) {
+    return msg;
+  }
+
+  default event message_t *
+  Snoop.receive[collection_id_t collectid](message_t *msg, void *payload,
+                                           uint8_t len) {
+    return msg;
+  }
+
+  default command collection_id_t CollectionId.fetch[uint8_t client]() {
+    return 0;
+  }
+
+  static void startRetxmitTimer(uint16_t mask, uint16_t offset) {
+    uint16_t r = call Random.rand16();
+    r &= mask;
+    r += offset;
+    call RetxmitTimer.startOneShot(r);
+    dbg("Forwarder", "Rexmit timer will fire in %hu ms\n", r);
+  }
+
+  static void startCongestionTimer(uint16_t mask, uint16_t offset) {
+    uint16_t r = call Random.rand16();
+    r &= mask;
+    r += offset;
+    call CongestionTimer.startOneShot(r);
+    dbg("Forwarder", "Congestion timer will fire in %hu ms\n", r);
+  }
+
+  /* signalled when this neighbor is evicted from the neighbor table */
+  event void LinkEstimator.evicted(am_addr_t neighbor) {
+  }
+
+
+  /* Default implementations for CollectionDebug calls.
+   * These allow CollectionDebug not to be wired to anything if debugging
+   * is not desired. */
+
+    default command error_t CollectionDebug.logEvent(uint8_t type) {
+        return SUCCESS;
+    }
+    default command error_t CollectionDebug.logEventSimple(uint8_t type, uint16_t arg) {
+        return SUCCESS;
+    }
+    default command error_t CollectionDebug.logEventDbg(uint8_t type, uint16_t arg1, uint16_t arg2, uint16_t arg3) {
+        return SUCCESS;
+    }
+    default command error_t CollectionDebug.logEventMsg(uint8_t type, uint16_t msg, am_addr_t origin, am_addr_t node) {
+        return SUCCESS;
+    }
+    default command error_t CollectionDebug.logEventRoute(uint8_t type, am_addr_t parent, uint8_t hopcount, uint16_t metric) {
+        return SUCCESS;
+    }
+   
+}
+
+/* Rodrigo. This is an alternative
+  event void CtpInfo.ParentCongested(bool congested) {
+    if (congested) {
+      // We've overheard our parent's ECN bit set.
+      startCongestionTimer(CONGESTED_WAIT_WINDOW, CONGESTED_WAIT_OFFSET);
+      parentCongested = TRUE;
+      call CollectionDebug.logEvent(NET_C_FE_CONGESTION_BEGIN);
+    } else {
+      // We've overheard our parent's ECN bit cleared.
+      call CongestionTimer.stop();
+      parentCongested = FALSE;
+      call CollectionDebug.logEventSimple(NET_C_FE_CONGESTION_END, 1);
+      post sendTask();
+    }
+  }
+*/
+
diff --git a/tos/lib/net/ctp/CtpInfo.nc b/tos/lib/net/ctp/CtpInfo.nc
new file mode 100644 (file)
index 0000000..57c275e
--- /dev/null
@@ -0,0 +1,86 @@
+/* $Id$ */
+/*
+ * "Copyright (c) 2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/*
+ *  @author Rodrigo Fonseca
+ *  @author Philip Levis
+ *  @date   $Date$
+ *  @see Net2-WG
+ */
+
+
+interface CtpInfo {
+
+  /**
+   * Get the parent of the node in the tree.  The pointer is allocated
+   * by the caller.  If the parent is invalid, return FAIL.  The
+   * caller MUST NOT use the value in parent if the return is not
+   * SUCCESS.
+   */
+  
+  command error_t getParent(am_addr_t* parent);
+  
+  /**
+   * Get the path quality metric for the current path to the root
+   * through the current parent.  The pointer is allocated by the
+   * caller.  If the parent is invalid, return FAIL (no info).  The
+   * caller MUST NOT use the value in parent if the return is not
+   * SUCCESS.
+   */
+  
+  command error_t getEtx(uint16_t* etx);
+
+  /**
+   * This informs the routing engine that sending a beacon soon is
+   * advisable, e.g., in response to a pull bit.
+   */
+  
+  command void triggerRouteUpdate();
+
+  /**
+   * This informs the routing engine that sending a beacon as soon
+   * as possible is advisable, e.g., due to queue overflow or
+   * a detected loop.
+   */
+  command void triggerImmediateRouteUpdate();
+
+  /** 
+   * Tell the routing engine it might want to recompute its routes.
+   */
+  command void recomputeRoutes();
+
+  /**
+   * Informs the routing engine that a neighbor is congested
+   */
+  command void setNeighborCongested(am_addr_t n, bool congested);
+
+  /**
+   *  Returns the currently known state about a neighbor's congestion state
+   */
+  command bool isNeighborCongested(am_addr_t n);
+
+  command uint8_t numNeighbors();
+  command uint16_t getNeighborLinkQuality(uint8_t neighbor);
+  command uint16_t getNeighborRouteQuality(uint8_t neighbor);
+  command am_addr_t getNeighborAddr(uint8_t neighbor);
+}
diff --git a/tos/lib/net/ctp/CtpP.nc b/tos/lib/net/ctp/CtpP.nc
new file mode 100644 (file)
index 0000000..7f73f44
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * "Copyright (c) 2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "Ctp.h"
+
+/**
+ * A data collection service that uses a tree routing protocol
+ * to deliver data to collection roots, following TEP 119.
+ *
+ * @author Rodrigo Fonseca
+ * @author Omprakash Gnawali
+ * @author Kyle Jamieson
+ * @author Philip Levis
+ */
+
+
+configuration CtpP {
+  provides {
+    interface StdControl;
+    interface Send[uint8_t client];
+    interface Receive[collection_id_t id];
+    interface Receive as Snoop[collection_id_t];
+    interface Intercept[collection_id_t id];
+
+    interface Packet;
+    interface CollectionPacket;
+    interface CtpPacket;
+
+    interface CtpInfo;
+    interface LinkEstimator;
+    interface CtpCongestion;
+    interface RootControl;    
+  }
+
+  uses {
+    interface CollectionId[uint8_t client];
+    interface CollectionDebug;
+  }
+}
+
+implementation {
+  enum {
+    CLIENT_COUNT = uniqueCount(UQ_CTP_CLIENT),
+    FORWARD_COUNT = 5,
+    TREE_ROUTING_TABLE_SIZE = 10,
+    QUEUE_SIZE = CLIENT_COUNT + FORWARD_COUNT,
+    CACHE_SIZE = 4,
+  };
+
+  components ActiveMessageC;
+  components new CtpForwardingEngineP() as Forwarder;
+  components MainC, LedsC;
+  
+  Send = Forwarder;
+  StdControl = Forwarder;
+  Receive = Forwarder.Receive;
+  Snoop = Forwarder.Snoop;
+  Intercept = Forwarder;
+  Packet = Forwarder;
+  CollectionId = Forwarder;
+  CollectionPacket = Forwarder;
+  CtpPacket = Forwarder;
+  CtpCongestion = Forwarder;
+  
+  components new PoolC(message_t, FORWARD_COUNT) as MessagePoolP;
+  components new PoolC(fe_queue_entry_t, FORWARD_COUNT) as QEntryPoolP;
+  Forwarder.QEntryPool -> QEntryPoolP;
+  Forwarder.MessagePool -> MessagePoolP;
+
+  components new QueueC(fe_queue_entry_t*, QUEUE_SIZE) as SendQueueP;
+  Forwarder.SendQueue -> SendQueueP;
+
+  components new LruCtpMsgCacheC(CACHE_SIZE) as SentCacheP;
+  Forwarder.SentCache -> SentCacheP;
+
+  components new TimerMilliC() as RoutingBeaconTimer;
+  components new TimerMilliC() as RouteUpdateTimer;
+  components LinkEstimatorP as Estimator;
+  Forwarder.LinkEstimator -> Estimator;
+
+  components new AMSenderC(AM_CTP_DATA);
+  components new AMReceiverC(AM_CTP_DATA);
+  components new AMSnooperC(AM_CTP_DATA);
+  
+  components new CtpRoutingEngineP(TREE_ROUTING_TABLE_SIZE, 1, 1024) as Router;
+  StdControl = Router;
+  StdControl = Estimator;
+  RootControl = Router;
+  MainC.SoftwareInit -> Router;
+  Router.BeaconSend -> Estimator.Send;
+  Router.BeaconReceive -> Estimator.Receive;
+  Router.LinkEstimator -> Estimator.LinkEstimator;
+  Router.LinkSrcPacket -> Estimator.LinkSrcPacket;
+  Router.AMPacket -> ActiveMessageC;
+  Router.RadioControl -> ActiveMessageC;
+  Router.BeaconTimer -> RoutingBeaconTimer;
+  Router.RouteTimer -> RouteUpdateTimer;
+  Router.CollectionDebug = CollectionDebug;
+  Forwarder.CollectionDebug = CollectionDebug;
+  Forwarder.CtpInfo -> Router;
+  Router.CtpCongestion -> Forwarder;
+  CtpInfo = Router;
+
+  components new TimerMilliC() as RetxmitTimer;
+  Forwarder.RetxmitTimer -> RetxmitTimer;
+
+  components new TimerMilliC() as CongestionTimer;
+  Forwarder.CongestionTimer -> CongestionTimer;
+
+  components RandomC;
+  Router.Random -> RandomC;
+  Forwarder.Random -> RandomC;
+
+  MainC.SoftwareInit -> Forwarder;
+  Forwarder.SubSend -> AMSenderC;
+  Forwarder.SubReceive -> AMReceiverC;
+  Forwarder.SubSnoop -> AMSnooperC;
+  Forwarder.SubPacket -> AMSenderC;
+  Forwarder.RootControl -> Router;
+  Forwarder.UnicastNameFreeRouting -> Router.Routing;
+  Forwarder.RadioControl -> ActiveMessageC;
+  Forwarder.PacketAcknowledgements -> AMSenderC.Acks;
+  Forwarder.AMPacket -> AMSenderC;
+  Forwarder.Leds -> LedsC;
+  
+  components new AMSenderC(AM_CTP_ROUTING) as SendControl;
+  components new AMReceiverC(AM_CTP_ROUTING) as ReceiveControl;
+
+  LinkEstimator = Estimator;
+  
+  Estimator.AMSend -> SendControl;
+  Estimator.SubReceive -> ReceiveControl;
+  Estimator.SubPacket -> SendControl;
+  Estimator.SubAMPacket -> SendControl;
+  MainC.SoftwareInit -> Estimator;
+}
diff --git a/tos/lib/net/ctp/CtpPacket.nc b/tos/lib/net/ctp/CtpPacket.nc
new file mode 100644 (file)
index 0000000..41c2402
--- /dev/null
@@ -0,0 +1,70 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ *  ADT for CTP data frames.
+ *
+ *  @author Philip Levis
+ *  @author Kyle Jamieson
+ *  @date   $Date$
+ */
+
+#include <AM.h>
+   
+interface CtpPacket {
+  // Sets the given options bit.
+  command void          setOption(message_t* msg, ctp_options_t option);
+
+  // Clears the given options bit.
+  command void          clearOption(message_t* msg, ctp_options_t option);
+
+  // Returns TRUE iff all of the given options bits are set.
+  command bool          option(message_t* msg, ctp_options_t opt);
+
+  command uint8_t       getThl(message_t* msg);
+  command void          setThl(message_t* msg, uint8_t thl);
+
+  command uint16_t      getEtx(message_t* msg);
+  command void          setEtx(message_t* msg, uint16_t etx);
+
+  command am_addr_t     getOrigin(message_t* msg);
+  command void          setOrigin(message_t* msg, am_addr_t addr);
+
+  command uint8_t       getSequenceNumber(message_t* msg);
+  command void          setSequenceNumber(message_t* msg, uint8_t seqno);
+
+  command uint8_t       getType(message_t* msg);
+  command void          setType(message_t* msg, uint8_t id);
+
+  command bool          matchInstance(message_t* m1, message_t* m2);
+  command bool          matchPacket(message_t* m1, message_t* m2);
+}
diff --git a/tos/lib/net/ctp/CtpRoutingEngineP.nc b/tos/lib/net/ctp/CtpRoutingEngineP.nc
new file mode 100644 (file)
index 0000000..0044233
--- /dev/null
@@ -0,0 +1,780 @@
+#include <Timer.h>
+#include <TreeRouting.h>
+#include <CollectionDebugMsg.h>
+/* $Id$ */
+/*
+ * "Copyright (c) 2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/** 
+ *  The TreeRoutingEngine is responsible for computing the routes for
+ *  collection.  It builds a set of trees rooted at specific nodes (roots) and
+ *  maintains these trees using information provided by the link estimator on
+ *  the quality of one hop links.
+ * 
+ *  <p>Each node is part of only one tree at any given time, but there is no
+ *  difference from the node's point of view of which tree it is part. In other
+ *  words, a message is sent towards <i>a</i> root, but which one is not
+ *  specified. It is assumed that the roots will work together to have all data
+ *  aggregated later if need be.  The tree routing engine's responsibility is
+ *  for each node to find the path with the least number of transmissions to
+ *  any one root.
+ *
+ *  <p>The tree is proactively maintained by periodic beacons sent by each
+ *  node. These beacons are jittered in time to prevent synchronizations in the
+ *  network. All nodes maintain the same <i>average</i> beacon sending rate
+ *  (defined by BEACON_INTERVAL +- 50%). The beacon contains the node's parent,
+ *  the current hopcount, and the cumulative path quality metric. The metric is
+ *  defined as the parent's metric plus the bidirectional quality of the link
+ *  between the current node and its parent.  The metric represents the
+ *  expected number of transmissions along the path to the root, and is 0 by
+ *  definition at the root.
+ * 
+ *  <p>Every time a node receives an update from a neighbor it records the
+ *  information if the node is part of the neighbor table. The neighbor table
+ *  keeps the best candidates for being parents i.e., the nodes with the best
+ *  path metric. The neighbor table does not store the full path metric,
+ *  though. It stores the parent's path metric, and the link quality to the
+ *  parent is only added when the information is needed: (i) when choosing a
+ *  parent and (ii) when choosing a route. The nodes in the neighbor table are
+ *  a subset of the nodes in the link estimator table, as a node is not
+ *  admitted in the neighbor table with an estimate of infinity.
+ * 
+ *  <p>There are two uses for the neighbor table, as mentioned above. The first
+ *  one is to select a parent. The parent is just the neighbor with the best
+ *  path metric. It serves to define the node's own path metric and hopcount,
+ *  and the set of child-parent links is what defines the tree. In a sense the
+ *  tree is defined to form a coherent propagation substrate for the path
+ *  metrics. The parent is (re)-selected periodically, immediately before a
+ *  node sends its own beacon, in the updateRouteTask.
+ *  
+ *  <p>The second use is to actually choose a next hop towards any root at
+ *  message forwarding time.  This need not be the current parent, even though
+ *  it is currently implemented as such.
+ *
+ *  <p>The operation of the routing engine has two main tasks and one main
+ *  event: updateRouteTask is called periodically and chooses a new parent;
+ *  sendBeaconTask broadcasts the current route information to the neighbors.
+ *  The main event is the receiving of a neighbor's beacon, which updates the
+ *  neighbor table.
+ *  
+ *  <p> The interface with the ForwardingEngine occurs through the nextHop()
+ *  call.
+ * 
+ *  <p> Any node can become a root, and routed messages from a subset of the
+ *  network will be routed towards it. The RootControl interface allows
+ *  setting, unsetting, and querying the root state of a node. By convention,
+ *  when a node is root its hopcount and metric are 0, and the parent is
+ *  itself. A root always has a valid route, to itself.
+ *
+ *  @author Rodrigo Fonseca
+ *  @author Philip Levis (added trickle-like updates)
+ *  Acknowledgment: based on MintRoute, MultiHopLQI, BVR tree construction, Berkeley's MTree
+ *                           
+ *  @date   $Date$
+ *  @see Net2-WG
+ */
+
+generic module CtpRoutingEngineP(uint8_t routingTableSize, uint16_t minInterval, uint16_t maxInterval) {
+    provides {
+        interface UnicastNameFreeRouting as Routing;
+        interface RootControl;
+        interface CtpInfo;
+        interface StdControl;
+        interface CtpRoutingPacket;
+        interface Init;
+    } 
+    uses {
+        interface AMSend as BeaconSend;
+        interface Receive as BeaconReceive;
+        interface LinkEstimator;
+        interface AMPacket;
+        interface LinkSrcPacket;
+        interface SplitControl as RadioControl;
+        interface Timer<TMilli> as BeaconTimer;
+        interface Timer<TMilli> as RouteTimer;
+        interface Random;
+        interface CollectionDebug;
+        interface CtpCongestion;
+    }
+}
+
+
+implementation {
+
+    bool ECNOff = TRUE;
+
+    /* Keeps track of whether the radio is on. No sense updating or sending
+     * beacons if radio is off */
+    bool radioOn = FALSE;
+    /* Controls whether the node's periodic timer will fire. The node will not
+     * send any beacon, and will not update the route. Start and stop control this. */
+    bool running = FALSE;
+    /* Guards the beacon buffer: only one beacon being sent at a time */
+    bool sending = FALSE;
+
+    /* Tells updateNeighbor that the parent was just evicted.*/ 
+    bool justEvicted = FALSE;
+
+    route_info_t routeInfo;
+    bool state_is_root;
+    am_addr_t my_ll_addr;
+
+    message_t beaconMsgBuffer;
+    ctp_routing_header_t* beaconMsg;
+
+    /* routing table -- routing info about neighbors */
+    routing_table_entry routingTable[routingTableSize];
+    uint8_t routingTableActive;
+
+    /* statistics */
+    uint32_t parentChanges;
+    /* end statistics */
+
+    uint32_t routeUpdateTimerCount;
+
+    // Maximimum it takes to hear four beacons
+    enum {
+      DEATH_TEST_INTERVAL = (maxInterval * 4) / (BEACON_INTERVAL / 1024),
+    };
+    
+    // forward declarations
+    void routingTableInit();
+    uint8_t routingTableFind(am_addr_t);
+    error_t routingTableUpdateEntry(am_addr_t, am_addr_t , uint16_t);
+    error_t routingTableEvict(am_addr_t neighbor);
+
+    uint16_t currentInterval = minInterval;
+    uint32_t t; 
+    bool tHasPassed;
+
+    void chooseAdvertiseTime() {
+       t = currentInterval;
+       t *= 512; // * 1024 / 2
+       t += call Random.rand32() % t;
+       tHasPassed = FALSE;
+       call BeaconTimer.stop();
+       call BeaconTimer.startOneShot(t);
+    }
+
+    void resetInterval() {
+      currentInterval = minInterval;
+      chooseAdvertiseTime();
+    }
+
+    void decayInterval() {
+      if (!state_is_root) {
+        currentInterval *= 2;
+        if (currentInterval > maxInterval) {
+          currentInterval = maxInterval;
+        }
+      }
+      chooseAdvertiseTime();
+    }
+
+    void remainingInterval() {
+       uint32_t remaining = currentInterval;
+       remaining *= 1024;
+       remaining -= t;
+       tHasPassed = TRUE;
+       call BeaconTimer.startPeriodic(t);
+    }
+
+    command error_t Init.init() {
+        uint8_t maxLength;
+       routeUpdateTimerCount = 0;
+        radioOn = FALSE;
+        running = FALSE;
+        parentChanges = 0;
+        state_is_root = 0;
+        routeInfoInit(&routeInfo);
+        routingTableInit();
+        my_ll_addr = call AMPacket.address();
+        beaconMsg = call BeaconSend.getPayload(&beaconMsgBuffer);
+        maxLength = call BeaconSend.maxPayloadLength();
+        dbg("TreeRoutingCtl","TreeRouting initialized. (used payload:%d max payload:%d!\n", 
+              sizeof(beaconMsg), maxLength);
+        return SUCCESS;
+    }
+
+    command error_t StdControl.start() {
+      //start will (re)start the sending of messages
+      if (!running) {
+       running = TRUE;
+       resetInterval();
+       call RouteTimer.startPeriodic(BEACON_INTERVAL);
+       dbg("TreeRoutingCtl","%s running: %d radioOn: %d\n", __FUNCTION__, running, radioOn);
+      }     
+      return SUCCESS;
+    }
+
+    command error_t StdControl.stop() {
+        running = FALSE;
+        dbg("TreeRoutingCtl","%s running: %d radioOn: %d\n", __FUNCTION__, running, radioOn);
+        return SUCCESS;
+    } 
+
+    event void RadioControl.startDone(error_t error) {
+        radioOn = TRUE;
+        dbg("TreeRoutingCtl","%s running: %d radioOn: %d\n", __FUNCTION__, running, radioOn);
+        if (running) {
+            uint16_t nextInt;
+            nextInt = call Random.rand16() % BEACON_INTERVAL;
+            nextInt += BEACON_INTERVAL >> 1;
+            call BeaconTimer.startOneShot(nextInt);
+        }
+    } 
+
+    event void RadioControl.stopDone(error_t error) {
+        radioOn = FALSE;
+        dbg("TreeRoutingCtl","%s running: %d radioOn: %d\n", __FUNCTION__, running, radioOn);
+    }
+
+    /* Is this quality measure better than the minimum threshold? */
+    // Implemented assuming quality is EETX
+    bool passLinkEtxThreshold(uint16_t etx) {
+       return TRUE;
+        return (etx < ETX_THRESHOLD);
+    }
+
+    /* Converts the output of the link estimator to path metric
+     * units, that can be *added* to form path metric measures */
+    uint16_t evaluateEtx(uint8_t quality) {
+        //dbg("TreeRouting","%s %d -> %d\n",__FUNCTION__,quality, quality+10);
+        return (quality + 10);
+    }
+
+    /* updates the routing information, using the info that has been received
+     * from neighbor beacons. Two things can cause this info to change: 
+     * neighbor beacons, changes in link estimates, including neighbor eviction */
+    /* TODO: take into account congested state to select parents */ 
+    task void updateRouteTask() {
+        uint8_t i;
+        routing_table_entry* entry;
+        routing_table_entry* best;
+        uint16_t minEtx;
+        uint16_t currentEtx;
+        uint16_t linkEtx, pathEtx;
+
+        if (state_is_root)
+            return;
+       
+        best = NULL;
+        /* Minimum etx found among neighbors, initially infinity */
+        minEtx = MAX_METRIC;
+        /* Metric through current parent, initially infinity */
+        currentEtx = MAX_METRIC;
+
+        dbg("TreeRouting","%s\n",__FUNCTION__);
+
+        /* Find best path in table, other than our current */
+        for (i = 0; i < routingTableActive; i++) {
+            entry = &routingTable[i];
+
+            // Avoid bad entries and 1-hop loops
+            if (entry->info.parent == INVALID_ADDR || entry->info.parent == my_ll_addr) {
+              dbg("TreeRouting", 
+                  "routingTable[%d]: neighbor: [id: %d parent: %d  etx: NO ROUTE]\n",  
+                  i, entry->neighbor, entry->info.parent);
+              continue;
+            }
+            /* Compute this neighbor's path metric */
+            linkEtx = evaluateEtx(call LinkEstimator.getLinkQuality(entry->neighbor));
+            dbg("TreeRouting", 
+                "routingTable[%d]: neighbor: [id: %d parent: %d etx: %d]\n",  
+                i, entry->neighbor, entry->info.parent, linkEtx);
+            pathEtx = linkEtx + entry->info.etx;
+            /* Operations specific to the current parent */
+            if (entry->neighbor == routeInfo.parent) {
+                dbg("TreeRouting", "   already parent.\n");
+                currentEtx = pathEtx;
+                /* update routeInfo with parent's current info */
+                atomic {
+                    routeInfo.etx = entry->info.etx;
+                    routeInfo.congested = entry->info.congested;
+                }
+                continue;
+            }
+            /* Ignore links that are bad */
+            if (!passLinkEtxThreshold(linkEtx)) {
+              dbg("TreeRouting", "   did not pass threshold.\n");
+              continue;
+            }
+            
+            if (pathEtx < minEtx) {
+                minEtx = pathEtx;
+                best = entry;
+            }  
+        }
+
+        //call CollectionDebug.logEventDbg(NET_C_DBG_3, routeInfo.parent, currentEtx, minEtx);  
+
+        /* Now choose between the current parent and the best neighbor */
+        if (minEtx != MAX_METRIC) {
+            if (currentEtx == MAX_METRIC ||
+                minEtx + PARENT_SWITCH_THRESHOLD < currentEtx) {
+                // routeInfo.metric will not store the composed metric.
+                // since the linkMetric may change, we will compose whenever
+                // we need it: i. when choosing a parent (here); 
+                //            ii. when choosing a next hop
+                parentChanges++;
+                resetInterval();
+                dbg("TreeRouting","Changed parent. from %d to %d\n", routeInfo.parent, best->neighbor);
+                call CollectionDebug.logEventRoute(NET_C_TREE_NEW_PARENT, best->neighbor, 0, best->info.etx); 
+                call LinkEstimator.unpinNeighbor(routeInfo.parent);
+                call LinkEstimator.pinNeighbor(best->neighbor);
+                call LinkEstimator.clearDLQ(best->neighbor);
+                atomic {
+                    routeInfo.parent = best->neighbor;
+                    routeInfo.etx = best->info.etx;
+                    routeInfo.congested = best->info.congested;
+                }
+            }
+        }    
+
+        /* Finally, tell people what happened:  */
+        /* We can only loose a route to a parent if it has been evicted. If it hasn't 
+         * been just evicted then we already did not have a route */
+        if (justEvicted && routeInfo.parent == INVALID_ADDR) 
+            signal Routing.noRoute();
+        /* On the other hand, if we didn't have a parent (no currentEtx) and now we
+         * do, then we signal route found. The exception is if we just evicted the 
+         * parent and immediately found a replacement route: we don't signal in this 
+         * case */
+        else if (!justEvicted && 
+                  currentEtx == MAX_METRIC &&
+                  minEtx != MAX_METRIC)
+            signal Routing.routeFound();
+        justEvicted = FALSE; 
+    }
+
+    
+
+    /* send a beacon advertising this node's routeInfo */
+    // only posted if running and radioOn
+    task void sendBeaconTask() {
+        error_t eval;
+        if (sending) {
+            return;
+        }
+
+        beaconMsg->options = 0;
+
+        /* Congestion notification: am I congested? */
+        if (call CtpCongestion.isCongested()) {
+            beaconMsg->options |= CTP_OPT_ECN;
+        }
+
+        beaconMsg->parent = routeInfo.parent;
+        if (state_is_root) {
+            beaconMsg->etx = routeInfo.etx;
+        }
+        else if (routeInfo.parent == INVALID_ADDR) {
+            beaconMsg->etx = routeInfo.etx;
+            beaconMsg->options |= CTP_OPT_PULL;
+        } else {
+            beaconMsg->etx = routeInfo.etx +
+                                evaluateEtx(call LinkEstimator.getLinkQuality(routeInfo.parent));
+        }
+
+        dbg("TreeRouting", "%s parent: %d etx: %d\n",
+                  __FUNCTION__,
+                  beaconMsg->parent, 
+                  beaconMsg->etx);
+        call CollectionDebug.logEventRoute(NET_C_TREE_SENT_BEACON, beaconMsg->parent, 0, beaconMsg->etx);
+
+        eval = call BeaconSend.send(AM_BROADCAST_ADDR, 
+                                    &beaconMsgBuffer, 
+                                    sizeof(ctp_routing_header_t));
+        if (eval == SUCCESS) {
+            sending = TRUE;
+        } else if (eval == EOFF) {
+            radioOn = FALSE;
+            dbg("TreeRoutingCtl","%s running: %d radioOn: %d\n", __FUNCTION__, running, radioOn);
+        }
+    }
+
+    event void BeaconSend.sendDone(message_t* msg, error_t error) {
+        if ((msg != &beaconMsgBuffer) || !sending) {
+            //something smells bad around here
+            return;
+        }
+        sending = FALSE;
+    }
+
+    event void RouteTimer.fired() {
+      if (radioOn && running) {
+       post updateRouteTask();
+      }
+    }
+      
+    event void BeaconTimer.fired() {
+      if (radioOn && running) {
+        if (!tHasPassed) {
+          post updateRouteTask(); //always send the most up to date info
+          post sendBeaconTask();
+          dbg("RoutingTimer", "Beacon timer fired at %s\n", sim_time_string());
+          remainingInterval();
+        }
+        else {
+          decayInterval();
+        }
+      }
+    }
+
+
+    ctp_routing_header_t* getHeader(message_t* m) {
+      return (ctp_routing_header_t*)call BeaconReceive.getPayload(m, NULL);
+    }
+    
+    
+    /* Handle the receiving of beacon messages from the neighbors. We update the
+     * table, but wait for the next route update to choose a new parent */
+    event message_t* BeaconReceive.receive(message_t* msg, void* payload, uint8_t len) {
+        am_addr_t from;
+        ctp_routing_header_t* rcvBeacon;
+        bool congested;
+
+        // Received a beacon, but it's not from us.
+        if (len != sizeof(ctp_routing_header_t)) {
+          dbg("LITest", "%s, received beacon of size %hhu, expected %i\n",
+                     __FUNCTION__, 
+                     len,
+                     (int)sizeof(ctp_routing_header_t));
+              
+          return msg;
+        }
+        
+        //need to get the am_addr_t of the source
+        from = call LinkSrcPacket.getSrc(msg);
+        rcvBeacon = (ctp_routing_header_t*)payload;
+        congested = call CtpRoutingPacket.getOption(msg, CTP_OPT_ECN);
+
+        dbg("TreeRouting","%s from: %d  [ parent: %d etx: %d]\n",
+            __FUNCTION__, from, 
+            rcvBeacon->parent, rcvBeacon->etx);
+        //call CollectionDebug.logEventRoute(NET_C_TREE_RCV_BEACON, rcvBeacon->parent, 0, rcvBeacon->etx);
+
+        //update neighbor table
+        if (rcvBeacon->parent != INVALID_ADDR) {
+
+            /* If this node is a root, request a forced insert in the link
+             * estimator table and pin the node. */
+            if (rcvBeacon->etx == 0) {
+                dbg("TreeRouting","from a root, inserting if not in table\n");
+                call LinkEstimator.insertNeighbor(from);
+                call LinkEstimator.pinNeighbor(from);
+            }
+            //TODO: also, if better than my current parent's path etx, insert
+
+            routingTableUpdateEntry(from, rcvBeacon->parent, rcvBeacon->etx);
+            call CtpInfo.setNeighborCongested(from, congested);
+        }
+
+        if (call CtpRoutingPacket.getOption(msg, CTP_OPT_PULL)) {
+              resetInterval();
+        }
+        //post updateRouteTask();
+        return msg;
+    }
+
+    /* Signals that a neighbor is no longer reachable. need special care if
+     * that neighbor is our parent */
+    event void LinkEstimator.evicted(am_addr_t neighbor) {
+        routingTableEvict(neighbor);
+        dbg("TreeRouting","%s\n",__FUNCTION__);
+        if (routeInfo.parent == neighbor) {
+            routeInfoInit(&routeInfo);
+            justEvicted = TRUE;
+            post updateRouteTask();
+        }
+    }
+
+    /* Interface UnicastNameFreeRouting */
+    /* Simple implementation: return the current routeInfo */
+    command am_addr_t Routing.nextHop() {
+        return routeInfo.parent;    
+    }
+    command bool Routing.hasRoute() {
+        return (routeInfo.parent != INVALID_ADDR);
+    }
+   
+    /* CtpInfo interface */
+    command error_t CtpInfo.getParent(am_addr_t* parent) {
+        if (parent == NULL) 
+            return FAIL;
+        if (routeInfo.parent == INVALID_ADDR)    
+            return FAIL;
+        *parent = routeInfo.parent;
+        return SUCCESS;
+    }
+
+    command error_t CtpInfo.getEtx(uint16_t* etx) {
+        if (etx == NULL) 
+            return FAIL;
+        if (routeInfo.parent == INVALID_ADDR)    
+            return FAIL;
+        *etx = routeInfo.etx;
+        return SUCCESS;
+    }
+
+    command void CtpInfo.recomputeRoutes() {
+      post updateRouteTask();
+    }
+
+    command void CtpInfo.triggerRouteUpdate() {
+      // Random time in interval 64-127ms
+      uint16_t time = call Random.rand16();
+      time &= 0x3f; 
+      time += 64;
+      if (call BeaconTimer.gett0() + call BeaconTimer.getdt() -
+                                     call BeaconTimer.getNow() >= time) {
+         call BeaconTimer.stop();
+         call BeaconTimer.startOneShot(time);
+        }
+     }
+
+    command void CtpInfo.triggerImmediateRouteUpdate() {
+      // Random time in interval 4-11ms
+      uint16_t time = call Random.rand16();
+      time &= 0x7; 
+      time += 4;
+      call BeaconTimer.stop();
+      call BeaconTimer.startOneShot(time);
+    }
+
+    command void CtpInfo.setNeighborCongested(am_addr_t n, bool congested) {
+        uint8_t idx;    
+        idx = routingTableFind(n);
+        if (idx < routingTableActive) {
+            routingTable[idx].info.congested = congested;
+        }
+        /* TODO:  (this only makes sense if routeUpdateTask takes congestion into
+         *         account for selecting routes.)
+         *   if (routeInfo.congested && !congested) 
+         *       post routeUpdateTask() 
+         *   else if (routeInfo.parent == n && congested) {
+         *       post routeUpdateTask()
+         *
+         */
+    }
+
+    command bool CtpInfo.isNeighborCongested(am_addr_t n) {
+        uint8_t idx;    
+
+        if (ECNOff) 
+            return FALSE;
+
+        idx = routingTableFind(n);
+        if (idx < routingTableActive) {
+            return routingTable[idx].info.congested;
+        }
+        return FALSE;
+    }
+    
+    /* RootControl interface */
+    /** sets the current node as a root, if not already a root */
+    /*  returns FAIL if it's not possible for some reason      */
+    command error_t RootControl.setRoot() {
+        bool route_found = FALSE;
+        route_found = (routeInfo.parent == INVALID_ADDR);
+        atomic {
+            state_is_root = 1;
+            routeInfo.parent = my_ll_addr; //myself
+            routeInfo.etx = 0;
+        }
+        if (route_found) 
+            signal Routing.routeFound();
+        dbg("TreeRouting","%s I'm a root now!\n",__FUNCTION__);
+        call CollectionDebug.logEventRoute(NET_C_TREE_NEW_PARENT, routeInfo.parent, 0, routeInfo.etx);
+        return SUCCESS;
+    }
+
+    command error_t RootControl.unsetRoot() {
+        atomic {
+            state_is_root = 0;
+            routeInfoInit(&routeInfo);
+        }
+        dbg("TreeRouting","%s I'm not a root now!\n",__FUNCTION__);
+        post updateRouteTask();
+        return SUCCESS;
+    }
+
+    command bool RootControl.isRoot() {
+        return state_is_root;
+    }
+
+    default event void Routing.noRoute() {
+    }
+    
+    default event void Routing.routeFound() {
+    }
+
+
+    /************************************************************/
+    /* Routing Table Functions                                  */
+
+    /* The routing table keeps info about neighbor's route_info,
+     * and is used when choosing a parent.
+     * The table is simple: 
+     *   - not fragmented (all entries in 0..routingTableActive)
+     *   - not ordered
+     *   - no replacement: eviction follows the LinkEstimator table
+     */
+
+    void routingTableInit() {
+        routingTableActive = 0;
+    }
+
+    /* Returns the index of parent in the table or
+     * routingTableActive if not found */
+    uint8_t routingTableFind(am_addr_t neighbor) {
+        uint8_t i;
+        if (neighbor == INVALID_ADDR)
+            return routingTableActive;
+        for (i = 0; i < routingTableActive; i++) {
+            if (routingTable[i].neighbor == neighbor)
+                break;
+        }
+        return i;
+    }
+
+
+    error_t routingTableUpdateEntry(am_addr_t from, am_addr_t parent, uint16_t etx)    {
+        uint8_t idx;
+        uint16_t  linkEtx;
+        linkEtx = evaluateEtx(call LinkEstimator.getLinkQuality(from));
+
+        idx = routingTableFind(from);
+        if (idx == routingTableSize) {
+            //not found and table is full
+            //if (passLinkEtxThreshold(linkEtx))
+                //TODO: add replacement here, replace the worst
+            //}
+            dbg("TreeRouting", "%s FAIL, table full\n", __FUNCTION__);
+            return FAIL;
+        }
+        else if (idx == routingTableActive) {
+            //not found and there is space
+            if (passLinkEtxThreshold(linkEtx)) {
+                atomic {
+                    routingTable[idx].neighbor = from;
+                    routingTable[idx].info.parent = parent;
+                    routingTable[idx].info.etx = etx;
+                   routingTable[idx].info.haveHeard = 1;
+                    routingTableActive++;
+                }
+                dbg("TreeRouting", "%s OK, new entry\n", __FUNCTION__);
+            } else {
+                dbg("TreeRouting", "%s Fail, link quality (%hu) below threshold\n", __FUNCTION__, linkEtx);
+            }
+        } else {
+            //found, just update
+            atomic {
+                routingTable[idx].neighbor = from;
+                routingTable[idx].info.parent = parent;
+                routingTable[idx].info.etx = etx;
+               routingTable[idx].info.haveHeard = 1;
+            }
+            dbg("TreeRouting", "%s OK, updated entry\n", __FUNCTION__);
+        }
+        return SUCCESS;
+    }
+
+    /* if this gets expensive, introduce indirection through an array of pointers */
+    error_t routingTableEvict(am_addr_t neighbor) {
+        uint8_t idx,i;
+        idx = routingTableFind(neighbor);
+        if (idx == routingTableActive) 
+            return FAIL;
+        routingTableActive--;
+        for (i = idx; i < routingTableActive; i++) {
+            routingTable[i] = routingTable[i+1];    
+        } 
+        return SUCCESS; 
+    }
+    /*********** end routing table functions ***************/
+
+    /* Default implementations for CollectionDebug calls.
+     * These allow CollectionDebug not to be wired to anything if debugging
+     * is not desired. */
+
+    default command error_t CollectionDebug.logEvent(uint8_t type) {
+        return SUCCESS;
+    }
+    default command error_t CollectionDebug.logEventSimple(uint8_t type, uint16_t arg) {
+        return SUCCESS;
+    }
+    default command error_t CollectionDebug.logEventDbg(uint8_t type, uint16_t arg1, uint16_t arg2, uint16_t arg3) {
+        return SUCCESS;
+    }
+    default command error_t CollectionDebug.logEventMsg(uint8_t type, uint16_t msg, am_addr_t origin, am_addr_t node) {
+        return SUCCESS;
+    }
+    default command error_t CollectionDebug.logEventRoute(uint8_t type, am_addr_t parent, uint8_t hopcount, uint16_t etx) {
+        return SUCCESS;
+    }
+
+    command bool CtpRoutingPacket.getOption(message_t* msg, ctp_options_t opt) {
+      return ((getHeader(msg)->options & opt) == opt) ? TRUE : FALSE;
+    }
+
+    command void CtpRoutingPacket.setOption(message_t* msg, ctp_options_t opt) {
+      getHeader(msg)->options |= opt;
+    }
+
+    command void CtpRoutingPacket.clearOption(message_t* msg, ctp_options_t opt) {
+      getHeader(msg)->options &= ~opt;
+    }
+
+    command void CtpRoutingPacket.clearOptions(message_t* msg) {
+      getHeader(msg)->options = 0;
+    }
+
+    
+    command am_addr_t     CtpRoutingPacket.getParent(message_t* msg) {
+      return getHeader(msg)->parent;
+    }
+    command void          CtpRoutingPacket.setParent(message_t* msg, am_addr_t addr) {
+      getHeader(msg)->parent = addr;
+    }
+    
+    command uint16_t      CtpRoutingPacket.getEtx(message_t* msg) {
+      return getHeader(msg)->etx;
+    }
+    command void          CtpRoutingPacket.setEtx(message_t* msg, uint8_t etx) {
+      getHeader(msg)->etx = etx;
+    }
+
+    command uint8_t CtpInfo.numNeighbors() {
+      return routingTableActive;
+    }
+    command uint16_t CtpInfo.getNeighborLinkQuality(uint8_t n) {
+      return (n < routingTableActive)? call LinkEstimator.getLinkQuality(routingTable[n].neighbor):0xffff;
+    }
+    command uint16_t CtpInfo.getNeighborRouteQuality(uint8_t n) {
+      return (n < routingTableActive)? call LinkEstimator.getLinkQuality(routingTable[n].neighbor) + routingTable[n].info.etx:0xfffff;
+    }
+    command am_addr_t CtpInfo.getNeighborAddr(uint8_t n) {
+      return (n < routingTableActive)? routingTable[n].neighbor:AM_BROADCAST_ADDR;
+    }
+    
+} 
diff --git a/tos/lib/net/ctp/CtpRoutingPacket.nc b/tos/lib/net/ctp/CtpRoutingPacket.nc
new file mode 100644 (file)
index 0000000..5fa376c
--- /dev/null
@@ -0,0 +1,58 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ *  ADT for CTP routing frames.
+ *
+ *  @author Philip Levis
+ *  @author Kyle Jamieson
+ *  @date   $Date$
+ */
+
+#include <AM.h>
+   
+interface CtpRoutingPacket {
+
+  /* Allow individual options to be read, set, and reset independently */
+  command bool          getOption(message_t* msg, ctp_options_t opt);
+  command void          setOption(message_t* msg, ctp_options_t opt);
+  command void          clearOption(message_t* msg, ctp_options_t opt);
+  
+  /* Clear all options */
+  command void          clearOptions(message_t* msg);
+
+  command am_addr_t     getParent(message_t* msg);
+  command void          setParent(message_t* msg, am_addr_t addr);
+
+  command uint16_t      getEtx(message_t* msg);
+  command void          setEtx(message_t* msg, uint8_t etx);
+}
diff --git a/tos/lib/net/ctp/CtpSenderC.nc b/tos/lib/net/ctp/CtpSenderC.nc
new file mode 100644 (file)
index 0000000..7a0eea3
--- /dev/null
@@ -0,0 +1,58 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2006 Massachusetts Institute of Technology (MIT).
+ * 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 Massachusetts Institute of Technology 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
+ * MASSACHUSETTS INSITIUTE OF TECHNOLOGY OR ITS CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+/**
+ * The virtualized collection sender abstraction.
+ *
+ * @author Kyle Jamieson
+ * @author Philip Levis
+ * @date April 25 2006
+ * @see TinyOS Net2-WG
+ */
+
+#include "Collection.h"
+#include "Ctp.h"
+
+generic configuration CtpSenderC(collection_id_t collectid) {
+  provides {
+    interface Send;
+    interface Packet;
+  }
+}
+
+implementation {
+  components new CtpSenderP(collectid, unique(UQ_CTP_CLIENT));
+  Send = CtpSenderP;
+  Packet = CtpSenderP;
+}
diff --git a/tos/lib/net/ctp/CtpSenderP.nc b/tos/lib/net/ctp/CtpSenderP.nc
new file mode 100644 (file)
index 0000000..293bc90
--- /dev/null
@@ -0,0 +1,51 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2006 Massachusetts Institute of Technology (MIT).
+ * 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 Massachusetts Institute of Technology 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
+ * MASSACHUSETTS INSITIUTE OF TECHNOLOGY OR ITS CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+#include "Collection.h"
+
+generic configuration CtpSenderP(collection_id_t collectid, uint8_t clientid) {
+  provides {
+    interface Send;
+    interface Packet;
+  }
+}
+
+implementation {
+  components CtpC as Collector;
+  components new CollectionIdP(collectid);
+  
+  Send = Collector.Send[clientid];
+  Packet = Collector.Packet;
+  Collector.CollectionId[clientid] -> CollectionIdP;
+}
diff --git a/tos/lib/net/ctp/LruCtpMsgCacheC.nc b/tos/lib/net/ctp/LruCtpMsgCacheC.nc
new file mode 100644 (file)
index 0000000..f1f3106
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+  * An LRU cache CTP packet instances, where insertion represents use.
+  *
+  * @author Philip Levis
+  */
+
+generic configuration LruCtpMsgCacheC(uint8_t CACHE_SIZE) {
+    provides interface Cache<message_t*>;
+}
+implementation {
+    components MainC, new LruCtpMsgCacheP(CACHE_SIZE) as CacheP;
+    components CtpP;
+    Cache = CacheP;
+    CacheP.CtpPacket -> CtpP;
+    MainC.SoftwareInit -> CacheP;
+}
diff --git a/tos/lib/net/ctp/LruCtpMsgCacheP.nc b/tos/lib/net/ctp/LruCtpMsgCacheP.nc
new file mode 100644 (file)
index 0000000..b4fd829
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2006 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the
+ *   distribution.
+ * - Neither the name of the Stanford University nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * An LRU cache that stores the signature of a CTP packet instance.
+ * An insert operation indicates "use".  Inserting an element not in
+ * the cache will replace the oldest, and inserting an element already
+ * in the cache will refresh its age.
+ *
+ * @author Philip Levis 
+ */
+
+#include <message.h>
+
+generic module LruCtpMsgCacheP(uint8_t size) {
+    provides {
+      interface Init;
+      interface Cache<message_t*>;
+    }
+    uses {
+      interface CtpPacket;
+    }
+}
+implementation {
+  typedef struct {
+    am_addr_t origin;
+    uint8_t seqno;
+    collection_id_t type;
+    uint8_t thl;
+  } ctp_packet_sig_t;
+  
+  ctp_packet_sig_t cache[size];
+  uint8_t first;
+  uint8_t count;
+
+  command error_t Init.init() {
+    first = 0;
+    count = 0;
+    return SUCCESS;
+  } 
+
+  void printCache() {
+#ifdef TOSSIM
+    int i;
+    dbg("Cache","Cache:");
+    for (i = 0; i < count; i++) {
+      dbg_clear("Cache", " %04x %02x %02x %02x", cache[i].origin, cache[i].seqno, cache[i].type, cache[i].thl);
+      if (i == first)
+       dbg_clear("Cache","*");
+    } 
+    dbg_clear("Cache","\n");
+#endif
+    }
+
+    /* if key is in cache returns the index (offset by first), otherwise returns count */
+  uint8_t lookup(message_t* m) {
+    uint8_t i;
+    uint8_t idx;
+    for (i = 0; i < count; i++) {
+      idx = (i + first) % size;
+      if (call CtpPacket.getOrigin(m)         == cache[idx].origin &&
+         call CtpPacket.getSequenceNumber(m) == cache[idx].seqno &&
+         call CtpPacket.getThl(m)            == cache[idx].thl &&
+         call CtpPacket.getType(m)           == cache[idx].type) {
+       break;
+      }
+    }
+    return i;
+  }
+  
+  /* remove the entry with index i (relative to first) */
+    void remove(uint8_t i) {
+        uint8_t j;
+        if (i >= count) 
+            return;
+        if (i == 0) {
+            //shift all by moving first
+            first = (first + 1) % size;
+        } else {
+            //shift everyone down
+            for (j = i; j < count; j++) {
+             memcpy(&cache[(j + first) % size], &cache[(j + first + 1) % size], sizeof(ctp_packet_sig_t));
+           }
+        }
+        count--;
+    }
+
+    command void Cache.insert(message_t* m) {
+        uint8_t i;
+        if (count == size ) {
+            //remove someone. If item not in 
+            //cache, remove the first item.
+            //otherwise remove the item temporarily for
+            //reinsertion. This moves the item up in the
+            //LRU stack.
+         i = lookup(m);
+         remove(i % count);
+        }
+        //now count < size
+        cache[(first + count) % size].origin = call CtpPacket.getOrigin(m);
+       cache[(first + count) % size].seqno  = call CtpPacket.getSequenceNumber(m);
+       cache[(first + count) % size].thl    = call CtpPacket.getThl(m);
+       cache[(first + count) % size].type   = call CtpPacket.getType(m);
+        count++;
+    }
+
+    command bool Cache.lookup(message_t* m) {
+        return (lookup(m) < count);
+    }
+
+    command void Cache.flush() {
+      call Init.init(); 
+    }
+
+}
diff --git a/tos/lib/net/ctp/TreeRouting.h b/tos/lib/net/ctp/TreeRouting.h
new file mode 100644 (file)
index 0000000..66b44d7
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _TREE_ROUTING_H
+#define _TREE_ROUTING_H
+
+enum {
+    AM_TREE_ROUTING_CONTROL = 0xCE,
+    BEACON_INTERVAL = 8192, 
+    INVALID_ADDR  = TOS_BCAST_ADDR,
+    ETX_THRESHOLD = 50,      // link quality=20% -> ETX=5 -> Metric=50 
+    PARENT_SWITCH_THRESHOLD = 15,
+    MAX_METRIC = 0xFFFF,
+}; 
+
+typedef struct {
+  am_addr_t parent;
+  uint16_t etx;
+  bool haveHeard;
+  bool congested;
+} route_info_t;
+
+typedef struct {
+  am_addr_t neighbor;
+  route_info_t info;
+} routing_table_entry;
+
+inline void routeInfoInit(route_info_t *ri) {
+    ri->parent = INVALID_ADDR;
+    ri->etx = 0;
+    ri->haveHeard = 0;
+    ri->congested = FALSE;
+}
+
+#endif
diff --git a/tos/lib/net/le/LinkEstimator.h b/tos/lib/net/le/LinkEstimator.h
new file mode 100644 (file)
index 0000000..3e7394a
--- /dev/null
@@ -0,0 +1,121 @@
+/* $Id$ */
+/*
+ * "Copyright (c) 2006 University of Southern California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the following two paragraphs and the author appear in all
+ * copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF SOUTHERN CALIFORNIA BE LIABLE TO
+ * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+ * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+ * DOCUMENTATION, EVEN IF THE UNIVERSITY OF SOUTHERN CALIFORNIA HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF SOUTHERN CALIFORNIA SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+ * SOUTHERN CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
+ * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+#ifndef LINK_ESITIMATOR_H
+#define LINK_ESITIMATOR_H
+/*
+ @ author Omprakash Gnawali
+ @ Created: June 08, 2006
+ */
+
+// Number of entries in the neighbor table
+#define NEIGHBOR_TABLE_SIZE 10
+
+// Masks for the flag field in the link estimation header
+enum {
+  // use last four bits to keep track of
+  // how many footer entries there are
+  NUM_ENTRIES_FLAG = 15,
+};
+
+// The first byte of each outgoing packet is a control byte
+// Bits 4..7 reserved for routing and other protocols
+// Bits 0..3 is used by the link estimator to encode the
+//   number of linkest entries in the packet
+
+// link estimator header added to
+// every message passing through the link estimator
+typedef nx_struct linkest_header {
+  nx_uint8_t flags;
+  nx_uint8_t seq;
+} linkest_header_t;
+
+
+// for outgoing link estimator message
+// so that we can compute bi-directional quality
+typedef nx_struct neighbor_stat_entry {
+  nx_am_addr_t ll_addr;
+  nx_uint8_t inquality;
+} neighbor_stat_entry_t;
+
+// we put the above neighbor entry in the footer
+typedef nx_struct linkest_footer {
+  neighbor_stat_entry_t neighborList[1];
+} linkest_footer_t;
+
+
+// Flags for the neighbor table entry
+enum {
+  VALID_ENTRY = 0x1, 
+  // A link becomes mature after BLQ_PKT_WINDOW
+  // packets are received and an estimate is computed
+  MATURE_ENTRY = 0x2,
+  // Flag to indicate that this link has received the
+  // first sequence number
+  INIT_ENTRY = 0x4,
+  // The upper layer has requested that this link be pinned
+  // Useful if we don't want to lose the root from the table
+  PINNED_ENTRY = 0x8
+};
+
+
+// neighbor table entry
+typedef struct neighbor_table_entry {
+  // link layer address of the neighbor
+  am_addr_t ll_addr;
+  // last beacon sequence number received from this neighbor
+  uint8_t lastseq;
+  // number of beacons received after last beacon estimator update
+  // the update happens every BLQ_PKT_WINDOW beacon packets
+  uint8_t rcvcnt;
+  // number of beacon packets missed after last beacon estimator update
+  uint8_t failcnt;
+  // flags to describe the state of this entry
+  uint8_t flags;
+  // MAXAGE-inage gives the number of update rounds we haven't been able
+  // update the inbound beacon estimator
+  uint8_t inage;
+  // MAXAGE-outage gives the number of update rounds we haven't received
+  // the outbound link quality
+  uint8_t outage;
+  // inbound and outbound link qualities in the range [1..255]
+  // 1 bad, 255 good
+  uint8_t inquality;
+  uint8_t outquality;
+  // EETX for the link to this neighbor. This is the quality returned to
+  // the users of the link estimator
+  uint16_t eetx;
+  // Number of data packets successfully sent (ack'd) to this neighbor
+  // since the last data estimator update round. This update happens
+  // every DLQ_PKT_WINDOW data packets
+  uint8_t data_success;
+  // The total number of data packets transmission attempt to this neighbor
+  // since the last data estimator update round.
+  uint8_t data_total;
+} neighbor_table_entry_t;
+
+
+#endif
diff --git a/tos/lib/net/le/LinkEstimator.nc b/tos/lib/net/le/LinkEstimator.nc
new file mode 100644 (file)
index 0000000..8e7a5df
--- /dev/null
@@ -0,0 +1,70 @@
+/* $Id$ */
+/*
+ * "Copyright (c) 2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/** Provides an additive quality measure for a neighbor. The
+ * provided quality increases when the true link quality increases.
+ *  @author Rodrigo Fonseca
+ *  @author Omprakash Gnawali
+ *  @date   $Date$
+ */
+
+/* Quality of a link is defined by the implementor of this interface.
+ * It could be ETX, PRR, etc.
+ */
+
+interface LinkEstimator {
+  
+  /* get bi-directional link quality for link to the neighbor */
+  command uint8_t getLinkQuality(uint16_t neighbor);
+
+  /* get quality of the link from neighbor to this node */
+  command uint8_t getReverseQuality(uint16_t neighbor);
+
+  /* get quality of the link from this node to the neighbor */
+  command uint8_t getForwardQuality(uint16_t neighbor);
+
+  /* insert this neighbor into the neighbor table */
+  command error_t insertNeighbor(am_addr_t neighbor);
+
+  /* pin a neighbor so that it does not get evicted */
+  command error_t pinNeighbor(am_addr_t neighbor);
+
+  /* pin a neighbor so that it does not get evicted */
+  command error_t unpinNeighbor(am_addr_t neighbor);
+
+  /* called when an acknowledgement is received; sign of a successful
+     data transmission; to update forward link quality */
+  command error_t txAck(am_addr_t neighbor);
+
+  /* called when an acknowledgement is not received; could be due to
+     data pkt or acknowledgement loss; to update forward link quality */
+  command error_t txNoAck(am_addr_t neighbor);
+
+  /* called when the parent changes; clear state about data-driven link quality  */
+  command error_t clearDLQ(am_addr_t neighbor);
+
+  /* signal when this neighbor is evicted from the neighbor table */
+  event void evicted(am_addr_t neighbor);
+}
+
+
diff --git a/tos/lib/net/le/LinkEstimatorC.nc b/tos/lib/net/le/LinkEstimatorC.nc
new file mode 100644 (file)
index 0000000..0aecace
--- /dev/null
@@ -0,0 +1,34 @@
+/* $Id$ */
+/*
+ * "Copyright (c) 2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/** The public component of the link estimator that provides the
+ * quality to and from a neighbor 
+ * 
+ *  @author Rodrigo Fonseca
+ *  @date   $Date$
+ */
+configuration LinkEstimatorC {
+    provides {
+        interface LinkEstimator;
+    }
+}
diff --git a/tos/lib/net/le/LinkEstimatorDummyP.nc b/tos/lib/net/le/LinkEstimatorDummyP.nc
new file mode 100644 (file)
index 0000000..2cc6de1
--- /dev/null
@@ -0,0 +1,175 @@
+/* $Id$ */
+/*
+ * "Copyright (c) 2006 University of Southern California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the following two paragraphs and the author appear in all
+ * copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF SOUTHERN CALIFORNIA BE LIABLE TO
+ * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+ * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+ * DOCUMENTATION, EVEN IF THE UNIVERSITY OF SOUTHERN CALIFORNIA HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF SOUTHERN CALIFORNIA SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+ * SOUTHERN CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
+ * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/*
+ @ author Omprakash Gnawali
+ @ Created: April 24, 2006
+ */
+
+
+#include "Timer.h"
+
+module LinkEstimatorDummyP {
+  provides {
+    interface AMSend as Send;
+    interface Receive;
+    interface LinkEstimator;
+    interface Init;
+    interface Packet;
+    interface LinkSrcPacket;
+  }
+
+  uses {
+    interface AMSend;
+    interface AMPacket as SubAMPacket;
+    interface Packet as SubPacket;
+    interface Receive as SubReceive;
+    interface Timer<TMilli>;
+  }
+}
+
+implementation {
+
+  // link estimator header added to
+  // every message passing thru' the link estimator
+  typedef nx_struct linkest_header {
+    nx_am_addr_t ll_addr;
+  } linkest_header_t;
+
+  linkest_header_t* getHeader(message_t* m) {
+    return (linkest_header_t*)call SubPacket.getPayload(m, NULL);
+  }
+
+
+  uint8_t addLinkEstHeaderAndFooter(message_t *msg, uint8_t len) {
+    uint8_t newlen;
+    linkest_header_t *hdr;
+    dbg("LI", "newlen1 = %d\n", len);
+    newlen = len + sizeof(linkest_header_t);
+    call Packet.setPayloadLength(msg, newlen);
+    hdr = getHeader(msg);
+
+    hdr->ll_addr = call SubAMPacket.address();
+    dbg("LI", "newlen2 = %d\n", newlen);
+    return newlen;
+  }
+
+  command error_t Init.init() {
+    return SUCCESS;
+  }
+
+  event void Timer.fired() { }
+
+  // EETX (Extra Expected number of Transmission)
+  // EETX = ETX - 1
+  // computeEETX returns EETX*10
+
+  command uint8_t LinkEstimator.getLinkQuality(uint16_t neighbor) {
+    return 2;
+  }
+
+  command uint8_t LinkEstimator.getReverseQuality(uint16_t neighbor) {
+    return 1;
+  }
+
+  command uint8_t LinkEstimator.getForwardQuality(uint16_t neighbor) {
+    return 1;
+  }
+
+  command am_addr_t LinkSrcPacket.getSrc(message_t* msg) {
+    linkest_header_t* hdr = getHeader(msg);
+    return hdr->ll_addr;
+  }
+
+  command error_t Send.send(am_addr_t addr, message_t* msg, uint8_t len) {
+    uint8_t newlen;
+    newlen = addLinkEstHeaderAndFooter(msg, len);
+    return call AMSend.send(addr, msg, newlen);
+  }
+
+  event void AMSend.sendDone(message_t* msg, error_t error ) {
+    return signal Send.sendDone(msg, error);
+  }
+
+  command uint8_t Send.cancel(message_t* msg) {
+    return call AMSend.cancel(msg);
+  }
+
+  command uint8_t Send.maxPayloadLength() {
+    return call Packet.maxPayloadLength();
+  }
+
+  command void* Send.getPayload(message_t* msg) {
+    return call Packet.getPayload(msg, NULL);
+  }
+
+  event message_t* SubReceive.receive(message_t* msg,
+                                     void* payload,
+                                     uint8_t len) {
+    if (call SubAMPacket.destination(msg) == AM_BROADCAST_ADDR) {
+      linkest_header_t* hdr = getHeader(msg);
+      dbg("LI", "Got pkt from link: %d\n", hdr->ll_addr);
+    }
+    
+    return signal Receive.receive(msg,
+                                 call Packet.getPayload(msg, NULL),
+                                 call Packet.payloadLength(msg));
+  }
+
+  command void* Receive.getPayload(message_t* msg, uint8_t* len) {
+    return call Packet.getPayload(msg, len);
+  }
+
+  command uint8_t Receive.payloadLength(message_t* msg) {
+    return call Packet.payloadLength(msg);
+  }
+
+  command void Packet.clear(message_t* msg) {
+    call SubPacket.clear(msg);
+  }
+
+  command uint8_t Packet.payloadLength(message_t* msg) {
+    return call SubPacket.payloadLength(msg) - sizeof(linkest_header_t);
+  }
+
+  command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
+    call SubPacket.setPayloadLength(msg, len + sizeof(linkest_header_t));
+  }
+
+  command uint8_t Packet.maxPayloadLength() {
+    return call SubPacket.maxPayloadLength() - sizeof(linkest_header_t);
+  }
+
+  command void* Packet.getPayload(message_t* msg, uint8_t* len) {
+    uint8_t* payload = call SubPacket.getPayload(msg, len);
+    if (len != NULL) {
+      *len -= sizeof(linkest_header_t);
+    }
+    return payload + sizeof(linkest_header_t);
+  }
+
+}
+
diff --git a/tos/lib/net/le/LinkEstimatorP.nc b/tos/lib/net/le/LinkEstimatorP.nc
new file mode 100644 (file)
index 0000000..2fee9a1
--- /dev/null
@@ -0,0 +1,741 @@
+/* $Id$ */
+/*
+ * "Copyright (c) 2006 University of Southern California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the following two paragraphs and the author appear in all
+ * copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF SOUTHERN CALIFORNIA BE LIABLE TO
+ * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+ * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+ * DOCUMENTATION, EVEN IF THE UNIVERSITY OF SOUTHERN CALIFORNIA HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF SOUTHERN CALIFORNIA SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+ * SOUTHERN CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
+ * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/*
+ @ author Omprakash Gnawali
+ @ Created: April 24, 2006
+ */
+
+#include "LinkEstimator.h"
+
+module LinkEstimatorP {
+  provides {
+    interface StdControl;
+    interface AMSend as Send;
+    interface Receive;
+    interface LinkEstimator;
+    interface Init;
+    interface Packet;
+    interface LinkSrcPacket;
+  }
+
+  uses {
+    interface AMSend;
+    interface AMPacket as SubAMPacket;
+    interface Packet as SubPacket;
+    interface Receive as SubReceive;
+  }
+}
+
+implementation {
+
+  // configure the link estimator and some constants
+  enum {
+    // If the eetx estimate is below this threshold
+    // do not evict a link
+    EVICT_EETX_THRESHOLD = 55,
+    // maximum link update rounds before we expire the link
+    MAX_AGE = 6,
+    // if received sequence number if larger than the last sequence
+    // number by this gap, we reinitialize the link
+    MAX_PKT_GAP = 10,
+    BEST_EETX = 0,
+    INVALID_RVAL = 0xff,
+    INVALID_NEIGHBOR_ADDR = 0xff,
+    INFINITY = 0xff,
+    // decay the link estimate using this alpha
+    // we use a denominator of 10, so this corresponds to 0.2
+    ALPHA = 2,
+    // number of packets to wait before computing a new
+    // DLQ (Data-driven Link Quality)
+    DLQ_PKT_WINDOW = 5,
+    // number of beacons to wait before computing a new
+    // BLQ (Beacon-driven Link Quality)
+    BLQ_PKT_WINDOW = 3,
+    // largest EETX value that we feed into the link quality EWMA
+    // a value of 60 corresponds to having to make six transmissions
+    // to successfully receive one acknowledgement
+    LARGE_EETX_VALUE = 60
+  };
+
+  // keep information about links from the neighbors
+  neighbor_table_entry_t NeighborTable[NEIGHBOR_TABLE_SIZE];
+  // link estimation sequence, increment every time a beacon is sent
+  uint8_t linkEstSeq = 0;
+  // if there is not enough room in the packet to put all the neighbor table
+  // entries, in order to do round robin we need to remember which entry
+  // we sent in the last beacon
+  uint8_t prevSentIdx = 0;
+
+  // get the link estimation header in the packet
+  linkest_header_t* getHeader(message_t* m) {
+    return (linkest_header_t*)call SubPacket.getPayload(m, NULL);
+  }
+
+  // get the link estimation footer (neighbor entries) in the packet
+  linkest_footer_t* getFooter(message_t* m, uint8_t len) {
+    return (linkest_footer_t*)(len + (uint8_t *)call Packet.getPayload(m,NULL));
+  }
+
+  // add the link estimation header (seq no) and link estimation
+  // footer (neighbor entries) in the packet. Call just before sending
+  // the packet.
+  uint8_t addLinkEstHeaderAndFooter(message_t *msg, uint8_t len) {
+    uint8_t newlen;
+    linkest_header_t *hdr;
+    linkest_footer_t *footer;
+    uint8_t i, j, k;
+    uint8_t maxEntries, newPrevSentIdx;
+    dbg("LI", "newlen1 = %d\n", len);
+    hdr = getHeader(msg);
+    footer = getFooter(msg, len);
+
+    maxEntries = ((call SubPacket.maxPayloadLength() - len - sizeof(linkest_header_t))
+                 / sizeof(linkest_footer_t));
+
+    // Depending on the number of bits used to store the number
+    // of entries, we can encode up to NUM_ENTRIES_FLAG using those bits
+    if (maxEntries > NUM_ENTRIES_FLAG) {
+      maxEntries = NUM_ENTRIES_FLAG;
+    }
+    dbg("LI", "Max payload is: %d, maxEntries is: %d\n", call SubPacket.maxPayloadLength(), maxEntries);
+
+    j = 0;
+    newPrevSentIdx = 0;
+    for (i = 0; i < NEIGHBOR_TABLE_SIZE && j < maxEntries; i++) {
+      k = (prevSentIdx + i + 1) % NEIGHBOR_TABLE_SIZE;
+      if (NeighborTable[k].flags & VALID_ENTRY) {
+       footer->neighborList[j].ll_addr = NeighborTable[k].ll_addr;
+       footer->neighborList[j].inquality = NeighborTable[k].inquality;
+       newPrevSentIdx = k;
+       dbg("LI", "Loaded on footer: %d %d %d\n", j, footer->neighborList[j].ll_addr,
+           footer->neighborList[j].inquality);
+       j++;
+      }
+    }
+    prevSentIdx = newPrevSentIdx;
+
+    hdr->seq = linkEstSeq++;
+    hdr->flags = 0;
+    hdr->flags |= (NUM_ENTRIES_FLAG & j);
+    newlen = sizeof(linkest_header_t) + len + j*sizeof(linkest_footer_t);
+    dbg("LI", "newlen2 = %d\n", newlen);
+    return newlen;
+  }
+
+
+  // initialize the given entry in the table for neighbor ll_addr
+  void initNeighborIdx(uint8_t i, am_addr_t ll_addr) {
+    neighbor_table_entry_t *ne;
+    ne = &NeighborTable[i];
+    ne->ll_addr = ll_addr;
+    ne->lastseq = 0;
+    ne->rcvcnt = 0;
+    ne->failcnt = 0;
+    ne->flags = (INIT_ENTRY | VALID_ENTRY);
+    ne->inage = MAX_AGE;
+    ne->outage = MAX_AGE;
+    ne->inquality = 0;
+    ne->outquality = 0;
+    ne->eetx = 0;
+  }
+
+  // find the index to the entry for neighbor ll_addr
+  uint8_t findIdx(am_addr_t ll_addr) {
+    uint8_t i;
+    for (i = 0; i < NEIGHBOR_TABLE_SIZE; i++) {
+      if (NeighborTable[i].flags & VALID_ENTRY) {
+       if (NeighborTable[i].ll_addr == ll_addr) {
+         return i;
+       }
+      }
+    }
+    return INVALID_RVAL;
+  }
+
+  // find an empty slot in the neighbor table
+  uint8_t findEmptyNeighborIdx() {
+    uint8_t i;
+    for (i = 0; i < NEIGHBOR_TABLE_SIZE; i++) {
+      if (NeighborTable[i].flags & VALID_ENTRY) {
+      } else {
+       return i;
+      }
+    }
+      return INVALID_RVAL;
+  }
+
+  // find the index to the worst neighbor if the eetx
+  // estimate is greater than the given threshold
+  uint8_t findWorstNeighborIdx(uint8_t thresholdEETX) {
+    uint8_t i, worstNeighborIdx;
+    uint16_t worstEETX, thisEETX;
+
+    worstNeighborIdx = INVALID_RVAL;
+    worstEETX = 0;
+    for (i = 0; i < NEIGHBOR_TABLE_SIZE; i++) {
+      if (!(NeighborTable[i].flags & VALID_ENTRY)) {
+       dbg("LI", "Invalid so continuing\n");
+       continue;
+      }
+      if (!(NeighborTable[i].flags & MATURE_ENTRY)) {
+       dbg("LI", "Not mature, so continuing\n");
+       continue;
+      }
+      if (NeighborTable[i].flags & PINNED_ENTRY) {
+       dbg("LI", "Pinned entry, so continuing\n");
+       continue;
+      }
+      thisEETX = NeighborTable[i].eetx;
+      if (thisEETX >= worstEETX) {
+       worstNeighborIdx = i;
+       worstEETX = thisEETX;
+      }
+    }
+    if (worstEETX >= thresholdEETX) {
+      return worstNeighborIdx;
+    } else {
+      return INVALID_RVAL;
+    }
+  }
+
+  // update the quality of the link link: self->neighbor
+  // this is found in the entries in the footer of incoming message
+  void updateReverseQuality(am_addr_t neighbor, uint8_t outquality) {
+    uint8_t idx;
+    idx = findIdx(neighbor);
+    if (idx != INVALID_RVAL) {
+      NeighborTable[idx].outquality = outquality;
+      NeighborTable[idx].outage = MAX_AGE;
+    }
+  }
+
+  // update the EETX estimator
+  // called when new beacon estimate is done
+  // also called when new DEETX estimate is done
+  void updateEETX(neighbor_table_entry_t *ne, uint16_t newEst) {
+    ne->eetx = (ALPHA * ne->eetx + (10 - ALPHA) * newEst)/10;
+  }
+
+
+  // update data driven EETX
+  void updateDEETX(neighbor_table_entry_t *ne) {
+    uint16_t estETX;
+
+    if (ne->data_success == 0) {
+      // if there were no successful packet transmission in the
+      // last window, assign a large EETX estimate
+      estETX = LARGE_EETX_VALUE;
+    } else {
+      estETX = (10 * ne->data_total) / ne->data_success - 10;
+    }
+    updateEETX(ne, estETX);
+    ne->data_success = 0;
+    ne->data_total = 0;
+  }
+
+
+  // EETX (Extra Expected number of Transmission)
+  // EETX = ETX - 1
+  // computeEETX returns EETX*10
+  uint8_t computeEETX(uint8_t q1) {
+    uint16_t q;
+    if (q1 > 0) {
+      q =  2550 / q1 - 10;
+      if (q > 255) {
+       q = INFINITY;
+      }
+      return (uint8_t)q;
+    } else {
+      return INFINITY;
+    }
+  }
+
+  // BidirETX = 1 / (q1*q2)
+  // BidirEETX = BidirETX - 1
+  // computeBidirEETX return BidirEETX*10
+  uint8_t computeBidirEETX(uint8_t q1, uint8_t q2) {
+    uint16_t q;
+    if ((q1 > 0) && (q2 > 0)) {
+      q =  65025u / q1;
+      q = (10*q) / q2 - 10;
+      if (q > 255) {
+       q = LARGE_EETX_VALUE;
+      }
+      return (uint8_t)q;
+    } else {
+      return LARGE_EETX_VALUE;
+    }
+  }
+
+  // update the inbound link quality by
+  // munging receive, fail count since last update
+  void updateNeighborTableEst(am_addr_t n) {
+    uint8_t i, totalPkt;
+    neighbor_table_entry_t *ne;
+    uint8_t newEst;
+    uint8_t minPkt;
+
+    minPkt = BLQ_PKT_WINDOW;
+    dbg("LI", "%s\n", __FUNCTION__);
+    for (i = 0; i < NEIGHBOR_TABLE_SIZE; i++) {
+      ne = &NeighborTable[i];
+      if (ne->ll_addr == n) {
+       if (ne->flags & VALID_ENTRY) {
+         if (ne->inage > 0)
+           ne->inage--;
+         if (ne->outage > 0)
+           ne->outage--;
+         
+         if ((ne->inage == 0) && (ne->outage == 0)) {
+           ne->flags ^= VALID_ENTRY;
+           ne->inquality = ne->outquality = 0;
+         } else {
+           dbg("LI", "Making link: %d mature\n", i);
+           ne->flags |= MATURE_ENTRY;
+           totalPkt = ne->rcvcnt + ne->failcnt;
+           dbg("LI", "MinPkt: %d, totalPkt: %d\n", minPkt, totalPkt);
+           if (totalPkt < minPkt) {
+             totalPkt = minPkt;
+           }
+           if (totalPkt == 0) {
+             ne->inquality = (ALPHA * ne->inquality) / 10;
+           } else {
+             newEst = (255 * ne->rcvcnt) / totalPkt;
+             dbg("LI,LITest", "  %hu: %hhu -> %hhu", ne->ll_addr, ne->inquality, (ALPHA * ne->inquality + (10-ALPHA) * newEst)/10);
+             ne->inquality = (ALPHA * ne->inquality + (10-ALPHA) * newEst)/10;
+           }
+           ne->rcvcnt = 0;
+           ne->failcnt = 0;
+         }
+         updateEETX(ne, computeBidirEETX(ne->inquality, ne->outquality));
+       }
+       else {
+         dbg("LI", " - entry %i is invalid.\n", (int)i);
+       }
+      }
+    }
+  }
+
+
+  // we received seq from the neighbor in idx
+  // update the last seen seq, receive and fail count
+  // refresh the age
+  void updateNeighborEntryIdx(uint8_t idx, uint8_t seq) {
+    uint8_t packetGap;
+
+    if (NeighborTable[idx].flags & INIT_ENTRY) {
+      dbg("LI", "Init entry update\n");
+      NeighborTable[idx].lastseq = seq;
+      NeighborTable[idx].flags &= ~INIT_ENTRY;
+    }
+    
+    packetGap = seq - NeighborTable[idx].lastseq;
+    dbg("LI", "updateNeighborEntryIdx: prevseq %d, curseq %d, gap %d\n",
+       NeighborTable[idx].lastseq, seq, packetGap);
+    NeighborTable[idx].lastseq = seq;
+    NeighborTable[idx].rcvcnt++;
+    NeighborTable[idx].inage = MAX_AGE;
+    if (packetGap > 0) {
+      NeighborTable[idx].failcnt += packetGap - 1;
+    }
+    if (packetGap > MAX_PKT_GAP) {
+      NeighborTable[idx].failcnt = 0;
+      NeighborTable[idx].rcvcnt = 1;
+      NeighborTable[idx].outage = 0;
+      NeighborTable[idx].outquality = 0;
+      NeighborTable[idx].inquality = 0;
+    }
+
+    if (NeighborTable[idx].rcvcnt >= BLQ_PKT_WINDOW) {
+      updateNeighborTableEst(NeighborTable[idx].ll_addr);
+    }
+
+  }
+
+
+
+  // print the neighbor table. for debugging.
+  void print_neighbor_table() {
+    uint8_t i;
+    neighbor_table_entry_t *ne;
+    for (i = 0; i < NEIGHBOR_TABLE_SIZE; i++) {
+      ne = &NeighborTable[i];
+      if (ne->flags & VALID_ENTRY) {
+       dbg("LI,LITest", "%d:%d inQ=%d, inA=%d, outQ=%d, outA=%d, rcv=%d, fail=%d, biQ=%d\n",
+           i, ne->ll_addr, ne->inquality, ne->inage, ne->outquality, ne->outage,
+           ne->rcvcnt, ne->failcnt, computeBidirEETX(ne->inquality, ne->outquality));
+      }
+    }
+  }
+
+  // print the packet. for debugging.
+  void print_packet(message_t* msg, uint8_t len) {
+    uint8_t i;
+    uint8_t* b;
+
+    b = (uint8_t *)msg->data;
+    for(i=0; i<len; i++)
+      dbg_clear("LI", "%x ", b[i]);
+    dbg_clear("LI", "\n");
+  }
+
+  // initialize the neighbor table in the very beginning
+  void initNeighborTable() {
+    uint8_t i;
+
+    for (i = 0; i < NEIGHBOR_TABLE_SIZE; i++) {
+      NeighborTable[i].flags = 0;
+    }
+  }
+
+  command error_t StdControl.start() {
+    dbg("LI", "Link estimator start\n");
+    return SUCCESS;
+  }
+
+  command error_t StdControl.stop() {
+    return SUCCESS;
+  }
+
+  // initialize the link estimator
+  command error_t Init.init() {
+    dbg("LI", "Link estimator init\n");
+    initNeighborTable();
+    return SUCCESS;
+  }
+
+  // return bi-directional link quality to the neighbor
+  command uint8_t LinkEstimator.getLinkQuality(am_addr_t neighbor) {
+    uint8_t idx;
+    idx = findIdx(neighbor);
+    if (idx == INVALID_RVAL) {
+      return INFINITY;
+    } else {
+      return NeighborTable[idx].eetx;
+    };
+  }
+
+  // return the quality of the link: neighor->self
+  command uint8_t LinkEstimator.getReverseQuality(am_addr_t neighbor) {
+    uint8_t idx;
+    idx = findIdx(neighbor);
+    if (idx == INVALID_RVAL) {
+      return INFINITY;
+    } else {
+      return computeEETX(NeighborTable[idx].inquality);
+    };
+  }
+
+  // return the quality of the link: self->neighbor
+  command uint8_t LinkEstimator.getForwardQuality(am_addr_t neighbor) {
+    uint8_t idx;
+    idx = findIdx(neighbor);
+    if (idx == INVALID_RVAL) {
+      return INFINITY;
+    } else {
+      return computeEETX(NeighborTable[idx].outquality);
+    };
+  }
+
+  // insert the neighbor at any cost (if there is a room for it)
+  // even if eviction of a perfectly fine neighbor is called for
+  command error_t LinkEstimator.insertNeighbor(am_addr_t neighbor) {
+    uint8_t nidx;
+
+    nidx = findIdx(neighbor);
+    if (nidx != INVALID_RVAL) {
+      dbg("LI", "insert: Found the entry, no need to insert\n");
+      return SUCCESS;
+    }
+
+    nidx = findEmptyNeighborIdx();
+    if (nidx != INVALID_RVAL) {
+      dbg("LI", "insert: inserted into the empty slot\n");
+      initNeighborIdx(nidx, neighbor);
+      return SUCCESS;
+    } else {
+      nidx = findWorstNeighborIdx(BEST_EETX);
+      if (nidx != INVALID_RVAL) {
+       dbg("LI", "insert: inserted by replacing an entry for neighbor: %d\n",
+           NeighborTable[nidx].ll_addr);
+       signal LinkEstimator.evicted(NeighborTable[nidx].ll_addr);
+       initNeighborIdx(nidx, neighbor);
+       return SUCCESS;
+      }
+    }
+    return FAIL;
+  }
+
+  // pin a neighbor so that it does not get evicted
+  command error_t LinkEstimator.pinNeighbor(am_addr_t neighbor) {
+    uint8_t nidx = findIdx(neighbor);
+    if (nidx == INVALID_RVAL) {
+      return FAIL;
+    }
+    NeighborTable[nidx].flags |= PINNED_ENTRY;
+    return SUCCESS;
+  }
+
+  // pin a neighbor so that it does not get evicted
+  command error_t LinkEstimator.unpinNeighbor(am_addr_t neighbor) {
+    uint8_t nidx = findIdx(neighbor);
+    if (nidx == INVALID_RVAL) {
+      return FAIL;
+    }
+    NeighborTable[nidx].flags &= ~PINNED_ENTRY;
+    return SUCCESS;
+  }
+
+
+  // called when an acknowledgement is received; sign of a successful
+  // data transmission; to update forward link quality
+  command error_t LinkEstimator.txAck(am_addr_t neighbor) {
+    neighbor_table_entry_t *ne;
+    uint8_t nidx = findIdx(neighbor);
+    if (nidx == INVALID_RVAL) {
+      return FAIL;
+    }
+    ne = &NeighborTable[nidx];
+    ne->data_success++;
+    ne->data_total++;
+    if (ne->data_total >= DLQ_PKT_WINDOW) {
+      updateDEETX(ne);
+    }
+    return SUCCESS;
+  }
+
+  // called when an acknowledgement is not received; could be due to
+  // data pkt or acknowledgement loss; to update forward link quality
+  command error_t LinkEstimator.txNoAck(am_addr_t neighbor) {
+    neighbor_table_entry_t *ne;
+    uint8_t nidx = findIdx(neighbor);
+    if (nidx == INVALID_RVAL) {
+      return FAIL;
+    }
+
+    ne = &NeighborTable[nidx];
+    ne->data_total++;
+    if (ne->data_total >= DLQ_PKT_WINDOW) {
+      updateDEETX(ne);
+    }
+    return SUCCESS;
+  }
+
+  // called when the parent changes; clear state about data-driven link quality
+  command error_t LinkEstimator.clearDLQ(am_addr_t neighbor) {
+    neighbor_table_entry_t *ne;
+    uint8_t nidx = findIdx(neighbor);
+    if (nidx == INVALID_RVAL) {
+      return FAIL;
+    }
+    ne = &NeighborTable[nidx];
+    ne->data_total = 0;
+    ne->data_success = 0;
+    return SUCCESS;
+  }
+
+
+  // get the link layer source address for the incoming packet
+  command am_addr_t LinkSrcPacket.getSrc(message_t* msg) {
+    return call SubAMPacket.source(msg);
+  }
+
+  // user of link estimator calls send here
+  // slap the header and footer before sending the message
+  command error_t Send.send(am_addr_t addr, message_t* msg, uint8_t len) {
+    uint8_t newlen;
+    newlen = addLinkEstHeaderAndFooter(msg, len);
+    dbg("LITest", "%s packet of length %hhu became %hhu\n", __FUNCTION__, len, newlen);
+    dbg("LI", "Sending seq: %d\n", linkEstSeq);
+    print_packet(msg, newlen);
+    return call AMSend.send(addr, msg, newlen);
+  }
+
+  // done sending the message that originated by
+  // the user of this component
+  event void AMSend.sendDone(message_t* msg, error_t error ) {
+    return signal Send.sendDone(msg, error);
+  }
+
+  // cascade the calls down
+  command uint8_t Send.cancel(message_t* msg) {
+    return call AMSend.cancel(msg);
+  }
+
+  command uint8_t Send.maxPayloadLength() {
+    return call Packet.maxPayloadLength();
+  }
+
+  command void* Send.getPayload(message_t* msg) {
+    return call Packet.getPayload(msg, NULL);
+  }
+
+  // called when link estimator generator packet or
+  // packets from upper layer that are wired to pass through
+  // link estimator is received
+  void processReceivedMessage(message_t* msg, void* payload, uint8_t len) {
+    uint8_t nidx;
+    uint8_t num_entries;
+
+    dbg("LI", "LI receiving packet, buf addr: %x\n", payload);
+    print_packet(msg, len);
+
+    if (call SubAMPacket.destination(msg) == AM_BROADCAST_ADDR) {
+      linkest_header_t* hdr = getHeader(msg);
+      linkest_footer_t* footer;
+      am_addr_t ll_addr;
+
+      ll_addr = call SubAMPacket.source(msg);
+
+      dbg("LI", "Got seq: %d from link: %d\n", hdr->seq, ll_addr);
+
+      num_entries = hdr->flags & NUM_ENTRIES_FLAG;
+      print_neighbor_table();
+
+      // update neighbor table with this information
+      // find the neighbor
+      // if found
+      //   update the entry
+      // else
+      //   find an empty entry
+      //   if found
+      //     initialize the entry
+      //   else
+      //     find a bad neighbor to be evicted
+      //     if found
+      //       evict the neighbor and init the entry
+      //     else
+      //       we can not accommodate this neighbor in the table
+      nidx = findIdx(ll_addr);
+      if (nidx != INVALID_RVAL) {
+       dbg("LI", "Found the entry so updating\n");
+       updateNeighborEntryIdx(nidx, hdr->seq);
+      } else {
+       nidx = findEmptyNeighborIdx();
+       if (nidx != INVALID_RVAL) {
+         dbg("LI", "Found an empty entry\n");
+         initNeighborIdx(nidx, ll_addr);
+         updateNeighborEntryIdx(nidx, hdr->seq);
+       } else {
+         nidx = findWorstNeighborIdx(EVICT_EETX_THRESHOLD);
+         if (nidx != INVALID_RVAL) {
+           dbg("LI", "Evicted neighbor %d at idx %d\n",
+               NeighborTable[nidx].ll_addr, nidx);
+           signal LinkEstimator.evicted(NeighborTable[nidx].ll_addr);
+           initNeighborIdx(nidx, ll_addr);
+         } else {
+           dbg("LI", "No room in the table\n");
+         }
+       }
+      }
+
+      if ((nidx != INVALID_RVAL) && (num_entries > 0)) {
+       dbg("LI", "Number of footer entries: %d\n", num_entries);
+       footer = (linkest_footer_t*) ((uint8_t *)call SubPacket.getPayload(msg, NULL)
+                                     + call SubPacket.payloadLength(msg)
+                                     - num_entries*sizeof(linkest_footer_t));
+       {
+         uint8_t i, my_ll_addr;
+         my_ll_addr = call SubAMPacket.address();
+         for (i = 0; i < num_entries; i++) {
+           dbg("LI", "%d %d %d\n", i, footer->neighborList[i].ll_addr,
+               footer->neighborList[i].inquality);
+           if (footer->neighborList[i].ll_addr == my_ll_addr) {
+             updateReverseQuality(ll_addr, footer->neighborList[i].inquality);
+           }
+         }
+       }
+      }
+      print_neighbor_table();
+    }
+
+
+  }
+
+  // new messages are received here
+  // update the neighbor table with the header
+  // and footer in the message
+  // then signal the user of this component
+  event message_t* SubReceive.receive(message_t* msg,
+                                     void* payload,
+                                     uint8_t len) {
+    dbg("LI", "Received upper packet. Will signal up\n");
+    processReceivedMessage(msg, payload, len);
+    return signal Receive.receive(msg,
+                                 call Packet.getPayload(msg, NULL),
+                                 call Packet.payloadLength(msg));
+  }
+
+  command void* Receive.getPayload(message_t* msg, uint8_t* len) {
+    return call Packet.getPayload(msg, len);
+  }
+
+  command uint8_t Receive.payloadLength(message_t* msg) {
+    return call Packet.payloadLength(msg);
+  }
+
+  command void Packet.clear(message_t* msg) {
+    call SubPacket.clear(msg);
+  }
+
+  // subtract the space occupied by the link estimation
+  // header and footer from the incoming payload size
+  command uint8_t Packet.payloadLength(message_t* msg) {
+    linkest_header_t *hdr;
+    hdr = getHeader(msg);
+    return call SubPacket.payloadLength(msg)
+      - sizeof(linkest_header_t)
+      - sizeof(linkest_footer_t)*(NUM_ENTRIES_FLAG & hdr->flags);
+  }
+
+  // account for the space used by header and footer
+  // while setting the payload length
+  command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
+    linkest_header_t *hdr;
+    hdr = getHeader(msg);
+    call SubPacket.setPayloadLength(msg,
+                                   len
+                                   + sizeof(linkest_header_t)
+                                   + sizeof(linkest_footer_t)*(NUM_ENTRIES_FLAG & hdr->flags));
+  }
+
+  command uint8_t Packet.maxPayloadLength() {
+    return call SubPacket.maxPayloadLength() - sizeof(linkest_header_t);
+  }
+
+  // application payload pointer is just past the link estimation header
+  command void* Packet.getPayload(message_t* msg, uint8_t* len) {
+    uint8_t* payload = call SubPacket.getPayload(msg, len);
+    linkest_header_t *hdr;
+    hdr = getHeader(msg);
+    if (len != NULL) {
+      *len = *len - sizeof(linkest_header_t) - sizeof(linkest_footer_t)*(NUM_ENTRIES_FLAG & hdr->flags);
+    }
+    return payload + sizeof(linkest_header_t);
+  }
+}
+
diff --git a/tos/lib/net/le/LinkSrcPacket.nc b/tos/lib/net/le/LinkSrcPacket.nc
new file mode 100644 (file)
index 0000000..f19433f
--- /dev/null
@@ -0,0 +1,35 @@
+/* $Id$ */
+/*
+ * "Copyright (c) 2005 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/*
+ *  @author Rodrigo Fonseca
+ *  Based on MintRoute, by Philip Buonadonna, Alec Woo, Terence Tong, Crossbow
+ *  @date   $Date$
+ */
+
+// Om: added the keyword "command"
+
+interface LinkSrcPacket {
+    /** Returns the am_addr of the link this message came from */
+    command am_addr_t getSrc(message_t* msg);
+}
diff --git a/tos/lib/printf/PrintfC.nc b/tos/lib/printf/PrintfC.nc
new file mode 100644 (file)
index 0000000..ec3ae39
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+
+/**
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+
+#include "printf.h"
+
+configuration PrintfC {
+  provides {
+       interface SplitControl as PrintfControl;
+       interface PrintfFlush;
+  }
+}
+implementation {
+  components SerialActiveMessageC;
+  components new SerialAMSenderC(AM_PRINTFMSG);
+  components PrintfP;
+  components LedsC;
+
+  PrintfControl = PrintfP;
+  PrintfFlush = PrintfP;
+  
+  PrintfP.Leds -> LedsC;
+  PrintfP.SerialControl -> SerialActiveMessageC;
+  PrintfP.AMSend -> SerialAMSenderC;
+  PrintfP.Packet -> SerialAMSenderC;
+}
+
diff --git a/tos/lib/printf/PrintfFlush.nc b/tos/lib/printf/PrintfFlush.nc
new file mode 100644 (file)
index 0000000..64b247f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+
+/**
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+#include "printf.h"
+interface PrintfFlush
+{
+  command error_t flush();
+  event void flushDone(error_t error);
+}
diff --git a/tos/lib/printf/PrintfP.nc b/tos/lib/printf/PrintfP.nc
new file mode 100644 (file)
index 0000000..608c4ea
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON 
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+
+/**
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$ 
+ */
+
+#include "printf.h"
+
+#ifdef _H_atmega128hardware_H
+static int uart_putchar(char c, FILE *stream);
+static FILE atm128_stdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
+#endif
+
+module PrintfP {
+  provides {
+    interface SplitControl as PrintfControl;
+    interface PrintfFlush;
+  }
+  uses {
+       interface SplitControl as SerialControl;
+    interface Leds;
+    interface AMSend;
+    interface Packet;
+  }
+}
+implementation {
+       
+  enum {
+       S_STARTED,
+       S_STOPPED,
+       S_FLUSHING,
+  };
+  
+  message_t printfMsg;
+  nx_uint8_t buffer[PRINTF_BUFFER_SIZE];
+  norace nx_uint8_t* next_byte;
+  uint8_t state = S_STOPPED;
+  uint8_t bytes_left_to_flush;
+  uint8_t length_to_send;
+  
+  task void retrySend() {
+    if(call AMSend.send(AM_BROADCAST_ADDR, &printfMsg, sizeof(PrintfMsg)) != SUCCESS)
+      post retrySend();
+  }
+  
+  void sendNext() {
+       PrintfMsg* m = (PrintfMsg*)call Packet.getPayload(&printfMsg, NULL);
+       length_to_send = (bytes_left_to_flush < sizeof(PrintfMsg)) ? bytes_left_to_flush : sizeof(PrintfMsg);
+       memset(m->buffer, 0, sizeof(printfMsg));
+       memcpy(m->buffer, (uint8_t*)next_byte, length_to_send);
+    if(call AMSend.send(AM_BROADCAST_ADDR, &printfMsg, sizeof(PrintfMsg)) != SUCCESS)
+      post retrySend();  
+    else {
+      bytes_left_to_flush -= length_to_send;
+      next_byte += length_to_send;
+    }
+  }
+
+  command error_t PrintfControl.start() {
+       if(state == S_STOPPED)
+      return call SerialControl.start();
+    return FAIL;
+  }
+  
+  command error_t PrintfControl.stop() {
+       if(state == S_STARTED)
+      return call SerialControl.stop();
+    return FAIL;
+  }
+
+  event void SerialControl.startDone(error_t error) {
+       if(error != SUCCESS) {
+         signal PrintfControl.startDone(error);
+         return;
+       }
+#ifdef _H_atmega128hardware_H
+       stdout = &atm128_stdout;
+#endif
+    atomic {
+      memset(buffer, 0, sizeof(buffer));
+      next_byte = buffer;
+      bytes_left_to_flush = 0; 
+      length_to_send = 0;
+      state = S_STARTED;
+    }
+    signal PrintfControl.startDone(error); 
+  }
+
+  event void SerialControl.stopDone(error_t error) {
+       if(error != SUCCESS) {
+         signal PrintfControl.stopDone(error);
+         return;
+       }
+    atomic state = S_STOPPED;
+    signal PrintfControl.stopDone(error); 
+  }
+  
+  command error_t PrintfFlush.flush() {
+       atomic {
+         if(state == S_STARTED && (next_byte > buffer)) {
+           state = S_FLUSHING;
+        bytes_left_to_flush = next_byte - buffer;
+           next_byte = buffer;
+         }
+         else return FAIL;
+       }
+       sendNext();
+       return SUCCESS;
+  }
+    
+  event void AMSend.sendDone(message_t* msg, error_t error) {    
+       if(error == SUCCESS) {
+         if(bytes_left_to_flush > 0)
+           sendNext();
+         else {
+        next_byte = buffer;
+        bytes_left_to_flush = 0; 
+       length_to_send = 0;
+        atomic state = S_STARTED;
+           signal PrintfFlush.flushDone(error);
+         }
+       }
+       else post retrySend();
+  }
+  
+#ifdef _H_msp430hardware_h
+  int putchar(int c) __attribute__((noinline)) @C() @spontaneous() {
+#endif
+#ifdef _H_atmega128hardware_H
+  int uart_putchar(char c, FILE *stream) __attribute__((noinline)) @C() @spontaneous() {
+#endif
+       atomic {
+         if(state == S_STARTED && ((next_byte-buffer+1) < PRINTF_BUFFER_SIZE)) {
+           *next_byte = c;
+           next_byte++;
+           return 0;
+         }
+         else return -1;
+       }
+  }
+}
diff --git a/tos/lib/printf/printf.h b/tos/lib/printf/printf.h
new file mode 100644 (file)
index 0000000..af95c28
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * "Copyright (c) 2006 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON 
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+
+/**
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+
+#ifndef PRINTF_H
+#define PRINTF_H
+
+#include <stdio.h>
+#include "message.h"
+
+#define PRINTF_BUFFER_SIZE 250
+
+typedef nx_struct PrintfMsg {
+  nx_uint8_t buffer[TOSH_DATA_LENGTH];
+} PrintfMsg;
+
+enum {
+  AM_PRINTFMSG = 100,
+};
+
+#endif //PRINTF_H
+
diff --git a/tos/platforms/eyesIFX/ActiveMessageFilterC.nc b/tos/platforms/eyesIFX/ActiveMessageFilterC.nc
new file mode 100644 (file)
index 0000000..ebb9a38
--- /dev/null
@@ -0,0 +1,73 @@
+/* 
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+ /* This component is the default AM filter component: it does not do anything,
+  * it uses no RAM and nesC will compile all code away. Its purpose is to allow
+  * other components to shadow (overwrite) it to implement their own
+  * filter/statistic component.
+  */
+
+#include "AM.h"
+module ActiveMessageFilterC {
+  provides {
+    interface AMSend[am_id_t id];
+    interface Receive[am_id_t id];
+    interface Receive as Snoop[am_id_t id];
+  }
+  uses {
+    interface AMSend as SubAMSend[am_id_t id];
+    interface Receive as SubReceive[am_id_t id];
+    interface Receive as SubSnoop[am_id_t id];
+  }
+} implementation {
+
+  command error_t AMSend.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len){ return call SubAMSend.send[id](addr, msg, len);}
+  command error_t AMSend.cancel[am_id_t id](message_t* msg){ return call SubAMSend.cancel[id](msg);}
+  command uint8_t AMSend.maxPayloadLength[am_id_t id](){ return call SubAMSend.maxPayloadLength[id]();}
+  command void* AMSend.getPayload[am_id_t id](message_t* msg){ return call SubAMSend.getPayload[id](msg);}
+  event void SubAMSend.sendDone[am_id_t id](message_t* msg, error_t error) { signal AMSend.sendDone[id](msg, error); }
+  default event void AMSend.sendDone[am_id_t id](message_t* msg, error_t error) { return; }
+
+  command void* Receive.getPayload[am_id_t id](message_t* msg, uint8_t* len){ return call SubReceive.getPayload[id](msg, len);}
+  command uint8_t Receive.payloadLength[am_id_t id](message_t* msg){ return call SubReceive.payloadLength[id](msg);}
+  event message_t* SubReceive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) { return signal Receive.receive[id](msg, payload, len); }
+  default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len){ return msg;}
+  
+  command void* Snoop.getPayload[am_id_t id](message_t* msg, uint8_t* len){ return call SubSnoop.getPayload[id](msg, len);}
+  command uint8_t Snoop.payloadLength[am_id_t id](message_t* msg){ return call SubSnoop.payloadLength[id](msg);}
+  event message_t* SubSnoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) { return signal Snoop.receive[id](msg, payload, len);
+  }
+  default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len){return msg;}
+}
diff --git a/tos/platforms/eyesIFX/byte_radio/Uart4b6bPhyC.nc b/tos/platforms/eyesIFX/byte_radio/Uart4b6bPhyC.nc
new file mode 100644 (file)
index 0000000..364bb49
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+* Copyright (c) 2006, Technische Universitaet Berlin
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+*   notice, this list of conditions and the following disclaimer in the
+*   documentation and/or other materials provided with the distribution.
+* - Neither the name of the Technische Universitaet 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.
+*/
+
+/**
+ * Configuration for the byte radio physical layer. Together with the
+ * PacketSerializerP the UartPhyP module turns byte streams into packets.
+ * This one 4b6b encodes/decodes a byte stream
+ *
+ * @see PacketSerializerP
+ *
+ * @author Philipp Huppertz <huppertz@tkn.tu-berlin.de>
+ */
+configuration Uart4b6bPhyC
+{
+  provides{
+    interface PhyPacketTx;
+    interface RadioByteComm as SerializerRadioByteComm;
+    interface PhyPacketRx;
+    interface UartPhyControl;
+  }
+  uses {
+    interface RadioByteComm;
+  }
+}
+implementation
+{
+    components 
+        new Alarm32khz16C() as RxByteTimer,
+        Uart4b6bPhyP,
+        // PlatformLedsC,
+        MainC;
+    
+    MainC.SoftwareInit -> Uart4b6bPhyP;
+    PhyPacketRx = Uart4b6bPhyP;
+    SerializerRadioByteComm = Uart4b6bPhyP;
+    RadioByteComm = Uart4b6bPhyP;
+    PhyPacketTx = Uart4b6bPhyP;
+    UartPhyControl = Uart4b6bPhyP;
+    
+    Uart4b6bPhyP.RxByteTimer -> RxByteTimer;
+//    PlatformLedsC.Led3 <- Uart4b6bPhyP.Led3;
+//     PlatformLedsC.Led1 <- Uart4b6bPhyP.Led1;
+}
diff --git a/tos/platforms/eyesIFX/byte_radio/Uart4b6bPhyP.nc b/tos/platforms/eyesIFX/byte_radio/Uart4b6bPhyP.nc
new file mode 100644 (file)
index 0000000..c91e73f
--- /dev/null
@@ -0,0 +1,379 @@
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ */
+
+#include "code4b6b.h"
+
+/**
+ * Implementation of the physical layer for the eyesIFX byte radio.
+ * Together with the PacketSerializerP this module turns byte streams 
+ * into packets.
+ *
+ * @author Andreas Koepke <koepke@tkn.tu-berlin.de>
+ */
+module Uart4b6bPhyP {
+    provides {
+        interface Init;
+        interface PhyPacketTx;
+        interface RadioByteComm as SerializerRadioByteComm;
+        interface PhyPacketRx;
+        interface UartPhyControl;
+    }
+    uses {
+        interface RadioByteComm;
+        interface Alarm<T32khz, uint16_t> as RxByteTimer;
+        // interface GeneralIO as Led3;
+    }
+}
+implementation
+{
+    /* Module Definitions  */
+    typedef enum {
+        STATE_PREAMBLE,
+        STATE_PREAMBLE_CODE,
+        STATE_SYNC,
+        STATE_SFD1,
+        STATE_SFD2,
+        STATE_SFD3,
+        STATE_HEADER_DONE,
+        STATE_DATA_HIGH_OR_SFD,
+        STATE_DATA_HIGH,
+        STATE_DATA_MIDDLE,
+        STATE_DATA_LOW,
+        STATE_DATA_LOW_FOOTER,
+        STATE_FOOTER_START,
+        STATE_FOOTER_DONE
+    } phyState_t;
+
+    /* constants */
+    enum {
+        PREAMBLE_LENGTH=2,
+        BYTE_TIME=11,
+        PREAMBLE_BYTE=0x55,
+        SYNC_BYTE=0xFF,
+        SFD_BYTE=0x83
+    };
+    
+    /** Module Global Variables  */
+    phyState_t phyState;    // Current Phy state State
+    uint16_t preambleCount;
+    uint16_t numPreambles;  // Number of preambles to send before the packet
+    uint8_t byteTime;       // max. time between two bytes
+    uint8_t bufByte;
+    /* Local Function Declarations */
+    void TransmitNextByte();
+    void ReceiveNextByte(uint8_t data);
+
+    /* Radio Init */
+    command error_t Init.init(){
+        atomic {
+            phyState = STATE_PREAMBLE;
+            numPreambles = PREAMBLE_LENGTH;
+            byteTime = BYTE_TIME;
+        }
+        return SUCCESS;
+    }
+    
+    async command error_t UartPhyControl.setNumPreambles(uint16_t numPreambleBytes) {
+        atomic {
+            numPreambles = numPreambleBytes;
+        }
+        return SUCCESS;
+    }
+    
+    command error_t UartPhyControl.setByteTimeout(uint8_t byteTimeout) {
+        if (call RxByteTimer.isRunning() == TRUE) {
+            return FAIL;
+        } else {
+            byteTime = byteTimeout * 33;
+            return SUCCESS;
+        }
+    }
+    
+    async command bool UartPhyControl.isBusy() {
+        return phyState != STATE_PREAMBLE;
+    }
+    
+    void resetState() {
+        call RxByteTimer.stop();
+        switch(phyState) {
+                       case STATE_PREAMBLE:
+            case STATE_PREAMBLE_CODE:
+             case STATE_SFD2:
+                break;
+            default:
+                signal PhyPacketRx.recvFooterDone(FAIL);
+                break;
+        }
+        phyState = STATE_PREAMBLE; 
+    }
+    
+    async event void RxByteTimer.fired() {
+        // no bytes have arrived, so...
+        resetState();
+    }
+
+    async command void PhyPacketTx.sendHeader() {
+        phyState = STATE_PREAMBLE;
+        preambleCount = numPreambles;
+        TransmitNextByte();
+    }
+
+    async command void SerializerRadioByteComm.txByte(uint8_t data) {
+        uint8_t high = nibbleToSixBit[(data & 0xf0) >> 4];
+        uint8_t low = nibbleToSixBit[data & 0x0f];
+        if(phyState == STATE_DATA_HIGH) {
+            high <<= 2;
+            if(low & 0x20) high |= 2;
+            if(low & 0x10) high |= 1;
+            bufByte = low << 4;
+            call RadioByteComm.txByte(high);
+            phyState = STATE_DATA_MIDDLE;
+        }
+        else {
+            call RadioByteComm.txByte(bufByte | (high >> 2));
+            if(high & 0x02) low |= 0x80;
+            if(high & 0x01) low |= 0x40;
+            bufByte = low;
+            phyState = STATE_DATA_LOW;
+        }
+    }
+
+    async command bool SerializerRadioByteComm.isTxDone() {
+        return call RadioByteComm.isTxDone();
+    }
+
+    async command void PhyPacketTx.sendFooter() {
+        if(phyState == STATE_DATA_MIDDLE) {
+            bufByte |= (nibbleToSixBit[0] >> 2);
+            phyState = STATE_DATA_LOW_FOOTER;
+            call RadioByteComm.txByte(bufByte);
+        } else {
+            phyState = STATE_FOOTER_START;
+            TransmitNextByte();
+        }
+    }
+    
+
+
+    /* Radio Recv */
+    async command void PhyPacketRx.recvFooter() {
+        // currently there is no footer
+        // atomic phyState = STATE_FOOTER_START;
+        phyState = STATE_PREAMBLE;
+        call RxByteTimer.stop();
+        signal PhyPacketRx.recvFooterDone(SUCCESS);
+    }
+
+    
+    /* Tx Done */
+    async event void RadioByteComm.txByteReady(error_t error) {
+        if(error == SUCCESS) {
+            TransmitNextByte();
+        } else {
+            signal SerializerRadioByteComm.txByteReady(error);
+            phyState = STATE_PREAMBLE;
+        }
+    }
+
+    void TransmitNextByte() {
+        switch(phyState) {
+            case STATE_PREAMBLE:
+                if(preambleCount > 0) {
+                    preambleCount--;
+                } else {
+                    phyState = STATE_SYNC;
+                }
+                call RadioByteComm.txByte(PREAMBLE_BYTE);
+                break;
+            case STATE_SYNC:
+                phyState = STATE_SFD1;
+                call RadioByteComm.txByte(SYNC_BYTE);
+                break;
+            case STATE_SFD1:
+                phyState = STATE_SFD2;
+                call RadioByteComm.txByte(SFD_BYTE);
+                break;
+               case STATE_SFD2:
+               phyState = STATE_SFD3;
+               call RadioByteComm.txByte(SFD_BYTE);
+               break;
+            case STATE_SFD3:
+                phyState = STATE_HEADER_DONE;
+                call RadioByteComm.txByte(SFD_BYTE);
+                break;
+            case STATE_HEADER_DONE:
+                phyState = STATE_DATA_HIGH;
+                signal PhyPacketTx.sendHeaderDone();
+                break;
+            case STATE_DATA_HIGH:
+                signal SerializerRadioByteComm.txByteReady(SUCCESS);
+                break;
+            case STATE_DATA_MIDDLE:
+                signal SerializerRadioByteComm.txByteReady(SUCCESS);
+                break;
+            case STATE_DATA_LOW:
+                call RadioByteComm.txByte(bufByte);
+                phyState = STATE_DATA_HIGH;
+                break;
+            case STATE_DATA_LOW_FOOTER:
+                phyState = STATE_FOOTER_START;
+                call RadioByteComm.txByte(bufByte);
+                break;
+            case STATE_FOOTER_START:
+                /* Pseudo-Footer: the MSP430 has two buffers: one for
+                 * transmit, one to store the next byte to be transmitted,
+                 * this footer fills the next-to-transmit buffer, to make
+                 * sure that the last real byte is actually
+                 * transmitted. The byte stored by this call may not be
+                 * transmitted fully or not at all. 
+                 */
+                phyState = STATE_FOOTER_DONE;
+                call RadioByteComm.txByte(bufByte);
+                break;
+            case STATE_FOOTER_DONE:
+                phyState = STATE_PREAMBLE;
+                signal PhyPacketTx.sendFooterDone();
+                break;
+            default:
+                break;
+        }
+    }
+
+    /* Rx Done */
+    async event void RadioByteComm.rxByteReady(uint8_t data) {
+      call RxByteTimer.start(byteTime);
+        ReceiveNextByte(data);
+    }
+
+    /* Receive the next Byte from the USART */
+    void ReceiveNextByte(uint8_t data) {
+        uint8_t decodedByte;
+        uint8_t low;
+        uint8_t high;
+        if((data == SFD_BYTE) && (phyState != STATE_SFD2) && (phyState != STATE_DATA_HIGH_OR_SFD)) {
+            resetState();
+            phyState = STATE_SFD1;
+            call RxByteTimer.start(byteTime<<1);
+        }
+        switch(phyState) {
+            case STATE_PREAMBLE:
+                low = data & 0xf;
+                high = data >> 4;
+                if((low > 0) && (low < 0xf) && (high > 0) && (high < 0xf))
+                    phyState = STATE_PREAMBLE_CODE;
+                break;
+            case STATE_PREAMBLE_CODE:
+                low = data & 0xf;
+                high = data >> 4;
+                if((low == 0) || (low == 0xf) || (high == 0) || (high == 0xf))
+                    phyState = STATE_PREAMBLE;
+                break;
+               case STATE_SFD1:
+               phyState = STATE_SFD2;
+            break;
+            case STATE_SFD2:
+              if(data == SFD_BYTE) {
+                       call RxByteTimer.start(byteTime<<1);
+                       signal PhyPacketRx.recvHeaderDone(SUCCESS);
+                  phyState = STATE_DATA_HIGH_OR_SFD;
+              }
+              else {
+                resetState();
+              }
+            break;
+            case STATE_DATA_HIGH_OR_SFD:
+                if(data != SFD_BYTE) {
+                    decodedByte = sixBitToNibble[data >> 2];
+                    if(decodedByte != ILLEGAL_CODE) {
+                        bufByte = decodedByte << 2;
+                        bufByte |= data & 0x03;
+                        bufByte <<= 2;
+                        phyState = STATE_DATA_MIDDLE;
+                    }
+                    else {
+                        resetState();
+                    }
+                }
+                else {
+                    phyState = STATE_DATA_HIGH;
+                }
+                break;
+            case STATE_DATA_HIGH:
+                decodedByte = sixBitToNibble[data >> 2];
+                if(decodedByte != ILLEGAL_CODE) {
+                    bufByte = decodedByte << 2;
+                    bufByte |= data & 0x03;
+                    bufByte <<= 2;
+                    phyState = STATE_DATA_MIDDLE;
+                }
+                else {
+                    resetState();
+                }
+                break;
+            case STATE_DATA_MIDDLE:
+                decodedByte = sixBitToNibble[((bufByte & 0x0f)<<2) | (data >> 4)];
+                if(decodedByte != ILLEGAL_CODE) {
+                    phyState = STATE_DATA_LOW;
+                    signal SerializerRadioByteComm.rxByteReady((bufByte & 0xf0) | decodedByte);
+                    bufByte = (data & 0x0f) << 2;
+                }
+                else {
+                    resetState();
+                }
+                break;
+            case STATE_DATA_LOW:
+                decodedByte = sixBitToNibble[bufByte | (data >> 6)];
+                if(decodedByte != ILLEGAL_CODE) {
+                    bufByte = (decodedByte << 4);
+                    decodedByte = sixBitToNibble[data & 0x3f];
+                    if(decodedByte != ILLEGAL_CODE) {
+                        phyState = STATE_DATA_HIGH;
+                        signal SerializerRadioByteComm.rxByteReady(bufByte | decodedByte);
+                    }
+                    else {
+                        resetState();
+                    }
+                }
+                else {
+                    resetState();
+                }
+                break;
+                // maybe there will be a time.... we will need this. but for now there is no footer
+                //case STATE_FOOTER_START:
+                //phyState = STATE_FOOTER_DONE;
+                //break;
+                //case STATE_FOOTER_DONE:
+                //phyState = STATE_NULL;
+                //signal PhyPacketRx.recvFooterDone(TRUE);
+                //break;
+            default:
+                break;
+        }
+    }
+}
diff --git a/tos/platforms/eyesIFX/byte_radio/UartManchPhyC.nc b/tos/platforms/eyesIFX/byte_radio/UartManchPhyC.nc
new file mode 100644 (file)
index 0000000..df0ef43
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2006, Technische Universitaet Berlin
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+*   notice, this list of conditions and the following disclaimer in the
+*   documentation and/or other materials provided with the distribution.
+* - Neither the name of the Technische Universitaet Berlin nor the names
+*   of its contributors may be used to endorse or promote products derived
+*   from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* - Description ---------------------------------------------------------
+*
+* - Revision -------------------------------------------------------------
+* $Revision$
+* $Date$
+* @author: Philipp Huppertz <huppertz@tkn.tu-berlin.de>
+* ========================================================================
+*/
+
+/**
+ * Configuration for the byte radio physical layer. Together with the
+ * PacketSerializerP the UartPhyP module turns byte streams into packets.
+ *
+ * @see PacketSerializerP
+ *
+ * @author Philipp Huppertz <huppertz@tkn.tu-berlin.de>
+ */
+configuration UartManchPhyC
+{
+  provides{
+    interface PhyPacketTx;
+    interface RadioByteComm as SerializerRadioByteComm;
+    interface PhyPacketRx;
+    interface UartPhyControl;
+  }
+  uses {
+    interface RadioByteComm;
+  }
+}
+implementation
+{
+    components 
+        new Alarm32khz16C() as RxByteTimer,
+        UartManchPhyP,
+//         PlatformLedsC,
+        MainC;
+    
+    MainC.SoftwareInit -> UartManchPhyP;
+    PhyPacketRx = UartManchPhyP;
+    SerializerRadioByteComm = UartManchPhyP;
+    RadioByteComm = UartManchPhyP;
+    PhyPacketTx = UartManchPhyP;
+    UartPhyControl = UartManchPhyP;
+    
+    UartManchPhyP.RxByteTimer -> RxByteTimer;
+//     PlatformLedsC.Led0 <- UartManchPhyP.Led0;
+//     PlatformLedsC.Led1 <- UartManchPhyP.Led1;
+}
diff --git a/tos/platforms/eyesIFX/byte_radio/UartManchPhyP.nc b/tos/platforms/eyesIFX/byte_radio/UartManchPhyP.nc
new file mode 100644 (file)
index 0000000..3021ff7
--- /dev/null
@@ -0,0 +1,328 @@
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2004, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Description ---------------------------------------------------------
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Kevin Klues (klues@tkn.tu-berlin.de)
+ * @author: Philipp Huppertz <huppertz@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+#include "manchester.h"
+
+/**
+ * Implementation of the physical layer for the eyesIFX byte radio.
+ * Together with the PacketSerializerP this module turns byte streams 
+ * into packets.
+ *
+ * @author Kevin Klues <klues@tkn.tu-berlin.de>
+ * @author Philipp Huppertz <huppertz@tkn.tu-berlin.de>
+ */
+module UartManchPhyP {
+    provides {
+        interface Init;
+        interface PhyPacketTx;
+        interface RadioByteComm as SerializerRadioByteComm;
+        interface PhyPacketRx;
+        interface UartPhyControl;
+    }
+    uses {
+        interface RadioByteComm;
+        interface Alarm<T32khz, uint16_t> as RxByteTimer;
+    }
+}
+implementation
+{
+    /* Module Definitions  */
+    typedef enum {
+        STATE_PREAMBLE,
+        STATE_PREAMBLE_MANCHESTER,
+        STATE_SYNC,
+        STATE_SFD,
+        STATE_HEADER_DONE,
+        STATE_DATA_HIGH,
+        STATE_DATA_LOW,
+        STATE_FOOTER_START,
+        STATE_FOOTER_DONE
+    } phyState_t;
+
+#define PREAMBLE_LENGTH   4
+#define BYTE_TIME         18
+#define PREAMBLE_BYTE     0x55
+#define SYNC_BYTE         0xFF
+#define SFD_BYTE          0x50
+
+    /** Module Global Variables  */
+    phyState_t phyState;    // Current Phy state State
+    uint16_t preambleCount;
+    uint16_t numPreambles;  // Number of preambles to send before the packet
+    uint8_t byteTime;       // max. time between two bytes
+    uint8_t bufByte;
+    
+    /* Local Function Declarations */
+    void TransmitNextByte();
+    void ReceiveNextByte(uint8_t data);
+
+    /* Radio Init */
+    command error_t Init.init(){
+        atomic {
+            phyState = STATE_PREAMBLE;
+            numPreambles = PREAMBLE_LENGTH;
+            byteTime = BYTE_TIME;
+        }
+        return SUCCESS;
+    }
+    
+    async command error_t UartPhyControl.setNumPreambles(uint16_t numPreambleBytes) {
+        atomic {
+            numPreambles = numPreambleBytes;
+        }
+        return SUCCESS;
+    }
+    
+    command error_t UartPhyControl.setByteTimeout(uint8_t byteTimeout) {
+        if (call RxByteTimer.isRunning() == TRUE) {
+            return FAIL;
+        } else {
+            atomic byteTime = byteTimeout * 33;
+            return SUCCESS;
+        }
+    }
+    
+    async command bool UartPhyControl.isBusy() {
+        return phyState != STATE_PREAMBLE;
+    }
+    
+    void resetState() {
+        atomic {
+            call RxByteTimer.stop();
+            switch(phyState) {
+                case STATE_SYNC:
+                case STATE_SFD:
+                    signal PhyPacketRx.recvHeaderDone(FAIL);
+                    break;
+                case STATE_DATA_HIGH:
+                case STATE_DATA_LOW:
+                case STATE_FOOTER_START:
+                    signal PhyPacketRx.recvFooterDone(FAIL);
+                    break;
+                default:
+                    break;
+            }
+            phyState = STATE_PREAMBLE; 
+        }
+    }
+    
+    async event void RxByteTimer.fired() {
+        // no bytes have arrived, so...
+        resetState();
+    }
+
+    async command void PhyPacketTx.sendHeader() {
+        atomic {
+            phyState = STATE_PREAMBLE;
+            preambleCount = numPreambles;
+        }
+        TransmitNextByte();
+    }
+
+    async command void SerializerRadioByteComm.txByte(uint8_t data) {
+        bufByte = data;
+        call RadioByteComm.txByte(manchesterEncodeNibble((bufByte & 0xf0) >> 4));
+        phyState = STATE_DATA_LOW;
+    }
+
+    async command bool SerializerRadioByteComm.isTxDone() {
+        return call RadioByteComm.isTxDone();
+    }
+
+    async command void PhyPacketTx.sendFooter() {
+        atomic phyState = STATE_FOOTER_START;
+        TransmitNextByte();
+    }
+
+
+    /* Radio Recv */
+    async command void PhyPacketRx.recvFooter() {
+        // currently there is no footer
+        // atomic phyState = STATE_FOOTER_START;
+        atomic {
+            phyState = STATE_PREAMBLE;
+        }
+        call RxByteTimer.stop();
+        signal PhyPacketRx.recvFooterDone(SUCCESS);
+    }
+
+    
+    /* Tx Done */
+    async event void RadioByteComm.txByteReady(error_t error) {
+        if(error == SUCCESS) {
+            TransmitNextByte();
+        } else {
+            atomic {
+                signal SerializerRadioByteComm.txByteReady(error);
+                phyState = STATE_PREAMBLE;
+            }
+        }
+    }
+
+    void TransmitNextByte() {
+        atomic {
+            switch(phyState) {
+                case STATE_PREAMBLE:
+                    if(preambleCount > 0) {
+                        preambleCount--;
+                    } else {
+                        phyState = STATE_SYNC;
+                    }
+                    call RadioByteComm.txByte(PREAMBLE_BYTE);
+                    break;
+                case STATE_SYNC:
+                    phyState = STATE_SFD;
+                    call RadioByteComm.txByte(SYNC_BYTE);
+                    break;
+                case STATE_SFD:
+                    phyState = STATE_HEADER_DONE;
+                    call RadioByteComm.txByte(SFD_BYTE);
+                    break;
+                case STATE_HEADER_DONE:
+                    phyState = STATE_DATA_HIGH;
+                    signal PhyPacketTx.sendHeaderDone();
+                    break;
+                case STATE_DATA_HIGH:
+                    signal SerializerRadioByteComm.txByteReady(SUCCESS);
+                    break;
+                case STATE_DATA_LOW:
+                    call RadioByteComm.txByte(manchesterEncodeNibble(bufByte & 0x0f));
+                    phyState = STATE_DATA_HIGH;                    
+                    break;
+                case STATE_FOOTER_START:
+                    /* Pseudo-Footer: the MSP430 has two buffers: one for
+                     * transmit, one to store the next byte to be transmitted,
+                     * this footer fills the next-to-transmit buffer, to make
+                     * sure that the last real byte is actually
+                     * transmitted. The byte stored by this call may not be
+                     * transmitted fully or not at all. 
+                     */
+                    phyState = STATE_FOOTER_DONE;
+                    call RadioByteComm.txByte(manchesterEncodeNibble(bufByte & 0x0f));
+                    break;
+                case STATE_FOOTER_DONE:
+                    phyState = STATE_PREAMBLE;
+                    signal PhyPacketTx.sendFooterDone();
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /* Rx Done */
+    async event void RadioByteComm.rxByteReady(uint8_t data) {
+        call RxByteTimer.start(byteTime);
+        ReceiveNextByte(data);
+    }
+
+    /* Receive the next Byte from the USART */
+    void ReceiveNextByte(uint8_t data) {
+        uint8_t decodedByte;
+        atomic {
+            switch(phyState) {
+                case STATE_SYNC:
+                    if(data != PREAMBLE_BYTE) {
+                        if (data == SFD_BYTE) {
+                            signal PhyPacketRx.recvHeaderDone(SUCCESS);
+                            phyState = STATE_DATA_HIGH;
+                        } else {
+                            phyState = STATE_SFD;
+                        } 
+                    }
+                    break;
+                case STATE_SFD:
+                    if (data == SFD_BYTE) {
+                        signal PhyPacketRx.recvHeaderDone(SUCCESS);
+                        phyState = STATE_DATA_HIGH;
+                    } else {
+                        phyState = STATE_PREAMBLE; 
+                    }
+                    break;
+                case STATE_PREAMBLE:
+                    if(data == PREAMBLE_BYTE) {
+                        phyState = STATE_SYNC;
+                    }
+                    else if(manchesterDecodeByte(data) != 0xff) {
+                        phyState = STATE_PREAMBLE_MANCHESTER;
+                    }
+                    break;
+                case STATE_PREAMBLE_MANCHESTER:
+                    if(data == PREAMBLE_BYTE) {
+                        phyState = STATE_SYNC;
+                    }
+                    else if(manchesterDecodeByte(data) == 0xff) {
+                        phyState = STATE_PREAMBLE; 
+                    }
+                    break;
+                case STATE_DATA_HIGH:
+                    decodedByte = manchesterDecodeByte(data);
+                    if(decodedByte != 0xff) {
+                        bufByte = decodedByte << 4;
+                        phyState = STATE_DATA_LOW;
+                    }
+                    else {
+                        resetState();
+                    }
+                    break;
+                case STATE_DATA_LOW:
+                    decodedByte = manchesterDecodeByte(data);
+                    if(decodedByte != 0xff) {
+                        bufByte |= decodedByte;
+                        phyState = STATE_DATA_HIGH;
+                        signal SerializerRadioByteComm.rxByteReady(bufByte);
+                    }
+                    else {
+                        resetState();
+                    }
+                    break;
+                    // maybe there will be a time.... we will need this. but for now there is no footer
+                    //case STATE_FOOTER_START:
+                    //phyState = STATE_FOOTER_DONE;
+                    //break;
+                    //case STATE_FOOTER_DONE:
+                    //phyState = STATE_NULL;
+                    //signal PhyPacketRx.recvFooterDone(TRUE);
+                    //break;
+                default:
+                    break;
+            }
+        }
+    }
+
+}
diff --git a/tos/platforms/eyesIFX/byte_radio/code4b6b.h b/tos/platforms/eyesIFX/byte_radio/code4b6b.h
new file mode 100644 (file)
index 0000000..f376f86
--- /dev/null
@@ -0,0 +1,130 @@
+/* -*- mode:c++; indent-tabs-mode: nil -*-
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ */
+
+/**
+ * provide functions to encode/decode a 4b 6b stream
+ * @author Andreas Koepke <koepke@tkn.tu-berlin.de>
+ * Book:     RF Monolithics, Inc: ASH Transceiver Designer's Guide, Okt 2002.
+ * http://www.rfm.com/products/tr_des24.pdf
+ */
+
+#ifndef CODE_4B_6B_H
+#define CODE_4B_6B_H
+
+enum {
+    ILLEGAL_CODE = 0xff
+};
+
+const uint8_t nibbleToSixBit[] = {
+    13, // 001101
+    14, // 001110
+    19, // 010011
+    21, // 010101
+    22, // 010110
+    25, // 011001
+    26, // 011010
+    28, // 011100
+    35, // 100011
+    37, // 100101
+    38, // 100110
+    41, // 101001
+    42, // 101010
+    44, // 101100
+    50, // 110010
+    52  // 110100
+};
+
+const uint8_t sixBitToNibble[] = {
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    0x00,
+    0x01,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    0x02,
+    ILLEGAL_CODE,
+    0x03,
+    0x04,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    0x05,
+    0x06,
+    ILLEGAL_CODE,
+    0x07,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    0x08,
+    ILLEGAL_CODE,
+    0x09,
+    0x0a,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    0x0b,
+    0x0c,
+    ILLEGAL_CODE,
+    0x0d,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    0x0e,
+    ILLEGAL_CODE,
+    0x0f,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE,
+    ILLEGAL_CODE
+};
+
+#endif
diff --git a/tos/platforms/eyesIFX/chips/msp430/Msp430Timer32khzMapC.nc b/tos/platforms/eyesIFX/chips/msp430/Msp430Timer32khzMapC.nc
new file mode 100644 (file)
index 0000000..8c18d51
--- /dev/null
@@ -0,0 +1,73 @@
+//$Id$
+
+/* "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement
+ * is hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
+ * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+//@author Cory Sharp <cssharp@eecs.berkeley.edu>
+
+/*
+  Msp430Timer32khzMapC presents as paramaterized interfaces all of the 32khz
+  hardware timers on the MSP430 that are available for compile time allocation
+  by "new Alarm32khz16C()", "new AlarmMilli32C()", and so on.
+
+  Platforms based on the Msp430 are encouraged to copy in and override this
+  file, presenting only the hardware timers that are available for allocation
+  on that platform.
+*/
+
+configuration Msp430Timer32khzMapC
+{
+  provides interface Msp430Timer[ uint8_t id ];
+  provides interface Msp430TimerControl[ uint8_t id ];
+  provides interface Msp430Compare[ uint8_t id ];
+}
+implementation
+{
+  components Msp430TimerC;
+
+  Msp430Timer[0] = Msp430TimerC.TimerB;
+  Msp430TimerControl[0] = Msp430TimerC.ControlB0;
+  Msp430Compare[0] = Msp430TimerC.CompareB0;
+
+  Msp430Timer[1] = Msp430TimerC.TimerB;
+  Msp430TimerControl[1] = Msp430TimerC.ControlB1;
+  Msp430Compare[1] = Msp430TimerC.CompareB1;
+
+  Msp430Timer[2] = Msp430TimerC.TimerB;
+  Msp430TimerControl[2] = Msp430TimerC.ControlB2;
+  Msp430Compare[2] = Msp430TimerC.CompareB2;
+
+  Msp430Timer[3] = Msp430TimerC.TimerB;
+  Msp430TimerControl[3] = Msp430TimerC.ControlB3;
+  Msp430Compare[3] = Msp430TimerC.CompareB3;
+
+  Msp430Timer[4] = Msp430TimerC.TimerB;
+  Msp430TimerControl[4] = Msp430TimerC.ControlB4;
+  Msp430Compare[4] = Msp430TimerC.CompareB4;
+
+  Msp430Timer[5] = Msp430TimerC.TimerB;
+  Msp430TimerControl[5] = Msp430TimerC.ControlB5;
+  Msp430Compare[5] = Msp430TimerC.CompareB5;
+
+  Msp430Timer[6] = Msp430TimerC.TimerB;
+  Msp430TimerControl[6] = Msp430TimerC.ControlB6;
+  Msp430Compare[6] = Msp430TimerC.CompareB6;
+}
+
diff --git a/tos/platforms/eyesIFX/chips/msp430/Msp430Uart0C.nc b/tos/platforms/eyesIFX/chips/msp430/Msp430Uart0C.nc
new file mode 100644 (file)
index 0000000..0cf129c
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * An implementation of the UART on USART0 for the MSP430.
+ * @author Vlado Handziski <handzisk@tkn.tu-berlin.de>
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#include "msp430usart.h"
+
+generic configuration Msp430Uart0C() {
+
+  provides interface Resource;   provides interface ResourceRequested;
+  provides interface UartStream;
+  provides interface UartByte;
+  provides interface Msp430UartControl as UartControl;
+
+  uses interface Msp430UartConfigure;
+}
+
+implementation {
+
+  enum {
+    CLIENT_ID = unique( MSP430_UARTO_BUS ),
+  };
+
+  components Msp430Uart0P as UartP;
+  Resource = UartP.Resource[ CLIENT_ID ];
+  UartStream = UartP.UartStream;
+  UartByte = UartP.UartByte;
+  UartControl = UartP.UartControl[ CLIENT_ID ];
+  Msp430UartConfigure = UartP.Msp430UartConfigure[ CLIENT_ID ];
+
+  components new Msp430Usart0C() as UsartC;
+  ResourceRequested = UsartC.ResourceRequested;
+  UartP.ResourceConfigure[ CLIENT_ID ] <- UsartC.ResourceConfigure;
+  UartP.UsartResource[ CLIENT_ID ] -> UsartC.Resource;
+  UartP.UsartInterrupts -> UsartC.HplMsp430UsartInterrupts;
+
+}
diff --git a/tos/platforms/eyesIFX/chips/msp430/Msp430Usart0C.nc b/tos/platforms/eyesIFX/chips/msp430/Msp430Usart0C.nc
new file mode 100644 (file)
index 0000000..e73993d
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * Provides an interface for USART0 on the MSP430.
+ *
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+generic configuration Msp430Usart0C() {
+
+  provides interface Resource;
+  provides interface ResourceRequested;  
+  provides interface ArbiterInfo;
+  provides interface HplMsp430Usart;
+  provides interface HplMsp430UsartInterrupts;
+  provides interface HplMsp430I2CInterrupts;
+
+  uses interface ResourceConfigure;
+}
+
+implementation {
+
+  enum {
+    CLIENT_ID = unique( MSP430_HPLUSART0_RESOURCE ),
+  };
+
+  components Msp430UsartShare0P as UsartShareP;
+
+  Resource = UsartShareP.Resource[ CLIENT_ID ];
+  ResourceRequested = UsartShareP.ResourceRequested[ CLIENT_ID ];
+  ResourceConfigure = UsartShareP.ResourceConfigure[ CLIENT_ID ];
+  ArbiterInfo = UsartShareP.ArbiterInfo;
+  HplMsp430UsartInterrupts = UsartShareP.Interrupts[ CLIENT_ID ];
+  HplMsp430I2CInterrupts = UsartShareP.I2CInterrupts[ CLIENT_ID ];
+
+  components HplMsp430Usart0C as UsartC;
+  HplMsp430Usart = UsartC;
+
+}
diff --git a/tos/platforms/eyesIFX/chips/msp430/Msp430UsartShare0P.nc b/tos/platforms/eyesIFX/chips/msp430/Msp430UsartShare0P.nc
new file mode 100644 (file)
index 0000000..ff0ca80
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2005-2006 Arched 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 Arched 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
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archedrock.com>
+ * @version $Revision$ $Date$
+ */
+
+configuration Msp430UsartShare0P {
+
+  provides interface HplMsp430UsartInterrupts as Interrupts[ uint8_t id ];
+  provides interface HplMsp430I2CInterrupts as I2CInterrupts[ uint8_t id ];
+  provides interface Resource[ uint8_t id ];
+  provides interface ResourceRequested[ uint8_t id ];
+  provides interface ArbiterInfo;
+
+  uses interface ResourceConfigure[ uint8_t id ];
+}
+
+implementation {
+
+  components new Msp430UsartShareP() as UsartShareP;
+  Interrupts = UsartShareP;
+  I2CInterrupts = UsartShareP;
+  UsartShareP.RawInterrupts -> UsartC;
+  UsartShareP.RawI2CInterrupts -> UsartC;
+
+  components new FcfsArbiterC( MSP430_HPLUSART0_RESOURCE ) as ArbiterC;
+  Resource = ArbiterC;
+  ResourceRequested = ArbiterC;
+  ResourceConfigure = ArbiterC;
+  ArbiterInfo = ArbiterC;
+  UsartShareP.ArbiterInfo -> ArbiterC;
+
+//  components new AsyncStdControlDeferredPowerManagerC(1) as PowerManagerC;
+//  PowerManagerC.ResourceController -> ArbiterC;
+
+  components HplMsp430Usart0C as UsartC;
+  //PowerManagerC.AsyncStdControl -> UsartC;
+}
diff --git a/tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataIOC.nc b/tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataIOC.nc
new file mode 100644 (file)
index 0000000..d5b6ce3
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+* Copyright (c) 2004, Technische Universitat Berlin
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+*   notice, this list of conditions and the following disclaimer in the
+*   documentation and/or other materials provided with the distribution.
+* - Neither the name of the Technische Universitat Berlin nor the names
+*   of its contributors may be used to endorse or promote products derived
+*   from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+* - Revision -------------------------------------------------------------
+* $Revision$
+* $Date$
+* ========================================================================
+*/
+
+
+/**
+ * Wiring the TDA5250 with the Msp430 Uart abstraction.
+ * 
+ * @author Philipp Hupertz (huppertz@tkn.tu-berlin.de)
+ */
+configuration HplTda5250DataIOC {
+  provides {
+               interface Resource;
+    interface ResourceRequested;
+               interface UartStream;
+    interface HplTda5250DataControl as UartDataControl;
+  }
+}
+implementation {
+
+  components 
+      new Msp430Uart0C(),
+                       HplTda5250DataIOP;
+
+       Resource = Msp430Uart0C.Resource;
+  ResourceRequested = Msp430Uart0C.ResourceRequested;
+  UartStream = Msp430Uart0C.UartStream;
+  UartDataControl = HplTda5250DataIOP.UartDataControl;
+  
+  HplTda5250DataIOP.Msp430UartControl -> Msp430Uart0C.UartControl;
+       HplTda5250DataIOP.UartResourceConfigure <- Msp430Uart0C.Msp430UartConfigure;  
+}
diff --git a/tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataIOP.nc b/tos/platforms/eyesIFX/chips/tda5250/HplTda5250DataIOP.nc
new file mode 100644 (file)
index 0000000..97860d4
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2004, Technische Universitat Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * ========================================================================
+ */
+
+#include "msp430usart.h"
+#include "tda5250BusResourceSettings.h"
+
+ /**
+ * Wrapper module for the Msp430 Uart abstraction.
+ *
+ * @author Philipp Hupertz (huppertz@tkn.tu-berlin.de)
+  */
+module HplTda5250DataIOP {
+  provides {
+    interface HplTda5250DataControl as UartDataControl;
+               interface Msp430UartConfigure as UartResourceConfigure;
+  } 
+  uses {
+    interface  Msp430UartControl;
+  }
+}
+
+implementation {
+  
+  async command error_t UartDataControl.setToTx() {
+    call Msp430UartControl.setModeTx();
+    return SUCCESS;
+  }
+
+  async command error_t UartDataControl.setToRx() {
+    call Msp430UartControl.setModeRx();
+    return SUCCESS;
+  }
+       
+       async command msp430_uart_config_t* UartResourceConfigure.getConfig() {
+               return &tda5250_uart_config;
+       }
+
+}
diff --git a/tos/platforms/eyesIFX/chips/tda5250/Tda5250ASKNFSKFakePinP.nc b/tos/platforms/eyesIFX/chips/tda5250/Tda5250ASKNFSKFakePinP.nc
new file mode 100644 (file)
index 0000000..08a3995
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+* The ASKNFSK Pin is not connected on the eyes platforms...
+*/
+
+module Tda5250ASKNFSKFakePinP {
+  provides interface   GeneralIO;
+}
+
+implementation {
+  async command void GeneralIO.set(){}
+  async command void GeneralIO.clr(){}
+  async command void GeneralIO.toggle(){}
+  async command bool GeneralIO.get(){ return FALSE; }
+  async command void GeneralIO.makeInput(){}
+  async command bool GeneralIO.isOutput() { return FALSE; }
+  async command void GeneralIO.makeOutput(){}
+  async command bool GeneralIO.isInput() { return FALSE; }
+}
diff --git a/tos/platforms/eyesIFX/chips/tda5250/tda5250BusResourceSettings.h b/tos/platforms/eyesIFX/chips/tda5250/tda5250BusResourceSettings.h
new file mode 100644 (file)
index 0000000..3826186
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2006, Technische Universitat Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * ========================================================================
+ */
+
+#include "msp430usart.h"
+
+#ifndef TDA5250BUSRESOURCEID_H
+#define TDA5250BUSRESOURCEID_H
+
+enum {
+    TDA5250_UART_BUS_ID = unique(MSP430_UARTO_BUS)
+};
+
+msp430_uart_config_t tda5250_uart_config = {ubr: UBR_1MHZ_38400, umctl: UMCTL_1MHZ_38400, ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1, listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 1, urxwie: 0};
+
+
+#endif
diff --git a/tos/platforms/eyesIFX/eyesIFXv2/chips/at45db/HplAt45dbC.nc b/tos/platforms/eyesIFX/eyesIFXv2/chips/at45db/HplAt45dbC.nc
new file mode 100644 (file)
index 0000000..860e5ef
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2006, Technische Universitat Berlin
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+*   notice, this list of conditions and the following disclaimer in the
+*   documentation and/or other materials provided with the distribution.
+* - Neither the name of the Technische Universitat Berlin nor the names
+*   of its contributors may be used to endorse or promote products derived
+*   from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+configuration HplAt45dbC {
+  provides interface HplAt45db;
+}
+implementation {
+  
+  components  new HplAt45dbByteC(9), 
+                                                       new Msp430Spi0C() as Spi, 
+                                                       HplAt45dbP,
+                                                       HplMsp430GeneralIOC as MspGeneralIO,
+                                                       new Msp430GpioC() as Select;  
+  
+       HplAt45db = HplAt45dbByteC;
+
+  HplAt45dbByteC.Resource -> Spi;
+  HplAt45dbByteC.FlashSpi -> Spi;
+  HplAt45dbByteC.HplAt45dbByte -> HplAt45dbP;
+       
+       Select -> MspGeneralIO.Port17;
+       HplAt45dbP.Select -> Select; 
+       HplAt45dbP.FlashSpi -> Spi;
+}
diff --git a/tos/platforms/eyesIFX/eyesIFXv2/chips/at45db/HplAt45dbP.nc b/tos/platforms/eyesIFX/eyesIFXv2/chips/at45db/HplAt45dbP.nc
new file mode 100644 (file)
index 0000000..d752b6b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+* Copyright (c) 2006, Technische Universitat Berlin
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+*   notice, this list of conditions and the following disclaimer in the
+*   documentation and/or other materials provided with the distribution.
+* - Neither the name of the Technische Universitat Berlin nor the names
+*   of its contributors may be used to endorse or promote products derived
+*   from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+module HplAt45dbP {
+  provides {
+    interface HplAt45dbByte;
+  }
+  uses {
+               interface SpiByte as FlashSpi;
+    interface GeneralIO as Select;
+  }
+}
+implementation
+{
+  command void HplAt45dbByte.select() {
+    call Select.clr();
+  }
+
+  command void HplAt45dbByte.deselect() {
+    call Select.set();
+  }
+  
+       task void idleTask() {
+               uint8_t status;
+               status = call FlashSpi.write(0);
+               if (!(status & 0x80)) {
+                       post idleTask();
+               } else {
+                       signal HplAt45dbByte.idle();
+               }
+       }
+
+  command void HplAt45dbByte.waitIdle() {
+               post idleTask();
+  }
+  
+  command bool HplAt45dbByte.getCompareStatus() {
+               uint8_t status;
+               status = call FlashSpi.write(0);
+    return (!(status & 0x40));
+  }
+}
diff --git a/tos/platforms/eyesIFX/eyesIFXv2/chips/at45db/HplAt45db_chip.h b/tos/platforms/eyesIFX/eyesIFXv2/chips/at45db/HplAt45db_chip.h
new file mode 100644 (file)
index 0000000..3a1ef27
--- /dev/null
@@ -0,0 +1,45 @@
+// $Id$
+
+/*                                                                     tab:4
+ * "Copyright (c) 2000-2003 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2006 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+#ifndef HPLAT45DB_CHIP_H
+#define HPLAT45DB_CHIP_H
+
+// flash characteristics
+enum {
+  AT45_MAX_PAGES = 2048,
+  AT45_PAGE_SIZE = 264,
+  AT45_PAGE_SIZE_LOG2 = 8 // For those who want to ignore the last 8 bytes
+};
+
+typedef uint16_t at45page_t;
+typedef uint16_t at45pageoffset_t; /* must fit 0 to AT45_PAGE_SIZE - 1 */
+
+#endif
diff --git a/tos/platforms/eyesIFX/sensors/RssiSensorVccP.nc b/tos/platforms/eyesIFX/sensors/RssiSensorVccP.nc
new file mode 100644 (file)
index 0000000..6045941
--- /dev/null
@@ -0,0 +1,99 @@
+/* -*- mode:c++ -*-
+ * Copyright (c) 2004, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet 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.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+/** 
+ *
+ * Please refer to TEP 109 for more information about this component and its
+ * intended use. This component provides platform-independent access to the
+ * RSSI sensor exported by the TDA5250 radio on the eyesIFXv{1,2} platform.
+ * Note: The radio must be configured to output the RSSI on the pin!
+ *
+ * @author Jan Hauer
+ */
+
+#include <sensors.h>
+
+module RssiSensorVccP
+{
+    provides {
+        interface ReadNow<uint16_t> as ReadNow;
+        interface Resource as ReadNowResource;
+    }
+    uses {
+        interface Resource as SubResource;
+        interface Msp430Adc12SingleChannel as SingleChannel;
+    }
+}
+implementation
+{
+    async command error_t ReadNow.read() {
+        return call SingleChannel.getData();
+    }
+    
+    async event error_t SingleChannel.singleDataReady(uint16_t data) {
+      signal ReadNow.readDone(SUCCESS, data);
+      return FAIL;  
+    }
+
+    async event uint16_t* SingleChannel.multipleDataReady(uint16_t buffer[], uint16_t numSamples){
+      return 0;
+    }
+    
+    async command error_t ReadNowResource.request() {
+        return call SubResource.request();
+    }
+    
+    async command error_t ReadNowResource.immediateRequest() {
+        error_t res = call SubResource.immediateRequest();
+        if(res == SUCCESS) {
+            res = call SingleChannel.configureSingle(&sensorconfigurations[RSSI_SENSOR_VCC]);
+            if(res != SUCCESS) call SubResource.release();
+        }
+        return res;
+    }
+
+    event void SubResource.granted() {
+        call SingleChannel.configureSingle(&sensorconfigurations[RSSI_SENSOR_VCC]);
+        signal ReadNowResource.granted();
+    }
+
+    async command error_t ReadNowResource.release() {
+        return call SubResource.release();
+    }
+    
+    async command bool ReadNowResource.isOwner() {
+        return call SubResource.isOwner();
+    }
+}
diff --git a/tos/platforms/intelmote2/BlockStorageC.nc b/tos/platforms/intelmote2/BlockStorageC.nc
new file mode 100644 (file)
index 0000000..a3fa975
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * 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
+ */
+
+/**
+ * Implementation of the block storage abstraction for the pxa271
+ * embedded flash.
+ *
+ * @author Philip Buonadonna
+ * @author Kaisen Lin
+ * @version $Revision$ $Date$
+ */
+
+generic configuration BlockStorageC( volume_id_t volume_id ) {
+
+  provides interface BlockRead;
+  provides interface BlockWrite;
+}
+
+implementation {
+
+  enum {
+    BLOCK_ID = unique( "pxa271p30.Block" ),
+  };
+
+  components P30BlockC as BlockC;
+  BlockRead = BlockC.Read[ volume_id ];
+  BlockWrite = BlockC.Write[ volume_id ];
+
+}
diff --git a/tos/platforms/intelmote2/ConfigStorageC.nc b/tos/platforms/intelmote2/ConfigStorageC.nc
new file mode 100644 (file)
index 0000000..5d0b93f
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * 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
+ */
+
+/**
+ * Configuration component for storage management on the PXA271
+ * 
+ * @author KaisenLin
+ * @author Phil Buonadonna
+ */
+
+generic configuration ConfigStorageC(volume_id_t vol_id) {
+
+  provides interface Mount;
+  provides interface ConfigStorage;
+
+}
+
+implementation {
+  enum {
+    CONFIG_ID = unique( "pxa271p30.Config" ),
+  };
+
+  components P30ConfigC as ConfigC;
+  ConfigStorage = ConfigC.ConfigStorage[ vol_id ];
+  Mount = ConfigC.Mount[ vol_id ];
+}
diff --git a/tos/platforms/intelmote2/LogStorageC.nc b/tos/platforms/intelmote2/LogStorageC.nc
new file mode 100644 (file)
index 0000000..ad0b785
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+/**
+ * @author Kaisen Lin
+ * @author Phil Buonadonna
+ *
+ */
+generic configuration LogStorageC( volume_id_t volume_id, bool circular ) {
+
+  provides interface LogRead;
+  provides interface LogWrite;
+}
+
+implementation {
+
+  enum {
+    LOG_ID = unique( "pxa271p30.Log" ),
+  };
+
+  components P30LogC as LogC;
+  LogRead = LogC.Read[ volume_id ];
+  LogWrite = LogC.Write[ volume_id ];
+
+  components new P30LogCircularP(circular);
+  LogC.Circular[ volume_id ] -> P30LogCircularP.Circular;
+}
diff --git a/tos/platforms/intelmote2/chips/ds2745/DS2745InternalC.nc b/tos/platforms/intelmote2/chips/ds2745/DS2745InternalC.nc
new file mode 100644 (file)
index 0000000..538d9be
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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 Arched 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
+ */
+
+/**
+ * 
+ * @author Phil Buonadonna <pbuonadonna@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+configuration DS2745InternalC {
+  provides interface SplitControl;
+  provides interface Resource[uint8_t id];
+  provides interface HplDS2745[uint8_t id];
+}
+
+implementation {
+  components new SimpleFcfsArbiterC( "Ds2745.Resource" ) as Arbiter;
+  components MainC;
+  Resource = Arbiter;
+  
+  components new HplDS2745LogicP(DS2745_SLAVE_ADDR) as Logic;
+  MainC.SoftwareInit -> Logic;
+
+  components new HalPXA27xI2CMasterC(TRUE) as I2CC;
+  Logic.I2CPacket -> I2CC;
+
+  components HplPXA27xGPIOC;
+  I2CC.I2CSCL -> HplPXA27xGPIOC.HplPXA27xGPIOPin[I2C_SCL];
+  I2CC.I2CSDA -> HplPXA27xGPIOC.HplPXA27xGPIOPin[I2C_SDA];
+
+  components DS2745InternalP as Internal;
+  HplDS2745 = Internal.HplDS2745;
+  Internal.ToHPLC -> Logic.HplDS2745;
+
+  SplitControl = Logic;
+
+}
diff --git a/tos/platforms/intelmote2/chips/ds2745/DS2745InternalP.nc b/tos/platforms/intelmote2/chips/ds2745/DS2745InternalP.nc
new file mode 100644 (file)
index 0000000..e4845f4
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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 Arched 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
+ */
+
+/**
+ * 
+ * @author Phil Buonadonna <pbuonadonna@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+module DS2745InternalP {
+  provides interface HplDS2745[uint8_t id];
+  uses interface HplDS2745 as ToHPLC;
+}
+
+implementation {
+  uint8_t currentId;
+  
+  command error_t HplDS2745.setConfig[uint8_t id](uint8_t val) {
+    currentId = id;
+    return call ToHPLC.setConfig(val);
+  }
+  command error_t HplDS2745.measureTemperature[uint8_t id]() {
+    currentId = id;
+    return call ToHPLC.measureTemperature();
+  }
+  command error_t HplDS2745.measureVoltage[uint8_t id]() {
+    currentId = id;
+    return call ToHPLC.measureVoltage();
+  }
+  command error_t HplDS2745.measureCurrent[uint8_t id]() {
+    currentId = id;
+    return call ToHPLC.measureCurrent();
+  }
+  command error_t HplDS2745.measureAccCurrent[uint8_t id]() {
+    currentId = id;
+    return call ToHPLC.measureAccCurrent();
+  }
+  command error_t HplDS2745.setOffsetBias[uint8_t id](int8_t val) {
+    currentId = id;
+    return call ToHPLC.setOffsetBias(val);
+  }
+  command error_t HplDS2745.setAccOffsetBias[uint8_t id](int8_t val) {
+    currentId = id;
+    return call ToHPLC.setAccOffsetBias(val);
+  }
+  
+  async event void ToHPLC.setConfigDone(error_t error) {
+    signal HplDS2745.setConfigDone[currentId](error);
+  }
+  async event void ToHPLC.measureTemperatureDone(error_t result, uint16_t val) {
+    signal HplDS2745.measureTemperatureDone[currentId](result, val);
+  }
+  async event void ToHPLC.measureVoltageDone(error_t result, uint16_t val) {
+    signal HplDS2745.measureVoltageDone[currentId](result, val);
+  }
+  async event void ToHPLC.measureCurrentDone(error_t result, uint16_t val) {
+    signal HplDS2745.measureCurrentDone[currentId](result, val);
+  }
+  async event void ToHPLC.measureAccCurrentDone(error_t result, uint16_t val) {
+    signal HplDS2745.measureAccCurrentDone[currentId](result, val);
+  }
+  async event void ToHPLC.setOffsetBiasDone(error_t error) {
+    signal HplDS2745.setOffsetBiasDone[currentId](error);
+  }
+  async event void ToHPLC.setAccOffsetBiasDone(error_t error) {
+    signal HplDS2745.setAccOffsetBiasDone[currentId](error);
+  }
+
+  default async event void HplDS2745.setConfigDone[uint8_t id]( error_t error ){ return; }
+  default async event void HplDS2745.measureTemperatureDone[uint8_t id]( error_t error, uint16_t val ){ return; }
+  default async event void HplDS2745.measureVoltageDone[uint8_t id]( error_t error, uint16_t val ){ return; }
+  default async event void HplDS2745.measureCurrentDone[uint8_t id]( error_t error, uint16_t val ){ return; }
+  default async event void HplDS2745.measureAccCurrentDone[uint8_t id]( error_t error, uint16_t val ){ return; }
+  default async event void HplDS2745.setOffsetBiasDone[uint8_t id]( error_t error ){ return; }
+  default async event void HplDS2745.setAccOffsetBiasDone[uint8_t id](error_t error){ return; }
+
+}
+
+
diff --git a/tos/platforms/tinynode/DemoSensorNowC.nc b/tos/platforms/tinynode/DemoSensorNowC.nc
new file mode 100644 (file)
index 0000000..028e231
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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$ $Date$
+ * 
+ */
+
+generic configuration DemoSensorNowC()
+{
+  provides interface Resource;
+  provides interface ReadNow<uint16_t>;
+}
+implementation
+{
+  components new Msp430InternalVoltageC() as DemoSensorNow;
+
+  Resource = DemoSensorNow;
+  ReadNow = DemoSensorNow;
+}
diff --git a/tos/platforms/tinynode/DemoSensorStreamC.nc b/tos/platforms/tinynode/DemoSensorStreamC.nc
new file mode 100644 (file)
index 0000000..d94e5ee
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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$ $Date$
+ * 
+ */
+
+generic configuration DemoSensorStreamC()
+{
+  provides interface ReadStream<uint16_t>;
+}
+implementation
+{
+  components new VoltageStreamC() as DemoSensor;
+  ReadStream = DemoSensor;
+}
diff --git a/tos/platforms/tinynode/VoltageStreamC.nc b/tos/platforms/tinynode/VoltageStreamC.nc
new file mode 100644 (file)
index 0000000..2c27834
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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$ $Date$
+ */
+
+generic configuration VoltageStreamC() {
+  provides interface ReadStream<uint16_t>;
+}
+implementation {
+  components new Msp430InternalVoltageC();
+  ReadStream = Msp430InternalVoltageC.ReadStream;
+}
+
diff --git a/tos/platforms/tinynode/chips/at45db/HplAt45dbC.nc b/tos/platforms/tinynode/chips/at45db/HplAt45dbC.nc
new file mode 100644 (file)
index 0000000..f855342
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2006, Technische Universitat Berlin
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+*   notice, this list of conditions and the following disclaimer in the
+*   documentation and/or other materials provided with the distribution.
+* - Neither the name of the Technische Universitat Berlin nor the names
+*   of its contributors may be used to endorse or promote products derived
+*   from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+configuration HplAt45dbC {
+  provides interface HplAt45db;
+}
+implementation {
+  
+  components  new HplAt45dbByteC(9), 
+    new Msp430Spi0C() as Spi, 
+    HplAt45dbP,
+    HplMsp430GeneralIOC as MspGeneralIO,
+    new Msp430GpioC() as Select;  
+  
+  HplAt45db = HplAt45dbByteC;
+  
+  HplAt45dbByteC.Resource -> Spi;
+  HplAt45dbByteC.FlashSpi -> Spi;
+  HplAt45dbByteC.HplAt45dbByte -> HplAt45dbP;
+  
+  Select -> MspGeneralIO.Port47;
+  HplAt45dbP.Select -> Select; 
+  HplAt45dbP.FlashSpi -> Spi;
+}
diff --git a/tos/platforms/tinynode/chips/at45db/HplAt45dbP.nc b/tos/platforms/tinynode/chips/at45db/HplAt45dbP.nc
new file mode 100644 (file)
index 0000000..683e4a8
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+* Copyright (c) 2006, Technische Universitat Berlin
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright notice,
+*   this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+*   notice, this list of conditions and the following disclaimer in the
+*   documentation and/or other materials provided with the distribution.
+* - Neither the name of the Technische Universitat Berlin nor the names
+*   of its contributors may be used to endorse or promote products derived
+*   from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+module HplAt45dbP {
+  provides {
+    interface HplAt45dbByte;
+  }
+  uses {
+    interface SpiByte as FlashSpi;
+    interface GeneralIO as Select;
+  }
+}
+implementation
+{
+  command void HplAt45dbByte.select() {
+    call Select.clr();
+  }
+  
+  command void HplAt45dbByte.deselect() {
+    call Select.set();
+  }
+  
+  task void idleTask() {
+    uint8_t status;
+    status = call FlashSpi.write(0);
+    if (!(status & 0x80)) {
+      post idleTask();
+    } else {
+      signal HplAt45dbByte.idle();
+    }
+  }
+  
+  command void HplAt45dbByte.waitIdle() {
+    post idleTask();
+  }
+  
+  command bool HplAt45dbByte.getCompareStatus() {
+    uint8_t status;
+    status = call FlashSpi.write(0);
+    return (!(status & 0x40));
+  }
+}
diff --git a/tos/platforms/tinynode/chips/at45db/HplAt45db_chip.h b/tos/platforms/tinynode/chips/at45db/HplAt45db_chip.h
new file mode 100644 (file)
index 0000000..3a1ef27
--- /dev/null
@@ -0,0 +1,45 @@
+// $Id$
+
+/*                                                                     tab:4
+ * "Copyright (c) 2000-2003 The Regents of the University  of California.  
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2006 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+#ifndef HPLAT45DB_CHIP_H
+#define HPLAT45DB_CHIP_H
+
+// flash characteristics
+enum {
+  AT45_MAX_PAGES = 2048,
+  AT45_PAGE_SIZE = 264,
+  AT45_PAGE_SIZE_LOG2 = 8 // For those who want to ignore the last 8 bytes
+};
+
+typedef uint16_t at45page_t;
+typedef uint16_t at45pageoffset_t; /* must fit 0 to AT45_PAGE_SIZE - 1 */
+
+#endif
diff --git a/tos/system/ArbiterP.nc b/tos/system/ArbiterP.nc
new file mode 100644 (file)
index 0000000..6bb79a2
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2004, Technische Universitat Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**
+ * Please refer to TEP 108 for more information about this component and its
+ * intended use.<br><br>
+ *
+ * This component provides the Resource, ResourceRequested, ArbiterInfo, 
+ * and ResourceController interfaces and uses the ResourceConfigure interface as
+ * described in TEP 108.  It provides arbitration to a shared resource.
+ * An Queue is used to keep track of which users have put
+ * in requests for the resource.  Upon the release of the resource by one
+ * of these users, the queue is checked and the next user
+ * that has a pending request will ge granted control of the resource.  If
+ * there are no pending requests, then the user of the ResourceController
+ * interface gains access to the resource, and holds onto it until
+ * another user makes a request.
+ *
+ * @param <b>resourceName</b> -- The name of the Resource being shared
+ * 
+ * @author Kevin Klues (klues@tkn.tu-berlin.de)
+ * @author Philip Levis
+ */
+generic module ArbiterP(uint8_t controller_id) {
+  provides {
+    interface Resource[uint8_t id];
+    interface ResourceRequested[uint8_t id];
+    interface ResourceController;
+    interface ArbiterInfo;
+  }
+  uses {
+    interface ResourceConfigure[uint8_t id];
+    interface ResourceQueue as Queue;
+    interface Leds;
+  }
+}
+implementation {
+
+  enum {RES_CONTROLLED, RES_GRANTING, RES_IMM_GRANTING, RES_BUSY};
+  enum {CONTROLLER_ID = controller_id};
+
+  uint8_t state = RES_CONTROLLED;
+  norace uint8_t resId = CONTROLLER_ID;
+  norace uint8_t reqResId;
+  
+  task void grantedTask();
+  
+  async command error_t Resource.request[uint8_t id]() {
+    signal ResourceRequested.requested[resId]();
+    atomic {
+      if(state == RES_CONTROLLED) {
+        state = RES_GRANTING;
+        reqResId = id;
+      }
+      else return call Queue.enqueue(id);
+    }
+    signal ResourceController.requested();
+    return SUCCESS;
+  }
+
+  async command error_t Resource.immediateRequest[uint8_t id]() {
+    signal ResourceRequested.immediateRequested[resId]();
+    atomic {
+      if(state == RES_CONTROLLED) {
+        state = RES_IMM_GRANTING;
+        reqResId = id;
+      }
+      else return FAIL;
+    }
+    signal ResourceController.immediateRequested();
+    if(resId == id) {
+      call ResourceConfigure.configure[resId]();
+      return SUCCESS;
+    }
+    atomic state = RES_CONTROLLED;
+    return FAIL;
+  }
+  
+  async command error_t Resource.release[uint8_t id]() {
+    atomic {
+      if(state == RES_BUSY && resId == id) {
+        if(call Queue.isEmpty() == FALSE) {
+          reqResId = call Queue.dequeue();
+          state = RES_GRANTING;
+          post grantedTask();
+        }
+        else {
+          resId = CONTROLLER_ID;
+          state = RES_CONTROLLED;
+          signal ResourceController.granted();
+        }
+        call ResourceConfigure.unconfigure[id]();
+      }
+    }
+    return FAIL;
+  }
+
+  async command error_t ResourceController.release() {
+    atomic {
+      if(resId == CONTROLLER_ID) {
+        if(state == RES_GRANTING) {
+          post grantedTask();
+          return SUCCESS;
+        }
+        else if(state == RES_IMM_GRANTING) {
+          resId = reqResId;
+          state = RES_BUSY;
+          return SUCCESS;
+        }
+      }
+    }
+    return FAIL;
+  }
+    
+  /**
+    Check if the Resource is currently in use
+  */    
+  async command bool ArbiterInfo.inUse() {
+    return TRUE;
+  }
+
+  /**
+    Returns the current user of the Resource.
+    If there is no current user, the return value
+    will be 0xFF
+  */      
+  async command uint8_t ArbiterInfo.userId() {
+    atomic return resId;
+  }
+
+  /**
+   * Returns my user id.
+   */      
+  async command uint8_t Resource.isOwner[uint8_t id]() {
+    atomic {
+      if(resId == id) return TRUE;
+      else return FALSE;
+    }
+  }
+
+  async command uint8_t ResourceController.isOwner() {
+    return call Resource.isOwner[CONTROLLER_ID]();
+  }
+  
+  task void grantedTask() {
+    atomic {
+      resId = reqResId;
+      state = RES_BUSY;
+    }
+    call ResourceConfigure.configure[resId]();
+    signal Resource.granted[resId]();
+  }
+  
+  //Default event/command handlers for all of the other
+    //potential users/providers of the parameterized interfaces 
+    //that have not been connected to.  
+  default event void Resource.granted[uint8_t id]() {
+  }
+  default async event void ResourceRequested.requested[uint8_t id]() {
+  }
+  default async event void ResourceRequested.immediateRequested[uint8_t id]() {
+  }
+  default async event void ResourceController.granted() {
+  }
+  default async event void ResourceController.requested() {
+    call ResourceController.release();
+  }
+  default async event void ResourceController.immediateRequested() {
+       call ResourceController.release();
+  }
+  default async command void ResourceConfigure.configure[uint8_t id]() {
+  }
+  default async command void ResourceConfigure.unconfigure[uint8_t id]() {
+  }
+}
diff --git a/tos/system/FcfsResourceQueueC.nc b/tos/system/FcfsResourceQueueC.nc
new file mode 100644 (file)
index 0000000..7be5ed4
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * "Copyright (c) 2005 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+
+/**
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+#include "Resource.h"
+generic module FcfsResourceQueueC(uint8_t size) {
+  provides {
+    interface Init;
+    interface ResourceQueue as FcfsQueue;
+  }
+}
+implementation {
+  enum {NO_ENTRY = 0xFF};
+
+  uint8_t resQ[size];
+  uint8_t qHead = NO_ENTRY;
+  uint8_t qTail = NO_ENTRY;
+
+  command error_t Init.init() {
+    memset(resQ, NO_ENTRY, sizeof(resQ));
+    return SUCCESS;
+  }  
+  
+  async command bool FcfsQueue.isEmpty() {
+    return (qHead == NO_ENTRY);
+  }
+       
+  async command bool FcfsQueue.isEnqueued(resource_client_id_t id) {
+       return resQ[id] != NO_ENTRY || qTail == id; 
+  }
+
+  async command resource_client_id_t FcfsQueue.dequeue() {
+    atomic {
+      if(qHead != NO_ENTRY) {
+        uint8_t id = qHead;
+        qHead = resQ[qHead];
+        if(qHead == NO_ENTRY)
+          qTail = NO_ENTRY;
+        resQ[id] = NO_ENTRY;
+        return id;
+      }
+      return NO_ENTRY;
+    }
+  }
+  
+  async command error_t FcfsQueue.enqueue(resource_client_id_t id) {
+    atomic {
+      if(!(call FcfsQueue.isEnqueued(id))) {
+        if(qHead == NO_ENTRY)
+               qHead = id;
+             else
+             resQ[qTail] = id;
+             qTail = id;
+        return SUCCESS;
+      }
+      return EBUSY;
+    }
+  }
+}
diff --git a/tos/system/RoundRobinResourceQueueC.nc b/tos/system/RoundRobinResourceQueueC.nc
new file mode 100644 (file)
index 0000000..b6d5565
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * "Copyright (c) 2005 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+
+/**
+ *
+ * @author Kevin Klues (klueska@cs.wustl.edu)
+ * @version $Revision$
+ * @date $Date$
+ */
+#include "Resource.h"
+generic module RoundRobinResourceQueueC(uint8_t size) {
+  provides {
+    interface Init;
+    interface ResourceQueue as RoundRobinQueue;
+  }
+}
+implementation {
+  enum {NO_ENTRY = 0xFF};
+
+  uint8_t resQ[(size-1)/8 + 1];
+  uint8_t last = 0;
+
+  void clearEntry(uint8_t id) {
+    resQ[id / 8] &= ~(1 << (id % 8));
+  }
+
+  command error_t Init.init() {
+    memset(resQ, 0, sizeof(resQ));
+    return SUCCESS;
+  }  
+  
+  async command bool RoundRobinQueue.isEmpty() {
+    int i;
+    atomic {
+      for (i = 0; i<sizeof(resQ); i++)
+        if(resQ[i] > 0) return FALSE;
+      return TRUE;
+    }
+  }
+       
+  async command bool RoundRobinQueue.isEnqueued(resource_client_id_t id) {
+       return resQ[id / 8] & (1 << (id % 8));
+  }
+
+  async command resource_client_id_t RoundRobinQueue.dequeue() {
+    int i;
+    atomic {
+      for (i = last+1; ; i++) {
+        if(i == size)
+          i = 0;
+        if (call RoundRobinQueue.isEnqueued(i)) {
+          clearEntry(i);
+          last = i;
+          return i;
+        }
+        if (i == last)
+          break;
+      }
+      return NO_ENTRY;
+    }
+  }
+  
+  async command error_t RoundRobinQueue.enqueue(resource_client_id_t id) {
+    atomic {
+      if (!(call RoundRobinQueue.isEnqueued(id))) {
+        resQ[id / 8] |=  1 << (id % 8);
+        return SUCCESS;
+      }
+      return EBUSY;
+    }
+  }
+}
diff --git a/tos/system/SimpleArbiterP.nc b/tos/system/SimpleArbiterP.nc
new file mode 100644 (file)
index 0000000..a3cfcae
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2004, Technische Universitat Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**
+ * Please refer to TEP 108 for more information about this component and its
+ * intended use.<br><br>
+ *
+ * This component provides the Resource, ArbiterInfo, and ResourceRequested
+ * interfaces and uses the ResourceConfigure interface as
+ * described in TEP 108.  It provides arbitration to a shared resource.
+ * An queue is used to keep track of which users have put
+ * in requests for the resource.  Upon the release of the resource by one
+ * of these users, the queue is checked and the next user
+ * that has a pending request will ge granted control of the resource.  If
+ * there are no pending requests, then the resource becomes idle and any
+ * user can put in a request and immediately receive access to the
+ * Resource.
+ *
+ * @param <b>resourceName</b> -- The name of the Resource being shared
+ * 
+ * @author Kevin Klues (klues@tkn.tu-berlin.de)
+ * @author Philip Levis
+ */
+generic module SimpleArbiterP() {
+  provides {
+    interface Resource[uint8_t id];
+    interface ResourceRequested[uint8_t id];
+    interface ArbiterInfo;
+  }
+  uses {
+    interface ResourceConfigure[uint8_t id];
+    interface ResourceQueue as Queue;
+  }
+}
+implementation {
+
+  enum {RES_IDLE = 0, RES_GRANTING = 1, RES_BUSY = 2};
+  enum {NO_RES = 0xFF};
+
+  uint8_t state = RES_IDLE;
+  norace uint8_t resId = NO_RES;
+  norace uint8_t reqResId;
+  
+  task void grantedTask();
+  
+  async command error_t Resource.request[uint8_t id]() {
+    signal ResourceRequested.requested[resId]();
+    atomic {
+      if(state == RES_IDLE) {
+        state = RES_GRANTING;
+        reqResId = id;
+        post grantedTask();
+        return SUCCESS;
+      }
+      return call Queue.enqueue(id);
+    }
+  }
+
+  async command error_t Resource.immediateRequest[uint8_t id]() {
+    signal ResourceRequested.immediateRequested[resId]();
+    atomic {
+      if(state == RES_IDLE) {
+        state = RES_BUSY;
+        resId = id;
+        call ResourceConfigure.configure[resId]();
+        return SUCCESS;
+      }
+      return FAIL;
+    }
+  }
+   
+  async command error_t Resource.release[uint8_t id]() {
+    bool released = FALSE;
+    atomic {
+      if(state == RES_BUSY && resId == id) {
+        if(call Queue.isEmpty() == FALSE) {
+          reqResId = call Queue.dequeue();
+          state = RES_GRANTING;
+          post grantedTask();
+        }
+        else {
+          resId = NO_RES;
+          state = RES_IDLE;
+        }
+        released = TRUE;
+      }
+    }
+    if(released == TRUE) {
+           call ResourceConfigure.unconfigure[id]();
+      return SUCCESS;
+    }
+    return FAIL;
+  }
+    
+  /**
+    Check if the Resource is currently in use
+  */    
+  async command bool ArbiterInfo.inUse() {
+    atomic {
+      if (state == RES_IDLE)
+        return FALSE;
+    }
+    return TRUE;
+  }
+
+  /**
+    Returns the current user of the Resource.
+    If there is no current user, the return value
+    will be 0xFF
+  */      
+  async command uint8_t ArbiterInfo.userId() {
+    atomic return resId;
+  }
+
+  /**
+   * Returns whether you are the current owner of the resource or not
+   */      
+  async command uint8_t Resource.isOwner[uint8_t id]() {
+    atomic {
+      if(resId == id) return TRUE;
+      else return FALSE;
+    }
+  }
+  
+  task void grantedTask() {
+    atomic {
+      resId = reqResId;
+      state = RES_BUSY;
+    }
+    call ResourceConfigure.configure[resId]();
+    signal Resource.granted[resId]();
+  }
+  
+  //Default event/command handlers
+  default event void Resource.granted[uint8_t id]() {
+  }
+  default async event void ResourceRequested.requested[uint8_t id]() {
+  }
+  default async event void ResourceRequested.immediateRequested[uint8_t id]() {
+  }
+  default async command void ResourceConfigure.configure[uint8_t id]() {
+  }
+  default async command void ResourceConfigure.unconfigure[uint8_t id]() {
+  }
+}
diff --git a/tos/system/SimpleFcfsArbiterC.nc b/tos/system/SimpleFcfsArbiterC.nc
new file mode 100644 (file)
index 0000000..9d7a7d0
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * "Copyright (c) 2005 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON 
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/*
+ * Copyright (c) 2004, Technische Universitat Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**
+ * Please refer to TEP 108 for more information about this component and its
+ * intended use.<br><br>
+ *
+ * This component provides the Resource, ArbiterInfo, and Resource
+ * Controller interfaces and uses the ResourceConfigure interface as
+ * described in TEP 108.  It provides arbitration to a shared resource in
+ * an FCFS fashion.  An array is used to keep track of which users have put
+ * in requests for the resource.  Upon the release of the resource by one
+ * of these users, the array is checked and the next user (in FCFS order)
+ * that has a pending request will ge granted control of the resource.  If
+ * there are no pending requests, then the resource becomes idle and any
+ * user can put in a request and immediately receive access to the
+ * Resource.
+ *
+ * @param <b>resourceName</b> -- The name of the Resource being shared
+ * 
+ * @author Kevin Klues (klues@tkn.tu-berlin.de)
+ * @author Philip Levis
+ */
+generic configuration SimpleFcfsArbiterC(char resourceName[]) {
+  provides {
+    interface Resource[uint8_t id];
+    interface ResourceRequested[uint8_t id];
+    interface ArbiterInfo;
+  }
+  uses interface ResourceConfigure[uint8_t id];
+}
+implementation {
+  components MainC;
+  components new FcfsResourceQueueC(uniqueCount(resourceName)) as Queue;
+  components new SimpleArbiterP() as Arbiter;
+
+  MainC.SoftwareInit -> Queue;
+
+  Resource = Arbiter;
+  ResourceRequested = Arbiter;
+  ArbiterInfo = Arbiter;
+  ResourceConfigure = Arbiter;
+
+  Arbiter.Queue -> Queue;
+}
diff --git a/tos/system/SimpleRoundRobinArbiterC.nc b/tos/system/SimpleRoundRobinArbiterC.nc
new file mode 100644 (file)
index 0000000..86c3b3e
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * "Copyright (c) 2005 Washington University in St. Louis.
+ * 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 WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON 
+ * UNIVERSITY IN ST. LOUIS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * WASHINGTON UNIVERSITY IN ST. LOUIS 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 WASHINGTON UNIVERSITY IN ST. LOUIS HAS NO 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS."
+ */
+/*
+ * Copyright (c) 2004, Technische Universitat Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**
+ * Please refer to TEP 108 for more information about this component and its
+ * intended use.<br><br>
+ *
+ * This component provides the Resource, ArbiterInfo, and Resource
+ * Controller interfaces and uses the ResourceConfigure interface as
+ * described in TEP 108.  It provides arbitration to a shared resource in
+ * an FCFS fashion.  An array is used to keep track of which users have put
+ * in requests for the resource.  Upon the release of the resource by one
+ * of these users, the array is checked and the next user (in FCFS order)
+ * that has a pending request will ge granted control of the resource.  If
+ * there are no pending requests, then the resource becomes idle and any
+ * user can put in a request and immediately receive access to the
+ * Resource.
+ *
+ * @param <b>resourceName</b> -- The name of the Resource being shared
+ * 
+ * @author Kevin Klues (klues@tkn.tu-berlin.de)
+ * @author Philip Levis
+ */
+generic configuration SimpleRoundRobinArbiterC(char resourceName[]) {
+  provides {
+    interface Resource[uint8_t id];
+    interface ResourceRequested[uint8_t id];
+    interface ArbiterInfo;
+  }
+  uses interface ResourceConfigure[uint8_t id];
+}
+implementation {
+  components MainC;
+  components new RoundRobinResourceQueueC(uniqueCount(resourceName)) as Queue;
+  components new SimpleArbiterP() as Arbiter;
+
+  MainC.SoftwareInit -> Queue;
+
+  Resource = Arbiter;
+  ResourceRequested = Arbiter;
+  ArbiterInfo = Arbiter;
+  ResourceConfigure = Arbiter;
+
+  Arbiter.Queue -> Queue;
+}
diff --git a/tos/system/SineSensorC.nc b/tos/system/SineSensorC.nc
new file mode 100644 (file)
index 0000000..cd11123
--- /dev/null
@@ -0,0 +1,45 @@
+/* $Id$
+ * Copyright (c) 2006 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE     
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+/**
+ * The micaZ doesn't have any built-in sensors - the DemoSensor returns
+ * a constant value of 0xbeef, or just reads the ground value for the
+ * stream sensor.
+ *
+ * @author Philip Levis
+ * @authod David Gay
+ */
+
+generic module SineSensorC()
+{
+  provides interface Init;
+  provides interface Read<uint16_t>;
+}
+implementation {
+
+  uint32_t counter;
+
+  command error_t Init.init() {
+    counter = TOS_NODE_ID * 40;
+    return SUCCESS;
+  }
+  
+  task void readTask() {
+    float val = (float)counter;
+    val = val / 20.0;
+    val = sin(val) * 32768.0;
+    val += 32768.0;
+    counter++;
+    signal Read.readDone(SUCCESS, (uint16_t)val);
+  }
+  command error_t Read.read() {
+    post readTask();
+    return SUCCESS;
+  }
+}
diff --git a/tos/system/State.nc b/tos/system/State.nc
new file mode 100644 (file)
index 0000000..0b5507f
--- /dev/null
@@ -0,0 +1,68 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+\r
+/**\r
+ * State machine interface\r
+ * @author David Moss - dmm@rincon.com\r
+ */\r
\r
+interface State {\r
+\r
+  /**\r
+   * This will allow a state change so long as the current\r
+   * state is S_IDLE.\r
+   * @return SUCCESS if the state is change, FAIL if it isn't\r
+   */\r
+  async command error_t requestState(uint8_t reqState);\r
+  \r
+  /**\r
+   * Force the state machine to go into a certain state,\r
+   * regardless of the current state it's in.\r
+   */\r
+  async command void forceState(uint8_t reqState);\r
+  \r
+  /**\r
+   * Set the current state back to S_IDLE\r
+   */\r
+  async command void toIdle();\r
+  \r
+  /**\r
+   * @return TRUE if the state machine is in S_IDLE\r
+   */\r
+  async command bool isIdle();\r
+  \r
+  /**\r
+   * Get the current state\r
+   */\r
+  async command uint8_t getState();\r
+\r
+}\r
diff --git a/tos/system/StateC.nc b/tos/system/StateC.nc
new file mode 100644 (file)
index 0000000..150641e
--- /dev/null
@@ -0,0 +1,78 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+\r
+/**\r
+ * This is a state controller for any and every component's\r
+ * state machine(s).\r
+ *\r
+ * There are several compelling reasons to use the State module/interface\r
+ * in all your components that have any kind of state associated with them:\r
+ *\r
+ *   1) It provides a unified interface to control any state, which makes\r
+ *      it easy for everyone to understand your code\r
+ *   2) You can easily keep track of multiple state machines in one component\r
+ *   3) You could have one state machine control several components\r
+ *\r
+ * There are three ways to change a component's state:\r
+ *  > Request a state change\r
+ *     The state is only changed if the state is currently in S_IDLE.  If\r
+ *     the state changes and access is grated, requestState returns SUCCESS.\r
+ *\r
+ *  > Force a state change\r
+ *     The state changes no matter what\r
+ * \r
+ *  > toIdle()\r
+ *     The state changes to S_IDLE, no matter what state the component is in.\r
+ *\r
+ * S_IDLE is the default state, and is always equal to 0.  Therefore,\r
+ * setup the enums in your internal component so the IDLE/default state is\r
+ * always 0.\r
+ *\r
+ * @author David Moss - dmm@rincon.com\r
+ */\r
\r
+#include "State.h"\r
+\r
+generic configuration StateC() {\r
+  provides {\r
+    interface State;\r
+  }\r
+}\r
+\r
+implementation {\r
+  components StateImplC;\r
+\r
+  State = StateImplC.State[unique(UQ_STATE)];\r
+}\r
+\r
+\r
+\r
diff --git a/tos/system/StateImplC.nc b/tos/system/StateImplC.nc
new file mode 100644 (file)
index 0000000..65b37de
--- /dev/null
@@ -0,0 +1,78 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * This is a state controller for any and every component's\r
+ * state machine(s).\r
+ *\r
+ * There are several compelling reasons to use the State module/interface\r
+ * in all your components that have any kind of state associated with them:\r
+ *\r
+ *   1) It provides a unified interface to control any state, which makes\r
+ *      it easy for everyone to understand your code\r
+ *   2) You can easily keep track of multiple state machines in one component\r
+ *   3) You could have one state machine control several components\r
+ *\r
+ * There are three ways to change a component's state:\r
+ *  > Request a state change\r
+ *     The state is only changed if the state is currently in S_IDLE.  If\r
+ *     the state changes and access is grated, requestState returns SUCCESS.\r
+ *\r
+ *  > Force a state change\r
+ *     The state changes no matter what\r
+ * \r
+ *  > toIdle()\r
+ *     The state changes to S_IDLE, no matter what state the component is in.\r
+ *\r
+ * S_IDLE is the default state, and is always equal to 0.  Therefore,\r
+ * setup the enums in your internal component so the IDLE/default state is\r
+ * always 0.\r
+ *\r
+ * @author David Moss - dmm@rincon.com\r
+ */\r
+\r
+#include "State.h"\r
+\r
+configuration StateImplC {\r
+  provides {\r
+    interface State[uint8_t id];\r
+  }\r
+}\r
+\r
+implementation {\r
+  components MainC, \r
+      StateImplP;\r
+\r
+  MainC.SoftwareInit -> StateImplP;\r
+  State = StateImplP;\r
+  \r
+}\r
+\r
diff --git a/tos/system/StateImplP.nc b/tos/system/StateImplP.nc
new file mode 100644 (file)
index 0000000..a14ea79
--- /dev/null
@@ -0,0 +1,138 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * This is a state controller for any and every component's\r
+ * state machine(s).\r
+ *\r
+ * There are several compelling reasons to use the State module/interface\r
+ * in all your components that have any kind of state associated with them:\r
+ *\r
+ *   1) It provides a unified interface to control any state, which makes\r
+ *      it easy for everyone to understand your code\r
+ *   2) You can easily keep track of multiple state machines in one component\r
+ *   3) You could have one state machine control several components\r
+ *\r
+ * There are three ways to change a component's state:\r
+ *  > Request a state change\r
+ *     The state is only changed if the state is currently in S_IDLE.  If\r
+ *     the state changes and access is grated, requestState returns SUCCESS.\r
+ *\r
+ *  > Force a state change\r
+ *     The state changes no matter what\r
+ * \r
+ *  > toIdle()\r
+ *     The state changes to S_IDLE, no matter what state the component is in.\r
+ *\r
+ * S_IDLE is the default state, and is always equal to 0.  Therefore,\r
+ * setup the enums in your internal component so the IDLE/default state is\r
+ * always 0.\r
+ *\r
+ * @author David Moss - dmm@rincon.com\r
+ */\r
\r
+#include "State.h"\r
\r
+module StateImplP {\r
+  provides {\r
+       interface Init;\r
+    interface State[uint8_t id];\r
+  }\r
+}\r
+\r
+implementation {\r
+\r
+  /** Each component's state - uniqueCount("State") of them */\r
+  norace uint8_t state[uniqueCount(UQ_STATE)];\r
+  \r
+  enum {\r
+    S_IDLE = 0,\r
+  };\r
+\r
+  /***************** Init Commands ****************/\r
+  command error_t Init.init() {\r
+    int i;\r
+    for(i = 0; i < uniqueCount(UQ_STATE); i++) {\r
+      state[i] = S_IDLE;\r
+    }\r
+    return SUCCESS;\r
+  }\r
+  \r
+  \r
+  /***************** State Commands ****************/  \r
+  /**\r
+   * This will allow a state change so long as the current\r
+   * state is S_IDLE.\r
+   * @return SUCCESS if the state is change, FAIL if it isn't\r
+   */\r
+  async command error_t State.requestState[uint8_t id](uint8_t reqState) {\r
+    error_t returnVal = FAIL;\r
+    atomic {\r
+      if(reqState == S_IDLE || state[id] == S_IDLE) {\r
+        state[id] = reqState;\r
+        returnVal = SUCCESS;\r
+      }\r
+    }\r
+    return returnVal;\r
+  }\r
+  \r
+  /**\r
+   * Force the state machine to go into a certain state,\r
+   * regardless of the current state it's in.\r
+   */\r
+  async command void State.forceState[uint8_t id](uint8_t reqState) {\r
+    state[id] = reqState;\r
+  }\r
+    \r
+  /**\r
+   * Set the current state back to S_IDLE\r
+   */\r
+  async command void State.toIdle[uint8_t id]() {\r
+    state[id] = S_IDLE;\r
+  }\r
+  \r
+    \r
+  /**\r
+   * @return TRUE if the state machine is in S_IDLE\r
+   */\r
+  async command bool State.isIdle[uint8_t id]() {\r
+    return state[id] == S_IDLE;\r
+  }\r
+  \r
+  /**\r
+   * Get the current state\r
+   */\r
+  async command uint8_t State.getState[uint8_t id]() {\r
+    return state[id];\r
+  }\r
+  \r
+}\r
+\r
diff --git a/tos/types/Resource.h b/tos/types/Resource.h
new file mode 100644 (file)
index 0000000..19a025c
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitat Berlin nor the names
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef RESOURCE_H
+#define RESOURCE_H
+
+typedef uint8_t resource_client_id_t;
+
+#endif
+
diff --git a/tos/types/State.h b/tos/types/State.h
new file mode 100644 (file)
index 0000000..7b3c6b6
--- /dev/null
@@ -0,0 +1,44 @@
+/*\r
+ * Copyright (c) 2005-2006 Rincon Research Corporation\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * - Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ * - Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the\r
+ *   distribution.\r
+ * - Neither the name of the Arch Rock Corporation nor the names of\r
+ *   its contributors may be used to endorse or promote products derived\r
+ *   from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE\r
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
+ * OF THE POSSIBILITY OF SUCH DAMAGE\r
+ */\r
+\r
+/**\r
+ * @author David Moss\r
+ */\r
\r
+#ifndef STATE_H\r
+#define STATE_H\r
+\r
+#ifndef UQ_STATE\r
+#define UQ_STATE "State"\r
+#endif\r
+\r
+#endif\r
+\r