[Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/evb13192/tos/chips/mc13192/ieee802154/phy
mc13192PhyInterrupt.nc, NONE, 1.1 mc13192PhyInterruptM.nc,
NONE, 1.1 PhyAttributes.h, NONE, 1.1 mc13192PhyTimer.nc, NONE,
1.1 mc13192PhyInitM.nc, NONE, 1.1 mc13192Filters.h, NONE,
1.1 mc13192PhyDriverC.nc, NONE, 1.1 mc13192Registers.h, NONE,
1.1 mc13192PhyDriverConst.h, NONE, 1.1 mc13192PhyTimerM.nc,
NONE, 1.1 mc13192PhyDriverM.nc, NONE, 1.1
Jan Flora
janflora at users.sourceforge.net
Wed Aug 23 02:34:05 PDT 2006
- Previous message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/evb13192/tos/chips/mc13192/interfaces
mc13192EventTimer.nc, NONE, 1.1 mc13192Receive.nc, 1.1,
1.2 mc13192TimerInterrupt.nc, 1.1, 1.2 mc13192Send.nc, 1.2,
1.3 mc13192Control.nc, 1.1, 1.2 mc13192TimerCounter.nc, 1.1,
1.2 mc13192DataInterrupt.nc, 1.1, 1.2 mc13192Timer.nc, 1.1,
1.2 mc13192PowerManagement.nc, 1.1, 1.2 mc13192State.nc, 1.1,
1.2 mc13192CCA.nc, 1.1, 1.2 mc13192StreamEvents.nc, 1.1,
1.2 mc13192ControlInterrupt.nc, 1.1, 1.2 mc13192Regs.nc, 1.1, 1.2
- Next message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/evb13192/tos/chips/mc13192
mc13192ControlM.nc, 1.2, 1.3 mc13192HardwareM.nc, 1.1,
1.2 mc13192Const.h, 1.2, 1.3 mc13192TOSRadioC.nc, 1.2,
1.3 mc13192TOSRadioM.nc, 1.2, 1.3 mc13192InterruptM.nc, 1.3,
1.4 mc13192DataM.nc, 1.7, 1.8 mc13192StateM.nc, 1.1,
1.2 mc13192Ieee802154M.nc, 1.10, 1.11 mc13192RawRadioC.nc, 1.2,
1.3 mc13192TimerM.nc, 1.1, 1.2 mc13192TimerCounterM.nc, 1.1,
1.2 mc13192Ieee802154RadioC.nc, 1.4, 1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-1.x/contrib/diku/evb13192/tos/chips/mc13192/ieee802154/phy
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv9134/tos/chips/mc13192/ieee802154/phy
Added Files:
mc13192PhyInterrupt.nc mc13192PhyInterruptM.nc PhyAttributes.h
mc13192PhyTimer.nc mc13192PhyInitM.nc mc13192Filters.h
mc13192PhyDriverC.nc mc13192Registers.h
mc13192PhyDriverConst.h mc13192PhyTimerM.nc
mc13192PhyDriverM.nc
Log Message:
MC13192 driver updates
--- NEW FILE: mc13192PhyInterrupt.nc ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
interface mc13192PhyInterrupt
{
async event bool fastAction();
//async event void dataIndication(bool crc);
async event bool streamRead();
async event void txDone();
async event void lockLost();
async event void ccaDone(bool isClear);
// Timers.
async event void ackTimerFired();
async event void eventTimerFired();
async event void deferTimer1Fired();
async event void deferTimer2Fired();
async command void enableStreamMode();
async command void disableStreamMode();
async command void disableFastAction();
}
--- NEW FILE: mc13192PhyInterruptM.nc ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
module mc13192PhyInterruptM {
provides
{
interface mc13192PhyInterrupt as Interrupt;
}
uses
{
interface FastSPI as SPI;
interface Debug;
}
}
implementation
{
#define DBG_LEVEL 1
#include "Debug.h"
// Forward declarations.
inline void handleAttnIRQ();
// No race conditions, since variable is
// read/written in one instruction.
norace bool fastAction = FALSE;
norace bool streamMode = FALSE;
async command void Interrupt.enableStreamMode()
{
atomic streamMode = TRUE;
}
async command void Interrupt.disableStreamMode()
{
atomic streamMode = FALSE;
}
async command void Interrupt.disableFastAction()
{
fastAction = FALSE;
}
// MC13192 interrupt handler.
TOSH_SIGNAL(IRQ)
{
volatile uint16_t status_content; // Result of the status register read.
DISABLE_IRQ;
ACK_IRQ; // Acknowledge the interrupt. MC13192 IRQ pin still low.
if (fastAction) {
// The fastAction event disables fastaction
// when done receiving/transmitting.
fastAction = signal Interrupt.fastAction();
// Now check if our fast action made the IRQ pin go high again.
// If not, the interrupt was more than just an ordinary stream
// rx/tx interrupt.
if (!IRQ_FLAG_SET) {
// Just enable interrupts and get out!
ENABLE_IRQ;
return;
}
ACK_IRQ;
// It takes 133 bus cycles to read the IRQ status register.
//ASSERT_CE;
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(IRQ_STATUS|0x80);
call SPI.fastReadWord((uint8_t*)&status_content);
//DEASSERT_CE;
TOSH_SET_RADIO_CE_PIN();
// It takes 335 bus cycles to process a read interrupt = 42 micro seconds
// It takes 327 bus cycles to process a write interrupt = 41 micro seconds
if ((status_content & 0xF100)) {
// Receive operation timeout handling.
if (status_content & TIMER1_IRQ_MASK)
{
signal Interrupt.ackTimerFired();
}
// LO LOCK IRQ - Occurs when MC13192 loses channel frequency lock.
// When this happens, all rx/tx traffic is aborted.
if (status_content & LO_LOCK_IRQ_MASK)
{
signal Interrupt.lockLost();
}
if (status_content & STRM_DATA_ERR_IRQ_MASK) {
DBG_STR("Stream error bit was set!",2);
}
}
ENABLE_IRQ;
return;
}
// It takes 133 bus cycles to read the IRQ status register.
//ASSERT_CE;
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(IRQ_STATUS|0x80);
call SPI.fastReadWord((uint8_t*)&status_content);
//DEASSERT_CE;
TOSH_SET_RADIO_CE_PIN();
//DBG_STRINT("Status was:",status_content,1);
// If packet RX is done
// In stream mode this is time critical.. This needs to be first.
// Stream RX takes 17 + 133 + 45 + 275 = 470 bus cycles = 58,75 micro seconds.
if (status_content & RX_IRQ_MASK) {
//if (streamMode) {
// 275 bus cycles to prepare stream read.
fastAction = signal Interrupt.streamRead();
/*} else {
signal Interrupt.dataIndication(status_content & CRC_VALID_MASK);
}*/
ENABLE_IRQ;
return;
}
// If packet TX done signal senddone.
// In stream mode this is time critical.. This needs to be first.
// Stream TX takes 17 + 133 + 50 + 173 = 373 bus cycles = 46,6 micro seconds.
if (status_content & TX_IRQ_MASK) {
if (streamMode) {
// This takes 173 bus cycles to complete.
fastAction = signal Interrupt.fastAction();
} else {
signal Interrupt.txDone();
}
ENABLE_IRQ;
return;
}
if (!(status_content & 0xFFFC)) {
ENABLE_IRQ;
return;
}
// TIMER1 IRQ Handler
if (status_content & TIMER1_IRQ_MASK)
{
signal Interrupt.ackTimerFired();
}
// LO LOCK IRQ - Occurs when MC13192 loses channel frequency lock.
// When this happens, all rx/tx traffic is aborted.
if (status_content & LO_LOCK_IRQ_MASK)
{
signal Interrupt.lockLost();
}
// DOZE Complete Interrupt
/* if (status_content & DOZE_IRQ_MASK)
{
signal Control.dozeIndication();
}
// ATTN IRQ Handler
if (status_content & ATTN_IRQ_MASK)
{
handleAttnIRQ();
}*/
// TIMER2 IRQ Handler
if (status_content & TIMER2_IRQ_MASK)
{
signal Interrupt.eventTimerFired();
}
// TIMER3 IRQ Handler
if (status_content & TIMER3_IRQ_MASK)
{
signal Interrupt.deferTimer1Fired();
}
// TIMER4 IRQ Handler
if (status_content & TIMER4_IRQ_MASK)
{
signal Interrupt.deferTimer2Fired();
}
// If CCA done signal
if (status_content & CCA_IRQ_MASK) {
signal Interrupt.ccaDone(!(status_content & CCA_STATUS_MASK));
}
// Dunno what this IRQ is. Snatched from Freescale code.
/* if (status_content & HG_IRQ_MASK) {
uint16_t reg,i;
//for (i=0x00;i<0x40;i++) {
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(0x2A|0x80);
call SPI.fastReadWord((uint8_t*)®);
TOSH_SET_RADIO_CE_PIN();
DBG_STRINT("Register 0x2A:",reg,1);
//}
DBG_STR("Got HG irq!",1);
}*/
// Unhandled IRQ!
/* DBG_STR("Unhandled IRQ!!!",3);
DBG_STR("status_content is:",3);
DBG_INT(status_content,3);*/
ENABLE_IRQ;
}
/* inline void handleAttnIRQ()
{
uint16_t tmp;
// Read the MC13192 reset indicator register.
//ASSERT_CE;
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(RST_IND|0x80);
call SPI.fastReadWord((uint8_t*)&tmp);
//DEASSERT_CE;
TOSH_SET_RADIO_CE_PIN();
tmp &= RESET_BIT_MASK;
if (tmp == 0) {
// If RST_IND is 0, a reset has occured.
signal Control.resetIndication();
} else {
// This must be a wakeup request.
signal Control.wakeUpIndication();
}
}*/
// Default events.
/* default async event void Control.resetIndication() {}
default async event void Control.wakeUpIndication() {}
default async event void Control.dozeIndication() {}*/
}
--- NEW FILE: PhyAttributes.h ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
#ifndef _PHYATTRIBUTES_H_
#define _PHYATTRIBUTES_H_
uint8_t phyCurChannel = 11;
uint32_t phySupportedChannels = 0x07FFF800;
uint8_t phyContentionWindow = 1;
uint8_t phyTransmitPower = 0;
#endif
--- NEW FILE: mc13192PhyTimer.nc ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
interface mc13192PhyTimer
{
command uint32_t getEventTime();
command void resetEventTime();
command bool eventTimerIsSet();
async command void startAckTimer(uint32_t timeout);
async command void stopAckTimer();
async command void startEventTimer(uint32_t commenceTime, uint8_t mode);
async command void stopEventTimer();
async command void startDeferTimer1(uint32_t timeout);
async command void stopDeferTimer1();
async command void startDeferTimer2(uint32_t timeout);
async command void stopDeferTimer2();
}
--- NEW FILE: mc13192PhyInitM.nc ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
#include "macConstants.h"
#include "endianconv.h"
module mc13192PhyInitM {
provides
{
interface StdControl;
interface PhyReset;
}
uses
{
interface LocalTime as MCUTime;
interface mc13192PhyTimer as RadioTime;
interface FastSPI as SPI;
interface Debug;
}
}
implementation
{
#include <mc13192Registers.h>
#define DBG_LEVEL 1
#include "Debug.h"
void initialize()
{
// Enable interrupts.
ENABLE_IRQ;
// Time to setup the radio registers.
// Please refer to document MC13192RM for hidden register initialization
// Register 0x11 is hidden. bit 8-9 should be initialized to 00.
writeRegister(0x11,0xA0FF);
writeRegister(GPIO_DIR, 0x3F80);
writeRegister(CCA_THRESH,0x9674); // WAS: 0xA08D
// Register 0x08 is hidden. bit 1 and 4 should be initialized to 1.
// Preferred injection
writeRegister(0x08,0xFFF7);
// ATTN masks, LO1
writeRegister(IRQ_MASK,0x8240);
// Register 0x06 has some hidden bits. bit 14 should be initialized to 1.
writeRegister(CONTROL_A,0x4010);
// Secret register settings snatched from Freescale implementation
writeRegister(0x13, 0x1843);
writeRegister(0x31, 0xA000);
writeRegister(0x38, 0x0008);
// These should fix excess power consumption during hibernate and doze.
writeRegister(CONTROL_B, 0x7D00); // Was: 0x7D1C (xx00)
// Timer prescale = 5
// Enable alt_GPIO
// Enable clock output.
writeRegister(CONTROL_C, 0xF3FD); // Was: 0xF3FA (xxxD)
// Use Freescale xtal trim value.
// clock rate = 5 (62.5 KHz)
writeRegister(CLKO_CTL, 0x3645);
// Sets the reset indicator bit
readRegister(RST_IND);
// Read the status register to clear any undesired IRQs.
readRegister(IRQ_STATUS);
//call State.setRXTXStateMirror(IDLE_MODE);
}
command void PhyReset.reset()
{
// Synchronize radio and MCU time.
call RadioTime.resetEventTime();
call MCUTime.reset();
}
command result_t StdControl.init()
{
// Initialize GPIO pins.
TOSH_SET_RADIO_CE_PIN();
TOSH_SET_RADIO_ATTN_PIN();
TOSH_CLR_RADIO_RXTXEN_PIN();
TOSH_CLR_RADIO_RESET_PIN();
TOSH_CLR_RADIO_ANT_CTRL_PIN();
TOSH_CLR_RADIO_LNA_CTRL_PIN();
return SUCCESS;
}
command result_t StdControl.start()
{
uint16_t irq_reg, attn_irq = FALSE;
// We then power up the radio and wait for it to init.
ACK_IRQ;
SETUP_IRQ_PIN;
// Detect IRQ on both level and edge to prevent fast double IRQ bug.
IRQ_LEVEL_EDGE;
// Take MC13192 out of reset
TOSH_SET_RADIO_RESET_PIN();
while (attn_irq == FALSE) {
// Check to see if IRQ is asserted
if (IRQ_FLAG_SET) {
// Clear MC13192 interrupts and check for ATTN IRQ from 13192.
irq_reg = readRegister(IRQ_STATUS);
irq_reg &= 0x400;
if (irq_reg != 0) attn_irq = TRUE;
// ACK the pending interrupt.
ACK_IRQ;
}
}
initialize();
// Use external clock.
extClock = 62500;
enterFEEMode(0,8,1); // FLL engaged, 32 MHz MCUclk / 16 MHz BUSclk.
// Set MAC address
// TODO: This should be done in a nicer way!
radioMACAddr = (uint8_t*)MAC_ADDR_LOCATION;
NTOUH64(radioMACAddr, aExtendedAddress);
// Synchronize radio and MCU time.
call RadioTime.resetEventTime();
call MCUTime.reset();
return SUCCESS;
}
command result_t StdControl.stop()
{
//ASSERT_RESET; // Power off the radio.
TOSH_CLR_RADIO_RESET_PIN();
return SUCCESS;
}
}
--- NEW FILE: mc13192Filters.h ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
#ifndef _MC13192_FILTERS_H_
#define _MC13192_FILTERS_H_
#include "MacPib.h"
typedef struct
{
uint8_t FrameType : 3;
uint8_t SecurityEnabled : 1;
uint8_t FramePending : 1;
uint8_t AckRequest : 1;
uint8_t IntraPAN : 1;
uint8_t Reserved1_2 : 1;
uint8_t Reserved1_1 : 2;
uint8_t DestAddrMode : 2;
uint8_t Reserved2 : 2;
uint8_t SrcAddrMode : 2;
} frameControlHeader_t;
// 802.15.4 filter parameters.
//uint8_t filterPanId[2] = {0xDE, 0xFE};
//uint8_t filterShortAddr[2] = {0x1F, 0x00};
//uint8_t filterExtAddr[8] = {0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
// 802.15.4 filtering global vars.
frameControlHeader_t *rxFrameControl;
uint8_t rxDstAddrLength;
uint8_t *filterValue;
uint8_t rxSeqNum;
bool (*filterWord)(uint8_t*);
char *filterReason;
bool ackFilter(uint8_t *data);
bool defaultFilter(uint8_t *data);
bool seqNumFilter(uint8_t *data);
bool dstPanFilter(uint8_t *data);
bool dstAddrFilter(uint8_t *data);
bool srcPanFilter(uint8_t *data);
// 802.15.4 filtering functions.
bool dummyFilter(uint8_t *dummy)
{
return TRUE;
}
bool ackFilter(uint8_t *data)
{
rxFrameControl = (frameControlHeader_t*)data;
if (rxFrameControl->FrameType == 2) {
filterWord = dummyFilter;
return TRUE;
}
return FALSE;
}
bool defaultFilter(uint8_t *data)
{
rxFrameControl = (frameControlHeader_t*)data;
// Discard if wrong frameType
if (rxFrameControl->FrameType > 3) {
filterReason = "Invalid frame type!";
return FALSE;
}
// Discard if unknown address mode.
if (rxFrameControl->DestAddrMode == 1 || rxFrameControl->SrcAddrMode == 1) {
filterReason = "Invalid addressing mode!";
return FALSE;
}
// Preaccept beacons when not associated.
//if (!(rxFrameControl->FrameType) && filterPanId[0] == 0xFF && filterPanId[1] == 0xFF) {
if (!(rxFrameControl->FrameType) && macPanId == 0xFFFF) {
filterWord = dummyFilter;
return TRUE;
}
// Calculate address lengths.
rxDstAddrLength = 0;
if (rxFrameControl->DestAddrMode) {
if (rxFrameControl->DestAddrMode == 2) {
rxDstAddrLength = 2;
} else {
rxDstAddrLength = 8;
}
}
filterWord = seqNumFilter;
return TRUE;
}
bool seqNumFilter(uint8_t *data)
{
// Not a real filter. Just fetch the sequence number
// and prepare the right filter.
rxSeqNum = data[0];
//filterValue = filterPanId;
filterValue = (uint8_t*)&macPanId;
if (rxDstAddrLength) {
filterWord = dstPanFilter;
} else {
filterWord = srcPanFilter;
}
return TRUE;
}
bool dstPanFilter(uint8_t *data)
{
// Read PANId for short address.
uint8_t *myPan = data-1;
if ((myPan[0] == filterValue[0] && myPan[1] == filterValue[1]) ||
(myPan[0] == 0xFF && myPan[0] == myPan[1])) {
// Broadcast pan is also accepted.
if (rxDstAddrLength == 2) {
//filterValue = filterShortAddr;
filterValue = (uint8_t*)&macShortAddress;
} else {
//filterValue = filterExtAddr;
filterValue = aExtendedAddress;
}
filterWord = dstAddrFilter;
return TRUE;
}
filterReason = "Invalid destination PAN Id!";
return FALSE;
}
bool dstAddrFilter(uint8_t *data)
{
uint8_t *myAddr = data-1;
if (rxDstAddrLength > 2) {
// We are handling an extended address.
if ((myAddr[0] == filterValue[0] && myAddr[1] == filterValue[1])) {
filterValue += 2;
rxDstAddrLength -= 2;
return TRUE;
} else {
filterReason = "Invalid destination address1!";
return FALSE;
}
} else {
// last part.
// We also accept broadcast address if short address.
if ((myAddr[0] == filterValue[0] && myAddr[1] == filterValue[1]) ||
(rxFrameControl->DestAddrMode == 2 &&
(myAddr[0] == 0xFF && myAddr[0] == myAddr[1]))) {
// Filter was passed.
filterWord = dummyFilter;
return TRUE;
} else {
filterReason = "Invalid destination address2!";
return FALSE;
}
}
}
bool srcPanFilter(uint8_t *data)
{
// Read PANId for short address.
uint8_t *myPan = data-1;
if ((myPan[0] == filterValue[0] && myPan[1] == filterValue[1])) {
filterWord = dummyFilter;
return TRUE;
}
filterReason = "Invalid source PAN Id!";
return FALSE;
}
#endif
--- NEW FILE: mc13192PhyDriverC.nc ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
configuration mc13192PhyDriverC
{
provides
{
interface StdControl;
interface PhyReceive;
interface PhyTransmit;
interface PhyEnergyDetect;
interface PhyAttributes;
interface PhyControl;
interface PhyReset;
}
uses
{
interface LocalTime as MCUTime;
interface FastSPI as SPI;
interface Debug;
}
}
implementation
{
components mc13192PhyDriverM,
mc13192PhyInitM,
mc13192PhyInterruptM,
mc13192PhyTimerM;
StdControl = mc13192PhyInitM.StdControl;
StdControl = mc13192PhyTimerM.StdControl;
PhyReceive = mc13192PhyDriverM.PhyReceive;
PhyTransmit = mc13192PhyDriverM.PhyTransmit;
PhyAttributes = mc13192PhyDriverM.PhyAttributes;
PhyEnergyDetect = mc13192PhyDriverM.PhyEnergyDetect;
PhyControl = mc13192PhyDriverM.PhyControl;
PhyReset = mc13192PhyDriverM.PhyReset;
PhyReset = mc13192PhyInitM.PhyReset;
mc13192PhyDriverM.Interrupt -> mc13192PhyInterruptM.Interrupt;
mc13192PhyDriverM.Timer -> mc13192PhyTimerM.Timer;
mc13192PhyInitM.RadioTime -> mc13192PhyTimerM.Timer;
mc13192PhyInitM.MCUTime = MCUTime;
mc13192PhyDriverM.MCUTime = MCUTime;
// Wire up the SPI.
mc13192PhyInitM.SPI = SPI;
mc13192PhyDriverM.SPI = SPI;
mc13192PhyInterruptM.SPI = SPI;
mc13192PhyTimerM.SPI = SPI;
// Wire debug module.
mc13192PhyDriverM.Debug = Debug;
mc13192PhyInterruptM.Debug = Debug;
mc13192PhyTimerM.Debug = Debug;
}
--- NEW FILE: mc13192Registers.h ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
// This file assumes that the SPI interface has been "used" before including.
#ifndef _MC13192REGISTER_H_
#define _MC13192REGISTER_H_
// inlined versions.
inline void writeRegisterFast(uint8_t addr, uint16_t content)
{
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(addr);
call SPI.fastWriteWord((uint8_t*)&content);
TOSH_SET_RADIO_CE_PIN();
}
inline uint16_t readRegisterFast(uint8_t addr)
{
uint16_t w=0;
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(addr | 0x80);
call SPI.fastReadWord((uint8_t*)&w);
TOSH_SET_RADIO_CE_PIN();
return w;
}
// Functions not inlined
void writeRegister(uint8_t addr, uint16_t content) __attribute((noinline))
{
writeRegisterFast(addr, content);
}
uint16_t readRegister(uint8_t addr) __attribute((noinline))
{
return readRegisterFast(addr);
}
#endif
--- NEW FILE: mc13192PhyDriverConst.h ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
#ifndef _PHY_DRIVER_CONST_H_
#define _PHY_DRIVER_CONST_H_
// Radio register 06 defines.
// Transmission modes.
#define TX_CCA_MODE1 0x4615
#define TX_CCA_MODE2 0x4616
// Event timer bit
#define EVENT_TIMED 0x0080
// Radio register 07 defines.
#define STREAM_MODE_ON 0x7D20
#define STREAM_MODE_OFF 0x7D00
// Deferred operation types.
#define DEFER_RX 0
#define DEFER_TX 1
#define DEFER_TX_CCA 2
/* typedef struct {
uint8_t *buffer;
uint8_t length;
uint8_t lqi;
} rxFrame_t;*/
#endif
--- NEW FILE: mc13192PhyTimerM.nc ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
module mc13192PhyTimerM
{
provides {
interface mc13192PhyTimer as Timer;
interface StdControl;
}
uses {
interface FastSPI as SPI;
interface Debug;
}
}
implementation
{
#include <mc13192Registers.h>
#define DBG_LEVEL 1
#include "Debug.h"
// Global variables.
bool eventTimerSet = FALSE;
command result_t StdControl.init()
{
return SUCCESS;
}
command result_t StdControl.start()
{
// Stop all timers.
call Timer.stopAckTimer();
call Timer.stopEventTimer();
call Timer.stopDeferTimer1();
call Timer.stopDeferTimer2();
return SUCCESS;
}
command result_t StdControl.stop()
{
// Stop all timers.
call Timer.stopAckTimer();
call Timer.stopEventTimer();
call Timer.stopDeferTimer1();
call Timer.stopDeferTimer2();
return SUCCESS;
}
/******************************/
/* Event triggering functions */
/******************************/
command bool Timer.eventTimerIsSet()
{
return eventTimerSet;
}
async command void Timer.startAckTimer(uint32_t timeout)
{
uint16_t mask;
// Turn Timer1 mask on
writeRegister(TMR_CMP1_A, (uint16_t)(timeout >> 16));
writeRegister(TMR_CMP1_B, (uint16_t)timeout);
// enable timer interrupt.
mask = readRegister(IRQ_MASK);
mask |= TIMER1_IRQMASK_BIT;
writeRegister(IRQ_MASK, mask);
}
async command void Timer.stopAckTimer()
{
uint16_t mask;
// disable timer interrupt.
mask = readRegister(IRQ_MASK);
mask &= ~(TIMER1_IRQMASK_BIT);
writeRegister(IRQ_MASK, mask);
// Disable timer compare.
writeRegister(TMR_CMP1_A, 0x8000);
}
async command void Timer.startEventTimer(uint32_t commenceTime, uint8_t mode)
{
uint16_t reg, mask;
// enable timer interrupt.
mask = readRegister(IRQ_MASK);
mask |= TIMER2_IRQMASK_BIT;
writeRegister(IRQ_MASK, mask);
eventTimerSet = TRUE;
// Program the right register with the timeout.
if (mode == STREAM_MODE) {
// Write timeout to tc2_prime
writeRegister(TC2_PRIME, (uint16_t)commenceTime);
// Write to tmr_cmp2_dis
writeRegister(TMR_CMP2_A, 0x0000);
} else {
// Assume packet mode.
// Write timeout to tmr_cmp2
writeRegister(TMR_CMP2_A, (uint16_t)(commenceTime >> 16));
writeRegister(TMR_CMP2_B, (uint16_t)commenceTime);
}
}
async command void Timer.stopEventTimer()
{
uint16_t mask;
// disable timer interrupt.
mask = readRegister(IRQ_MASK);
mask &= ~(TIMER2_IRQMASK_BIT);
writeRegister(IRQ_MASK, mask);
// Disable timer compare.
writeRegister(TMR_CMP2_A, 0x8000);
eventTimerSet = FALSE;
}
async command void Timer.startDeferTimer1(uint32_t timeout)
{
uint16_t mask;
// Turn Timer1 mask on
writeRegister(TMR_CMP3_A, (uint16_t)(timeout >> 16));
writeRegister(TMR_CMP3_B, (uint16_t)timeout);
// enable timer interrupt.
mask = readRegister(IRQ_MASK);
mask |= TIMER3_IRQMASK_BIT;
writeRegister(IRQ_MASK, mask);
}
async command void Timer.stopDeferTimer1()
{
uint16_t mask;
// disable timer interrupt.
mask = readRegister(IRQ_MASK);
mask &= ~(TIMER3_IRQMASK_BIT);
writeRegister(IRQ_MASK, mask);
// Disable timer compare.
writeRegister(TMR_CMP3_A, 0x8000);
}
async command void Timer.startDeferTimer2(uint32_t timeout)
{
uint16_t mask;
// Turn Timer1 mask on
writeRegister(TMR_CMP4_A, (uint16_t)(timeout >> 16));
writeRegister(TMR_CMP4_B, (uint16_t)timeout);
// enable timer interrupt.
mask = readRegister(IRQ_MASK);
mask |= TIMER4_IRQMASK_BIT;
writeRegister(IRQ_MASK, mask);
}
async command void Timer.stopDeferTimer2()
{
uint16_t mask;
// disable timer interrupt.
mask = readRegister(IRQ_MASK);
mask &= ~(TIMER4_IRQMASK_BIT);
writeRegister(IRQ_MASK, mask);
// Disable timer compare.
writeRegister(TMR_CMP4_A, 0x8000);
}
command uint32_t Timer.getEventTime()
{
uint8_t timestamp[4];
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(CURRENT_TIME_A|0x80);
call SPI.fastReadWord(timestamp);
call SPI.fastReadWord(timestamp+2);
TOSH_SET_RADIO_CE_PIN();
return *(uint32_t*)timestamp;
}
command void Timer.resetEventTime()
{
uint8_t timestamp[2] = {0x00, 0x00};
// Program Time1 comparator with time.
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(TMR_CMP1_A);
call SPI.fastWriteWord(timestamp);
call SPI.fastWriteWord(timestamp);
TOSH_SET_RADIO_CE_PIN();
writeRegister(CONTROL_B, STREAM_MODE_OFF|0x8000);
}
}
--- NEW FILE: mc13192PhyDriverM.nc ---
/* Copyright (c) 2006, Jan Flora <janflora at diku.dk>
* 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 Copenhagen nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
@author Jan Flora <janflora at diku.dk>
*/
#include <mcuToRadioPorts.h>
#include <mc13192Const.h>
#include <mc13192Filters.h>
#include <mc13192PhyDriverConst.h>
#include <PhyTypes.h>
module mc13192PhyDriverM {
provides
{
interface PhyReceive;
interface PhyTransmit;
interface PhyEnergyDetect;
interface PhyAttributes;
interface PhyControl;
interface PhyReset;
}
uses
{
interface mc13192PhyInterrupt as Interrupt;
interface FastSPI as SPI;
interface mc13192PhyTimer as Timer;
interface LocalTime as MCUTime;
interface Debug;
}
}
implementation
{
#include <mc13192Registers.h>
// Level 1 = List function calls.
// Level 2 = Function calls + return values.
// Level 3 = Extensive debug.
#define DBG_LEVEL 0
#define DBG_MIN_LEVEL 1
#include "Debug.h"
// Phy attribute variables.
uint8_t curChannel = 11;
bool (*myFilter)(uint8_t*) = NULL;
// CCA globals
bool edOperation = FALSE;
uint16_t ccaMode = TX_CCA_MODE1;
// RX packet variables
rxdata_t rxPacket;
uint8_t rxDuration;
uint32_t rxCommenceTime;
// Stream mode globals
norace uint8_t dataTransferMode = PACKET_MODE;
norace uint8_t *nextByte;
norace uint8_t *lastByte;
norace uint8_t opMode = NO_OPERATION;
bool isReceiving = FALSE;
// Defer support.
// Defer 1 slot.
uint8_t defer1OpType;
bool defer1Ack;
txdata_t *defer1Data;
uint32_t defer1RxTime;
bool defer1SlotFree = TRUE;
// Defer 2 slot.
uint8_t defer2OpType;
bool defer2Ack;
txdata_t *defer2Data;
uint32_t defer2RxTime;
// 802.15.4 acknowledgement support.
bool backoffAligned = FALSE;
bool ackedOperation = FALSE;
uint8_t seqNum;
// The 802.15.4 spec states a wait time of 54. We add 12 symbol periods,
// since a packet reception is first signalled after receiving preamble,
// start of frame delimiter and frame length indicator. That totals 6
// bytes equaling 12 symbol periods of transmission time.
uint8_t ackWaitTime = 66;
uint8_t ackFrame[2] = {0x02, 0x00};
bool acking = FALSE;
// Transmit and receive functions
void enableReceiver(bool immediateCommence);
bool sendCca(txdata_t *data, bool ack);
void sendNoCca(txdata_t *data, bool ack);
inline uint32_t getRxTime();
inline void abortReceive();
inline void restartReceive();
inline void changeState(uint16_t state);
//inline void writeRegister(uint8_t addr, uint16_t content);
inline void finishStreamOperation();
inline void finishRx();
inline bool readRXPacketLength();
inline uint8_t getCCAFinal();
//inline void getReceiveBuffer();
//inline void readRXPacket();
inline void writeTXPacket(uint8_t *packet, uint8_t length);
inline void writeTXPacketLength(uint8_t length);
command void PhyReset.reset()
{
ccaMode = TX_CCA_MODE1;
backoffAligned = FALSE;
}
/* **********************************************************************
* PhyAttributes code
* *********************************************************************/
command result_t PhyAttributes.setChannel(uint8_t channel)
{
// Convert from IEEE 802.15.4 notation.
channel -= 11;
if (channel <= 0x0F) {
uint16_t num = ((channel + 1)*5 & 0x000F)<<12;
uint16_t div = 0x0F95;
while (channel >= 3) {
div++;
channel -= 3;
}
writeRegister(LO1_INT_DIV,div);
writeRegister(LO1_NUM,num);
curChannel = channel;
return SUCCESS;
}
return FAIL;
}
command result_t PhyAttributes.setContentionWindow(uint8_t size)
{
if (size == 1) {
ccaMode = TX_CCA_MODE1;
} else if (size == 2) {
ccaMode = TX_CCA_MODE2;
} else {
return FAIL;
}
return SUCCESS;
}
command result_t PhyAttributes.setTransmitPower(uint8_t power)
{
return SUCCESS;
}
command result_t PhyAttributes.setAckBackoffAlignment(bool align)
{
backoffAligned = align;
return SUCCESS;
}
command result_t PhyAttributes.setFilter(bool (*filter)(uint8_t*))
{
myFilter = filter;
return SUCCESS;
}
command result_t PhyAttributes.clearFilter()
{
myFilter = NULL;
return SUCCESS;
}
/* command uint8_t PhyAttributes.getChannel()
{
return curChannel;
}*/
command uint32_t PhyAttributes.getSupportedChannels()
{
return 0x07FFF800;
}
/* **********************************************************************
* PhyControl code
* *********************************************************************/
command result_t PhyControl.trxOff(bool force)
{
atomic opMode = NO_OPERATION;
abortReceive();
return SUCCESS;
}
command void PhyControl.sleep(uint32_t wakeUpTime)
{
}
/* **********************************************************************
* Setup/Init code
* *********************************************************************/
command void PhyReceive.initRxBuffer(uint8_t *packetBuf)
{
rxPacket.frame = packetBuf;
}
command phy_error_t PhyReceive.rxOn(uint32_t commenceTime, bool immediateCommence)
{
if (immediateCommence) {
enableReceiver(TRUE);
} else {
// TODO: Check that commence time is sane.
// Defer until 12 symbols before commence time.
bool wasFree;
atomic {
wasFree = defer1SlotFree;
defer1SlotFree = FALSE;
}
if (wasFree) {
// Use defer slot 1.
defer1OpType = DEFER_RX;
defer1RxTime = commenceTime;
call Timer.startDeferTimer1(commenceTime-12);
} else {
// Use spare defer slot 2.
defer2OpType = DEFER_RX;
defer2RxTime = commenceTime;
call Timer.startDeferTimer2(commenceTime-12);
}
}
return PHY_SUCCESS;
}
command phy_error_t PhyTransmit.tx(txdata_t *data)
{
bool ack = (data->frame[0] & 0x20);
if (data->immediateCommence) {
// Just start operation as fast as possible.
if (data->cca) {
if (!sendCca(data,ack)) {
return PHY_CCA_FAIL;
}
} else {
sendNoCca(data,ack);
}
} else {
// TODO: Check that commence time is sane.
// Defer until 12 symbols before commence time.
bool wasFree;
atomic {
wasFree = defer1SlotFree;
defer1SlotFree = FALSE;
}
if (wasFree) {
// Use defer slot 1.
defer1OpType = DEFER_TX;
defer1Ack = ack;
defer1Data = data;
call Timer.startDeferTimer1(data->commenceTime-12);
} else {
// Use spare defer slot 2.
defer2OpType = DEFER_TX;
defer2Ack = ack;
defer2Data = data;
call Timer.startDeferTimer2(data->commenceTime-12);
}
}
return PHY_SUCCESS;
}
void enableReceiver(bool immediateCommence)
{
// We are doing this kinda backwards. We first request the state
// change from the radio, and then prepare for the reception,
// while the radio is getting ready (takes 9 symbols).
if (immediateCommence) {
while(TOSH_READ_RADIO_OOI_PIN());
changeState(RX_STRM_MODE);
} else {
changeState(RX_STRM_MODE | EVENT_TIMED);
call Timer.startEventTimer(rxCommenceTime, STREAM_MODE);
}
if (dataTransferMode != STREAM_MODE) {
// Enable stream mode.
writeRegister(CONTROL_B, STREAM_MODE_ON);
call Interrupt.enableStreamMode();
dataTransferMode = STREAM_MODE;
}
atomic opMode = RX_OPERATION;
nextByte = rxPacket.frame;
filterWord = defaultFilter;
}
bool sendCca(txdata_t *data, bool ack)
{
if (isReceiving) return FALSE;
if (!data->immediateCommence) {
changeState(ccaMode | EVENT_TIMED);
call Timer.startEventTimer(data->commenceTime, PACKET_MODE);
} else {
changeState(ccaMode);
}
if (dataTransferMode != PACKET_MODE) {
writeRegister(CONTROL_B, STREAM_MODE_OFF);
call Interrupt.disableStreamMode();
dataTransferMode = PACKET_MODE;
}
// Write the TX packet length!
writeTXPacketLength(data->length);
// Write packet to radio.
writeTXPacket(data->frame, data->length);
ackedOperation = ack;
seqNum = data->frame[2];
atomic opMode = TX_OPERATION;
return TRUE;
}
void sendNoCca(txdata_t *data, bool ack)
{
abortReceive();
// We are doing this kinda backwards. We first request the state
// change from the radio, and then prepare for the transmission,
// while the radio is getting ready (takes 9 symbols).
if (!data->immediateCommence) {
changeState(TX_STRM_MODE | EVENT_TIMED);
call Timer.startEventTimer(data->commenceTime, STREAM_MODE);
} else {
changeState(TX_STRM_MODE);
}
// Write first word to packet ram.
writeTXPacket(data->frame, 2);
// Write the TX packet length!
writeTXPacketLength(data->length);
// Enable stream mode.
if (dataTransferMode != STREAM_MODE) {
// Enable stream mode.
writeRegister(CONTROL_B, STREAM_MODE_ON);
call Interrupt.enableStreamMode();
dataTransferMode = STREAM_MODE;
}
atomic opMode = TX_OPERATION;
// Set ack mode variables.
ackedOperation = ack;
seqNum = data->frame[2];
// Set stream frame pointers correct.
nextByte = data->frame+2;
lastByte = data->frame + data->length;
}
default async event void PhyEnergyDetect.edDone(phy_error_t error, uint8_t power) {}
command phy_error_t PhyEnergyDetect.ed()
{
edOperation = TRUE;
if (dataTransferMode != PACKET_MODE) {
writeRegister(CONTROL_B, STREAM_MODE_OFF);
call Interrupt.disableStreamMode();
dataTransferMode = PACKET_MODE;
}
changeState(ED_MODE);
return PHY_SUCCESS;
}
/******************************/
/* Interrupt handlers */
/******************************/
// RX uses 175 bus cycles to complete = 22 micro seconds
// TX uses 167 bus cycles to complete = 21 micro seconds
inline async event bool Interrupt.fastAction()
{
// TIME CRITICAL SECTION
// NO DBG IN HERE
if (opMode == RX_OPERATION) {
// Receive mode. Read next byte.
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(RX_PKT_RAM|0x80);
call SPI.fastReadWordSwapped(nextByte);
call SPI.fastReadWordSwapped(nextByte);
TOSH_SET_RADIO_CE_PIN();
nextByte += 2;
// Filter the received word.
if (!filterWord(nextByte-2)) {
// Discard packet.
restartReceive();
DBG_STR("Discarded by filter!",3);
DBG_STR(filterReason,3);
DBG_DUMP(rxPacket.frame,rxPacket.length,3);
return FALSE;
}
} else {
// Transmit mode. Supply next word.
//ASSERT_CE; // Enable SPI
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(TX_PKT_RAM);
call SPI.fastWriteWordSwapped(nextByte);
//DEASSERT_CE;
TOSH_SET_RADIO_CE_PIN();
nextByte += 2;
}
if (nextByte >= lastByte) {
finishStreamOperation();
return FALSE;
}
return TRUE;
}
async event void Interrupt.ackTimerFired()
{
call Timer.stopAckTimer();
if (ackedOperation) {
ackedOperation = FALSE;
abortReceive();
signal PhyTransmit.txDone(PHY_ACK_FAIL);
}
}
async event void Interrupt.eventTimerFired()
{
call Timer.stopEventTimer();
}
async event void Interrupt.deferTimer1Fired()
{
// Activate deferred operation.
if (defer1OpType == DEFER_TX) {
if (defer1Data->cca) {
if (!sendCca(defer1Data,defer1Ack)) {
signal PhyTransmit.txDone(PHY_CCA_FAIL);
}
} else {
sendNoCca(defer1Data,defer1Ack);
}
} else if (defer1OpType == DEFER_RX) {
rxCommenceTime = defer1RxTime;
enableReceiver(FALSE);
}
call Timer.stopDeferTimer1();
defer1SlotFree = TRUE;
}
async event void Interrupt.deferTimer2Fired()
{
// Activate deferred operation.
if (defer2OpType == DEFER_TX) {
if (defer2Data->cca) {
if (!sendCca(defer2Data,defer2Ack)) {
signal PhyTransmit.txDone(PHY_CCA_FAIL);
}
} else {
sendNoCca(defer2Data,defer2Ack);
}
DBG_STR("Starting deferred tx from slot 2",4);
} else if (defer2OpType == DEFER_RX) {
rxCommenceTime = defer2RxTime;
enableReceiver(FALSE);
}
call Timer.stopDeferTimer2();
}
// Interrupt indicating packet mode tx done.
async event void Interrupt.txDone()
{
if (ackedOperation) {
/* uint32_t timeout;
changeState(RX_MODE);
timeout = call Timer.getEventTime() + ackWaitTime;
call Timer.startAckTimer(timeout);*/
uint32_t timeout;
filterWord = ackFilter;
opMode = RX_OPERATION;
// Enable stream mode.
writeRegister(CONTROL_B, STREAM_MODE_ON);
call Interrupt.enableStreamMode();
dataTransferMode = STREAM_MODE;
changeState(RX_STRM_MODE);
// clear interrupt flag to allow rx to finish up.
__nesc_enable_interrupt();
nextByte = rxPacket.frame;
timeout = call Timer.getEventTime() + ackWaitTime;
call Timer.startAckTimer(timeout);
} else {
// We're done!
signal PhyTransmit.txDone(PHY_SUCCESS);
}
}
// Interrupt indicating that a packet receive is about to commence
// in stream mode.
// This function takes 269 bus cycles to complete if successful.
inline async event bool Interrupt.streamRead()
{
// TIME CRITICAL SECTION
// NO DBG IN HERE (This time I mean it!!)
if (opMode == RX_OPERATION) {
// Read packet length.
if (readRXPacketLength()) {
isReceiving = TRUE;
return TRUE;
}
// Abort and retry here.
// Packet contained no data. Abort receive.
restartReceive();
}
return FALSE;
}
/* async event void Interrupt.dataIndication(bool crc)
{
// We only packet mode reception for receiving acks!
if (crc && ackedOperation && readRXPacketLength() && rxPacket.length == 3) {
readRXPacket(); // Read data from MC13192.
if (rxPacket.frame[2] == seqNum) {
ackedOperation = FALSE;
call Timer.stopAckTimer();
DBG_STR("Got ack and finishing up operation!",4);
signal PhyTransmit.txDone(PHY_SUCCESS);
return;
} else {
DBG_STR("Got frame, but not an ack!",1);
}
} else {
readRXPacketLength();
readRXPacket();
DBG_DUMP(rxPacket.frame, rxPacket.length,1);
}
}*/
// What do we do here?
async event void Interrupt.lockLost()
{
// Handle restart of operations.
/* if (opMode == RX_OPERATION) {
DBG_STR("Restarting RX operation",3);
nextByte = rxPacket->buffer;
lastByte = nextByte + rxPacket->length;
receive();
} else if (opMode == TX_OPERATION) {
DBG_STR("Restarting TX operation",3);
nextByte = txPacket;
lastByte = txPacket + txLength;
send();
} else if (opMode == CCA_OPERATION) {
DBG_STR("Restarting CCA operation",3);
// Just restart previous operation
if (ccaType == ENERGY_DETECT) {
call State.setEDMode(dataTransferMode);
} else {
// Must be CCA.
call State.setCCAMode(dataTransferMode);
}
}*/
}
async event void Interrupt.ccaDone(bool isClear)
{
// Put radio in idle mode.
TOSH_CLR_RADIO_RXTXEN_PIN();
if (edOperation) {
uint16_t energy = readRegister(RX_STATUS);
signal PhyEnergyDetect.edDone(PHY_SUCCESS, (uint8_t)(energy>>8));
} else {
// Only signalled when CCA-CCA-TX fails.
signal PhyTransmit.txDone(PHY_CCA_FAIL);
}
}
// Helper functions below here
inline void writeTXPacketLength(uint8_t length)
{
uint16_t reg = length + 2;
writeRegister(TX_PKT_CTL, reg);
}
inline void writeTXPacket(uint8_t *packet, uint8_t length)
{
uint8_t i = 0;
// Not pretty, but fast!
// Worst case write is 31 symbol periods.
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(TX_PKT_RAM);
while (i<length) {
call SPI.fastWriteWordSwapped(packet+i);
i += 2;
}
TOSH_SET_RADIO_CE_PIN();
}
/* inline void readRXPacket()
{
uint8_t *myNextByte = rxPacket.frame;
uint8_t *myLastByte = myNextByte + rxPacket.length;
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(RX_PKT_RAM|0x80);
// Receive register will contain garbage for first read.
call SPI.fastReadWordSwapped(myNextByte);
while (myNextByte <= myLastByte) {
call SPI.fastReadWordSwapped(myNextByte);
myNextByte += 2;
}
TOSH_SET_RADIO_CE_PIN();
}*/
/* inline void getReceiveBuffer()
{
// Get new receive buffer.
nextByte = rxPacket.frame = bufQueue[bufHead];
bufHead = (bufHead+1)%queueSize;
bufCount--;
}*/
inline uint8_t getCCAFinal()
{
uint8_t power[2];
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(RX_STATUS|0x80);
call SPI.fastReadWord(power);
TOSH_SET_RADIO_CE_PIN();
return power[0];
}
inline bool readRXPacketLength()
{
uint8_t status[2];
// TIME CRITICAL SECTION.
// NO DEBUG IN HERE.
// This is time critical in stream mode, so we
// call the SPI operations directly..
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(RX_STATUS|0x80);
call SPI.fastReadWord(status);
TOSH_SET_RADIO_CE_PIN();
// Read out link quality and packet length.
rxPacket.linkQuality = status[0];
rxPacket.length = status[1] & 0x007F;
if (rxPacket.length < 5) {
// This is not valid.
return FALSE;
}
// Get rx timestamp.
// Subtract the time it takes to receive preamble.
rxPacket.recvTime = getRxTime()-12;
rxDuration = 12 + rxPacket.length*2;
// MC13192 reports length with 2 CRC bytes. We don't need them.
rxPacket.length -= 2;
lastByte = nextByte + rxPacket.length;
return TRUE;
}
inline void finishStreamOperation()
{
// We're done.
if (opMode == RX_OPERATION) {
// We need to wait for the radio to go out of idle
// before we can read the correct CRC result.
while(TOSH_READ_RADIO_OOI_PIN());
if (!TOSH_READ_RADIO_CRC_PIN()) {
restartReceive();
return;
}
// If we are waiting for an ack.
if (ackedOperation) {
isReceiving = FALSE;
if (rxPacket.frame[2] == seqNum) {
ackedOperation = FALSE;
call Timer.stopAckTimer();
DBG_STR("Got ack and finishing up operation!",4);
signal PhyTransmit.txDone(PHY_SUCCESS);
return;
}
return;
}
// Check if we need to ack the received packet.
if (rxFrameControl->AckRequest) {
// The ack should commence 12 symbol periods after the time of arrival
// of the frame.
uint16_t commenceTime = ((uint16_t)rxPacket.recvTime) + rxDuration + 12;
if (backoffAligned) {
// We backoff align the ack, by assuming that the transmission commenced
// on a backoff boundary. We figure out, how much to add to the commence
// time, so that the commence time of the ack is a multiple of 20 bigger
// than the frame recv time.
commenceTime += 20 - ((rxDuration + 12)%20);
}
// Program event timer.
writeRegister(TC2_PRIME, commenceTime);
writeRegister(TMR_CMP2_A, 0x0000);
changeState(TX_STRM_MODE|EVENT_TIMED);
// We ack the packet.
writeTXPacketLength(3);
// Write the two first ack bytes to packet ram.
writeTXPacket(ackFrame, 2);
nextByte = lastByte = &rxSeqNum;
acking = TRUE;
call Interrupt.disableFastAction();
opMode = TX_OPERATION;
// clear interrupt flag to allow tx to finish up.
ENABLE_IRQ;
__nesc_enable_interrupt();
} else {
isReceiving = FALSE;
finishRx();
}
} else {
if (ackedOperation) {
uint32_t timeout;
filterWord = ackFilter;
while(TOSH_READ_RADIO_OOI_PIN());
call Interrupt.disableFastAction();
opMode = RX_OPERATION;
changeState(RX_STRM_MODE);
// clear interrupt flag to allow rx to finish up.
__nesc_enable_interrupt();
nextByte = rxPacket.frame;
//getReceiveBuffer();
timeout = call Timer.getEventTime() + ackWaitTime;
call Timer.startAckTimer(timeout);
return;
}
if (acking) {
// If we were transmitting an ack, just return.
while(TOSH_READ_RADIO_OOI_PIN());
acking = FALSE;
isReceiving = FALSE;
finishRx();
return;
}
signal PhyTransmit.txDone(PHY_SUCCESS);
}
}
inline void finishRx()
{
uint32_t myMcuTime;
// Filter received packet through additional filter if set.
if (myFilter != NULL) {
if (!myFilter(rxPacket.frame)) {
DBG_STR("Packet discarded by custom filter",4);
restartReceive();
return;
}
}
// Extend the rx timestamp. (Radio time is 24 bits, MCU is 32 bits).
myMcuTime = call MCUTime.getTime();
rxPacket.recvTime += (myMcuTime & 0xFF000000);
if (rxPacket.recvTime > myMcuTime) {
// MCU timer must have incremented its 8 most significant bits
// since receive time. Subtract 0x01000000 from packet timestamp.
rxPacket.recvTime -= 0x01000000;
}
// Enable interrupts in case we have to process an orphan notification or
// an association request, which is done in async context (speed).
ENABLE_IRQ;
__nesc_enable_interrupt();
// Get new receive buffer.
rxPacket.frame = signal PhyReceive.dataReady(&rxPacket);
if (opMode == RX_OPERATION) {
// The receiver still needs to be on.
enableReceiver(TRUE);
}
}
/* inline void writeRegister(uint8_t addr, uint16_t content)
{
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(addr);
call SPI.fastWriteWord((uint8_t*)&content);
TOSH_SET_RADIO_CE_PIN();
}*/
inline void changeState(uint16_t state)
{
TOSH_CLR_RADIO_RXTXEN_PIN();
writeRegister(CONTROL_A, state);
TOSH_SET_RADIO_RXTXEN_PIN();
}
inline uint32_t getRxTime()
{
uint8_t timestamp[4];
TOSH_CLR_RADIO_CE_PIN();
call SPI.fastWriteByte(TIMESTAMP_A|0x80);
call SPI.fastReadWord(timestamp);
call SPI.fastReadWord(timestamp+2);
TOSH_SET_RADIO_CE_PIN();
return *(uint32_t*)timestamp;
}
inline void restartReceive()
{
isReceiving = FALSE;
call Interrupt.disableFastAction();
TOSH_CLR_RADIO_RXTXEN_PIN();
while(TOSH_READ_RADIO_OOI_PIN());
writeRegister(CONTROL_A, RX_STRM_MODE);
TOSH_SET_RADIO_RXTXEN_PIN();
filterWord = defaultFilter;
nextByte = rxPacket.frame;
}
inline void abortReceive()
{
isReceiving = FALSE;
call Interrupt.disableFastAction();
TOSH_CLR_RADIO_RXTXEN_PIN();
}
}
- Previous message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/evb13192/tos/chips/mc13192/interfaces
mc13192EventTimer.nc, NONE, 1.1 mc13192Receive.nc, 1.1,
1.2 mc13192TimerInterrupt.nc, 1.1, 1.2 mc13192Send.nc, 1.2,
1.3 mc13192Control.nc, 1.1, 1.2 mc13192TimerCounter.nc, 1.1,
1.2 mc13192DataInterrupt.nc, 1.1, 1.2 mc13192Timer.nc, 1.1,
1.2 mc13192PowerManagement.nc, 1.1, 1.2 mc13192State.nc, 1.1,
1.2 mc13192CCA.nc, 1.1, 1.2 mc13192StreamEvents.nc, 1.1,
1.2 mc13192ControlInterrupt.nc, 1.1, 1.2 mc13192Regs.nc, 1.1, 1.2
- Next message: [Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/diku/evb13192/tos/chips/mc13192
mc13192ControlM.nc, 1.2, 1.3 mc13192HardwareM.nc, 1.1,
1.2 mc13192Const.h, 1.2, 1.3 mc13192TOSRadioC.nc, 1.2,
1.3 mc13192TOSRadioM.nc, 1.2, 1.3 mc13192InterruptM.nc, 1.3,
1.4 mc13192DataM.nc, 1.7, 1.8 mc13192StateM.nc, 1.1,
1.2 mc13192Ieee802154M.nc, 1.10, 1.11 mc13192RawRadioC.nc, 1.2,
1.3 mc13192TimerM.nc, 1.1, 1.2 mc13192TimerCounterM.nc, 1.1,
1.2 mc13192Ieee802154RadioC.nc, 1.4, 1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-contrib-commits
mailing list