📄 cc1000radiointm.nc
字号:
// $Id: CC1000RadioIntM.nc,v 1.2 2004/09/24 21:46:37 dcm Exp $
/* -*- Mode: C; c-basic-indent: 2; indent-tabs-mode: nil -*- */
/* tab:4
*
*
* "Copyright (c) 2000-2002 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."
*
*/
/* 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.
*
*
*/
/*
* Authors: Philip Buonadonna, Jaein Jeong, Joe Polastre, Crossbow Technologies
* Date last modified: $Revision: 1.2 $
*
* This module provides the layer2 functionality for the mica2 radio.
* While the internal architecture of this module is not CC1000 specific,
* It does make some CC1000 specific calls via CC1000Control.
*
*/
/**
* @author Philip Buonadonna
* @author Jaein Jeong
* @author Joe Polastre
*/
includes crc;
includes CC1000Const;
module CC1000RadioIntM {
provides {
interface StdControl;
interface BareSendMsg as Send;
interface ReceiveMsg as Receive;
command result_t EnableRSSI();
command result_t DisableRSSI();
command result_t SetListeningMode(uint8_t power);
command uint8_t GetListeningMode();
command result_t SetTransmitMode(uint8_t power);
command uint8_t GetTransmitMode();
command uint16_t GetSquelch();
async command uint8_t GetRxBitOffset();
async command result_t CancelQueuedPacket();
interface RadioCoordinator as RadioSendCoordinator;
interface RadioCoordinator as RadioReceiveCoordinator;
interface MacControl;
interface MacBackoff;
}
uses {
interface PowerManagement;
interface StdControl as CC1000StdControl;
interface CC1000Control;
interface Random;
interface ADCControl;
interface ADC as RSSIADC;
interface SpiByteFifo;
interface StdControl as TimerControl;
interface Timer as WakeupTimer;
interface Timer as SquelchTimer;
interface Leds;
async command uint16_t GetClockLow();
}
}
implementation {
enum {
TX_STATE,
DISABLED_STATE,
IDLE_STATE,
PRETX_STATE,
SYNC_STATE,
RX_STATE,
SENDING_ACK,
POWER_DOWN_STATE,
NULL_STATE
};
enum {
TXSTATE_WAIT,
TXSTATE_START,
TXSTATE_PREAMBLE,
TXSTATE_SYNC,
TXSTATE_DATA,
TXSTATE_CRC,
TXSTATE_FLUSH,
TXSTATE_WAIT_FOR_ACK,
TXSTATE_READ_ACK,
TXSTATE_DONE
};
enum {
SYNC_BYTE = 0x33,
NSYNC_BYTE = 0xcc,
SYNC_WORD = 0x33cc,
NSYNC_WORD = 0xcc33,
ACK_LENGTH = 16,
MAX_ACK_WAIT = 18
};
uint8_t ack_code[3] = {0xab, 0xba, 0x83};
uint8_t RadioState;
uint8_t RadioTxState;
uint8_t RSSIInitState;
norace uint8_t iRSSIcount;
uint8_t iSquelchCount;
uint16_t txlength;
uint16_t rxlength;
TOS_MsgPtr txbufptr; // pointer to transmit buffer
TOS_MsgPtr rxbufptr; // pointer to receive buffer
TOS_Msg RxBuf; // save received messages
uint8_t NextTxByte;
uint8_t lplpower; // low power listening mode
uint8_t lplpowertx; // low power listening transmit mode
uint16_t preamblelen; // current length of the preamble
uint16_t PreambleCount; // found a valid preamble
uint8_t SOFCount;
uint16_t search_word;
union {
uint16_t W;
struct {
uint8_t LSB;
uint8_t MSB;
};
} RxShiftBuf;
uint8_t RxBitOffset; // bit offset for spibus
uint16_t RxByteCnt; // received byte counter
uint16_t TxByteCnt;
uint16_t RSSISampleFreq; // in Bytes rcvd per sample
norace bool bInvertRxData; // data inverted
bool bTxPending;
bool bTxBusy;
bool bAckEnable;
uint16_t usRunningCRC; // Running CRC variable
norace uint16_t usRSSIVal; // suppress nesc warnings
uint16_t usSquelchVal;
uint16_t usTempSquelch;
uint8_t usSquelchIndex;
uint16_t usSquelchTable[CC1K_SquelchTableSize];
int16_t sMacDelay; // MAC delay for the next transmission
// XXX-PB:
// Here's the deal, the mica (RFM) radio stacks used TOS_LOCAL_ADDRESS
// to determine if an L2 ack was reqd. This stack doesn't do L2 acks
// and, thus doesn't need it. HOWEVER, some set-mote-id versions
// break if this symbol is missing from the binary.
// Thus, I put this LocalAddr here and set it to TOS_LOCAL_ADDRESS
// to keep things happy for now.
volatile uint16_t LocalAddr;
///**********************************************************
//* local function definitions
//**********************************************************/
/*
int sortByShort(const void *x, const void *y) {
uint16_t* x1 = (uint16_t*)x;
uint16_t* y1 = (uint16_t*)y;
if (x1[0] > y1[0]) return -1;
if (x1[0] == y1[0]) return 0;
if (x1[0] < y1[0]) return 1;
return 0; // shouldn't reach here becasue it covers all the cases
}
*/
task void adjustSquelch() {
uint16_t tempArray[CC1K_SquelchTableSize];
char i,j,min;
uint16_t min_value;
uint32_t tempsquelch;
atomic {
usSquelchTable[usSquelchIndex] = usTempSquelch;
usSquelchIndex++;
if (usSquelchIndex >= CC1K_SquelchTableSize)
usSquelchIndex = 0;
if (iSquelchCount <= CC1K_SquelchCount)
iSquelchCount++;
}
for (i=0; i<CC1K_SquelchTableSize; i++) {
tempArray[(int)i] = usSquelchTable[(int)i];
}
min = 0;
// for (j = 0; j < ((CC1K_SquelchTableSize) >> 1); j++) {
for (j = 0; j < 3; j++) {
for (i = 1; i < CC1K_SquelchTableSize; i++) {
if ((tempArray[(int)i] != 0xFFFF) &&
((tempArray[(int)i] > tempArray[(int)min]) ||
(tempArray[(int)min] == 0xFFFF))) {
min = i;
}
}
min_value = tempArray[(int)min];
tempArray[(int)min] = 0xFFFF;
}
tempsquelch = ((uint32_t)(usSquelchVal << 5) + (uint32_t)(min_value << 1));
atomic usSquelchVal = (uint16_t)((tempsquelch / 34) & 0x0FFFF);
/*
// XXX: qsort actually causes ~600bits/sec lower bandwidth... why???
//
qsort (tempArray,CC1K_SquelchTableSize, sizeof(uint16_t),sortByShort);
min_value = tempArray[CC1K_SquelchTableSize >> 1];
atomic usSquelchVal = ((usSquelchVal << 5) + (min_value << 1)) / 34;
*/
}
task void PacketRcvd() {
TOS_MsgPtr pBuf;
atomic {
// rxbufptr->time = 0;
pBuf = rxbufptr;
}
pBuf = signal Receive.receive((TOS_MsgPtr)pBuf);
atomic {
if (pBuf)
rxbufptr = pBuf;
rxbufptr->length = 0;
}
call SpiByteFifo.enableIntr();
}
task void PacketSent() {
TOS_MsgPtr pBuf; //store buf on stack
atomic {
// txbufptr->time = 0;
pBuf = txbufptr;
}
signal Send.sendDone((TOS_MsgPtr)pBuf,SUCCESS);
atomic bTxBusy = FALSE;
}
///**********************************************************
//* Exported interface functions
//**********************************************************/
command result_t StdControl.init() {
char i;
atomic {
RadioState = DISABLED_STATE;
RadioTxState = TXSTATE_PREAMBLE;
RSSIInitState = NULL_STATE;
rxbufptr = &RxBuf;
rxbufptr->length = 0;
rxlength = MSG_DATA_SIZE-2;
RxBitOffset = 0;
iSquelchCount = 0;
PreambleCount = 0;
RSSISampleFreq = 0;
RxShiftBuf.W = 0;
iRSSIcount = 0;
bTxPending = FALSE;
bTxBusy = FALSE;
bAckEnable = FALSE;
sMacDelay = -1;
usRSSIVal = -1;
usSquelchIndex = 0;
lplpower = lplpowertx = 0;
usSquelchVal = CC1K_SquelchInit;
}
for (i = 0; i < CC1K_SquelchTableSize; i++)
usSquelchTable[(int)i] = CC1K_SquelchInit;
call SpiByteFifo.initSlave(); // set spi bus to slave mode
call CC1000StdControl.init();
call CC1000Control.SelectLock(0x9); // Select MANCHESTER VIOLATION
bInvertRxData = call CC1000Control.GetLOStatus();
call ADCControl.bindPort(TOS_ADC_CC_RSSI_PORT,TOSH_ACTUAL_CC_RSSI_PORT);
call ADCControl.init();
call Random.init();
call TimerControl.init();
LocalAddr = TOS_LOCAL_ADDRESS;
return SUCCESS;
}
command result_t EnableRSSI() {
return SUCCESS;
}
command result_t DisableRSSI() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -