📄 cc1000radiointm.nc
字号:
break;
case TXSTATE_READ_ACK:
{
uint8_t i;
for(i = 0; i < 8; i ++){
search_word <<= 1;
if(data_in & 0x80) search_word |= 0x1;
data_in <<= 1;
if (search_word == 0xba83){
txbufptr->ack = 1;
RadioTxState = TXSTATE_DONE;
return SUCCESS;
}
}
}
if(TxByteCnt == MAX_ACK_WAIT){
txbufptr->ack = 0;
RadioTxState = TXSTATE_DONE;
}
break;
case TXSTATE_DONE:
default:
bTxPending = FALSE;
if (post PacketSent()) {
// If the post operation succeeds, goto Idle
// otherwise, we'll try again.
call SpiByteFifo.rxMode();
call CC1000Control.RxMode();
RadioState = IDLE_STATE;
RSSIInitState = RadioState;
call RSSIADC.getData();
}
break;
}
}
break;
case DISABLED_STATE:
break;
case IDLE_STATE:
{
if (((data_in == (0xaa)) || (data_in == (0x55)))) {
PreambleCount++;
if (PreambleCount > CC1K_ValidPrecursor) {
PreambleCount = SOFCount = 0;
RxBitOffset = RxByteCnt = 0;
usRunningCRC = 0;
rxlength = MSG_DATA_SIZE-2;
RadioState = SYNC_STATE;
}
}
else if (bTxPending && (--sMacDelay <= 0)) {
RadioState = PRETX_STATE;
RSSIInitState = PRETX_STATE;
iRSSIcount = 0;
PreambleCount = 0;
call RSSIADC.getData();
}
}
break;
case PRETX_STATE:
{
if (((data_in == (0xaa)) || (data_in == (0x55)))) {
// Back to the penalty box.
sMacDelay = signal MacBackoff.congestionBackoff(txbufptr);
RadioState = IDLE_STATE;
}
}
break;
case SYNC_STATE:
{
// draw in the preamble bytes and look for a sync byte
// save the data in a short with last byte received as msbyte
// and current byte received as the lsbyte.
// use a bit shift compare to find the byte boundary for the sync byte
// retain the shift value and use it to collect all of the packet data
// check for data inversion, and restore proper polarity
// XXX-PB: Don't do this.
uint8_t i;
if ((data_in == 0xaa) || (data_in == 0x55)) {
// It is actually possible to have the LAST BIT of the incoming
// data be part of the Sync Byte. SO, we need to store that
// However, the next byte should definitely not have this pattern.
// XXX-PB: Do we need to check for excessive preamble?
RxShiftBuf.MSB = data_in;
}
else {
// TODO: Modify to be tolerant of bad bits in the preamble...
uint16_t usTmp;
switch (SOFCount) {
case 0:
RxShiftBuf.LSB = data_in;
break;
case 1:
case 2:
// bit shift the data in with previous sample to find sync
usTmp = RxShiftBuf.W;
RxShiftBuf.W <<= 8;
RxShiftBuf.LSB = data_in;
for(i=0;i<8;i++) {
usTmp <<= 1;
if(data_in & 0x80)
usTmp |= 0x1;
data_in <<= 1;
// check for sync bytes
if (usTmp == SYNC_WORD) {
if (rxbufptr->length !=0) {
call Leds.redToggle();
RadioState = IDLE_STATE;
}
else {
RadioState = RX_STATE;
RSSIInitState = RX_STATE;
call RSSIADC.getData();
RxBitOffset = 7-i;
// For time sync services
signal RadioReceiveCoordinator.startSymbol(8, RxBitOffset, rxbufptr);
}
break;
}
}
break;
default:
// We didn't find it after a reasonable number of tries, so....
RadioState = IDLE_STATE; // Ensures we wait till the end of the transmission
break;
}
SOFCount++;
}
}
break;
// collect the data and shift into double buffer
// shift out data by correct offset
// invert the data if necessary
// stop after the correct packet length is read
// return notification to upper levels
// go back to idle state
case RX_STATE:
{
char Byte;
RxShiftBuf.W <<=8;
RxShiftBuf.LSB = data_in;
Byte = (RxShiftBuf.W >> RxBitOffset);
((char*)rxbufptr)[(int)RxByteCnt] = Byte;
RxByteCnt++;
// Time Sync: substract one to start counting from zero
signal RadioReceiveCoordinator.byte(rxbufptr, (uint8_t)RxByteCnt-1);
if (RxByteCnt < rxlength) {
usRunningCRC = crcByte(usRunningCRC,Byte);
/* DCM: timestamp received packets with a millisecond timer */
if (RxByteCnt == (offsetof(struct TOS_Msg,data))) {
rxbufptr->time = call GetClockLow();
}
if (RxByteCnt == (offsetof(struct TOS_Msg,length) +
sizeof(((struct TOS_Msg *)0)->length))) {
rxlength = rxbufptr->length;
if (rxlength > TOSH_DATA_LENGTH) {
// The packet's screwed up, so just dump it
rxbufptr->length = 0;
RadioState = IDLE_STATE; // Waits till end of transmission
return SUCCESS;
}
//Add in the header size
rxlength += offsetof(struct TOS_Msg,data);
}
}
else if (RxByteCnt == rxlength) {
usRunningCRC = crcByte(usRunningCRC,Byte);
// Shift index ahead to the crc field.
RxByteCnt = offsetof(struct TOS_Msg,crc);
}
else if (RxByteCnt >= MSG_DATA_SIZE) {
// Packet filtering based on bad CRC's is done at higher layers.
// So sayeth the TOS weenies.
if (rxbufptr->crc == usRunningCRC) {
rxbufptr->crc = 1;
if (bAckEnable) {
if (rxbufptr->addr == TOS_LOCAL_ADDRESS) {
RadioState = SENDING_ACK;
call CC1000Control.TxMode();
call SpiByteFifo.txMode();
call SpiByteFifo.writeByte(0xaa);
RxByteCnt = 0;
return SUCCESS;
}
}
} else {
rxbufptr->crc = 0;
}
call SpiByteFifo.disableIntr();
RadioState = IDLE_STATE; //DISABLED_STATE;
rxbufptr->strength = usRSSIVal;
if (!(post PacketRcvd())) {
// If there are insufficient resources to process the incoming packet
// we drop it
rxbufptr->length = 0;
RadioState = IDLE_STATE;
call SpiByteFifo.enableIntr();
}
}
}
break;
case SENDING_ACK:
{
RxByteCnt++;
if (RxByteCnt >= ACK_LENGTH) {
call CC1000Control.RxMode();
call SpiByteFifo.rxMode();
call SpiByteFifo.disableIntr();
RadioState = IDLE_STATE; //DISABLED_STATE;
rxbufptr->strength = usRSSIVal;
if (!(post PacketRcvd())) {
rxbufptr->length = 0;
RadioState = IDLE_STATE;
call SpiByteFifo.enableIntr();
}
}else if(RxByteCnt >= ACK_LENGTH - sizeof(ack_code) - 2){
call SpiByteFifo.writeByte(ack_code[RxByteCnt + sizeof(ack_code) + 2- ACK_LENGTH]);
}
}
break;
default:
break;
}
return SUCCESS;
}
async event result_t RSSIADC.dataReady(uint16_t data) {
uint8_t currentRadioState;
uint8_t initRSSIState;
atomic {
currentRadioState = RadioState;
initRSSIState = RSSIInitState;
}
// find the maximum RSSI value over CC1K_MAX_RSSI_SAMPLES
switch(currentRadioState) {
case IDLE_STATE:
if (initRSSIState == IDLE_STATE) {
atomic usTempSquelch = data;
post adjustSquelch();
}
atomic RSSIInitState = NULL_STATE;
break;
case RX_STATE:
if (initRSSIState == RX_STATE) {
atomic usRSSIVal = data;
}
atomic RSSIInitState = NULL_STATE;
break;
case PRETX_STATE:
iRSSIcount++;
// if the channel is clear, GO GO GO!
if ((data > (usSquelchVal + CC1K_SquelchBuffer)) && (initRSSIState == PRETX_STATE)) {
call SpiByteFifo.writeByte(0xaa);
call CC1000Control.TxMode();
call SpiByteFifo.txMode();
atomic {
usRSSIVal = data;
iRSSIcount = CC1K_MaxRSSISamples;
TxByteCnt = 0;
usRunningCRC = 0;
RadioState = TX_STATE;
RadioTxState = TXSTATE_PREAMBLE;
NextTxByte = 0xaa;
RSSIInitState = NULL_STATE;
}
return SUCCESS;
}
atomic RSSIInitState = NULL_STATE;
if (iRSSIcount == CC1K_MaxRSSISamples) {
atomic {
sMacDelay = signal MacBackoff.congestionBackoff(txbufptr);
RadioState = IDLE_STATE;
}
}
else {
atomic RSSIInitState = currentRadioState;
call RSSIADC.getData();
}
break;
default:
}
return SUCCESS;
}
async command void MacControl.enableAck() {
bAckEnable = TRUE;
}
async command void MacControl.disableAck() {
bAckEnable = FALSE;
}
// XXX:JP- for testing the mac layer squlech value
command uint16_t GetSquelch() {
return usSquelchVal;
}
// Default events for radio send/receive coordinators do nothing.
// Be very careful using these, you'll break the stack.
default async event void RadioSendCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff) { }
default async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
default async event void RadioSendCoordinator.blockTimer() { }
default async event void RadioReceiveCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset, TOS_MsgPtr msgBuff) { }
default async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
default async event void RadioReceiveCoordinator.blockTimer() { }
default async event int16_t MacBackoff.initialBackoff(TOS_MsgPtr m) {
return (call Random.rand() & 0x1F) + 1;
// return 0;
}
default async event int16_t MacBackoff.congestionBackoff(TOS_MsgPtr m) {
return (call Random.rand() & 0xF) + 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -