📄 cc1000radiointm.nc
字号:
return SUCCESS;
}
command uint8_t GetTransmitMode() {
return lplpowertx;
}
async command uint8_t GetRxBitOffset() {
return RxBitOffset;
}
/**
* Set the state of low power transmit on the chipcon radio.
* The transmit mode of the sender *must* match the receiver in
* order for the receiver to successfully get the packet.
* <p>
* The default power up state is 0 (radio always on).
* See CC1000Const.h for low power duty cycles and bandwidth
*/
command result_t SetTransmitMode(uint8_t power) {
if ((power >= CC1K_LPL_STATES) || (power == lplpowertx))
return FAIL;
// check if the radio is currently doing something
if ((!bTxPending) && ((RadioState == POWER_DOWN_STATE) ||
(RadioState == IDLE_STATE) ||
(RadioState == DISABLED_STATE))) {
atomic {
lplpowertx = power;
preamblelen = ((PRG_RDB(&CC1K_LPL_PreambleLength[lplpowertx*2]) << 8)
| PRG_RDB(&CC1K_LPL_PreambleLength[(lplpowertx*2)+1]));
}
return SUCCESS;
}
return FAIL;
}
/**
* Set the state of low power listening on the chipcon radio.
* <p>
* The default power up state is 0 (radio always on).
* See CC1000Const.h for low power duty cycles and bandwidth
*/
command result_t SetListeningMode(uint8_t power) {
// valid low power listening values are 0 to 3
// 0 is "always on" and 3 is lowest duty cycle
// 1 and 2 are in the middle
if ((power >= CC1K_LPL_STATES) || (power == lplpower))
return FAIL;
// check if the radio is currently doing something
if ((!bTxPending) && ((RadioState == POWER_DOWN_STATE) ||
(RadioState == IDLE_STATE) ||
(RadioState == DISABLED_STATE))) {
// change receiving function in CC1000Radio
call WakeupTimer.stop();
atomic {
if (lplpower == lplpowertx) {
lplpowertx = power;
}
lplpower = power;
}
// if successful, change power here
if (RadioState == IDLE_STATE) {
RadioState = DISABLED_STATE;
call StdControl.stop();
call StdControl.start();
}
if (RadioState == POWER_DOWN_STATE) {
RadioState = DISABLED_STATE;
call StdControl.start();
call PowerManagement.adjustPower();
}
}
else {
return FAIL;
}
return SUCCESS;
}
/**
* Gets the state of low power listening on the chipcon radio.
* <p>
* @return Current low power listening state value
*/
command uint8_t GetListeningMode() {
return lplpower;
}
/*
* DCM: Added for use by crickets
*
* This command will cancel an outgoing packet that has been sent
* using the Send.send() command. As long as the packet or its
* preamble has not been put on the air yet, this command will
* succeed.
*/
async command result_t CancelQueuedPacket() {
uint8_t fail = 0;
atomic {
if (RadioState == TX_STATE)
fail = 1;
if (RadioState == PRETX_STATE && sMacDelay <= 0)
fail = 1;
}
if (fail)
return FAIL;
atomic {
bTxPending = FALSE;
bTxBusy = FALSE;
}
}
event result_t SquelchTimer.fired() {
char currentRadioState;
atomic currentRadioState = RadioState;
if (currentRadioState == IDLE_STATE) {
atomic RSSIInitState = currentRadioState;
call RSSIADC.getData();
}
return SUCCESS;
}
event result_t WakeupTimer.fired() {
uint16_t sleeptime;
bool tempTxPending;
uint8_t currentRadioState;
if (lplpower == 0)
return SUCCESS;
atomic {
currentRadioState = RadioState;
tempTxPending = bTxPending;
}
switch(currentRadioState) {
case IDLE_STATE:
sleeptime = ((PRG_RDB(&CC1K_LPL_SleepTime[lplpower*2]) << 8) |
PRG_RDB(&CC1K_LPL_SleepTime[(lplpower*2)+1]));
if (!tempTxPending) {
atomic RadioState = POWER_DOWN_STATE;
call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime);
call SquelchTimer.stop();
call CC1000StdControl.stop();
call SpiByteFifo.disableIntr();
}
else {
call WakeupTimer.start(TIMER_ONE_SHOT, CC1K_LPL_PACKET_TIME*2);
}
break;
case POWER_DOWN_STATE:
sleeptime = PRG_RDB(&CC1K_LPL_SleepPreamble[lplpower]);
atomic RadioState = IDLE_STATE;
call CC1000StdControl.start();
call CC1000Control.BIASOn();
call SpiByteFifo.rxMode(); // SPI to miso
call CC1000Control.RxMode();
call SpiByteFifo.enableIntr(); // enable spi interrupt
if (iSquelchCount > CC1K_SquelchCount)
call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow);
else
call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast);
call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime);
break;
default:
call WakeupTimer.start(TIMER_ONE_SHOT, CC1K_LPL_PACKET_TIME*2);
}
return SUCCESS;
}
command result_t StdControl.stop() {
atomic RadioState = DISABLED_STATE;
call SquelchTimer.stop();
call WakeupTimer.stop();
call CC1000StdControl.stop();
call SpiByteFifo.disableIntr(); // disable spi interrupt
return SUCCESS;
}
command result_t StdControl.start() {
uint8_t currentRadioState;
atomic currentRadioState = RadioState;
if (currentRadioState == DISABLED_STATE) {
atomic {
rxbufptr->length = 0;
RadioState = IDLE_STATE;
bTxPending = bTxBusy = FALSE;
sMacDelay = -1;
preamblelen = ((PRG_RDB(&CC1K_LPL_PreambleLength[lplpowertx*2]) << 8) |
PRG_RDB(&CC1K_LPL_PreambleLength[(lplpowertx*2)+1]));
}
if (lplpower == 0) {
// all power on, captain!
rxbufptr->length = 0;
atomic RadioState = IDLE_STATE;
call CC1000StdControl.start();
call CC1000Control.BIASOn();
call SpiByteFifo.rxMode(); // SPI to miso
call CC1000Control.RxMode();
if (iSquelchCount > CC1K_SquelchCount)
call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow);
else
call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast);
call SpiByteFifo.enableIntr(); // enable spi interrupt
}
else {
uint16_t sleeptime = ((PRG_RDB(&CC1K_LPL_SleepTime[lplpower*2]) << 8) |
PRG_RDB(&CC1K_LPL_SleepTime[(lplpower*2)+1]));
atomic RadioState = POWER_DOWN_STATE;
call TimerControl.start();
call SquelchTimer.stop();
call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime);
}
}
return SUCCESS;
}
command result_t Send.send(TOS_MsgPtr pMsg) {
result_t Result = SUCCESS;
uint8_t currentRadioState = 0;
atomic {
if (bTxBusy) {
Result = FAIL;
}
else {
bTxBusy = TRUE;
txbufptr = pMsg;
txlength = pMsg->length + (MSG_DATA_SIZE - DATA_LENGTH - 2);
// initially back off [1,32] bytes (approx 2/3 packet)
sMacDelay = signal MacBackoff.initialBackoff(pMsg);
bTxPending = TRUE;
}
currentRadioState = RadioState;
}
if (Result) {
// if we're off, start the radio
if (currentRadioState == POWER_DOWN_STATE) {
// disable wakeup timer
call WakeupTimer.stop();
call CC1000StdControl.start();
call CC1000Control.BIASOn();
call CC1000Control.RxMode();
call SpiByteFifo.rxMode(); // SPI to miso
call SpiByteFifo.enableIntr(); // enable spi interrupt
if (iSquelchCount > CC1K_SquelchCount)
call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow);
else
call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast);
call WakeupTimer.start(TIMER_ONE_SHOT, CC1K_LPL_PACKET_TIME*2);
atomic RadioState = IDLE_STATE;
}
}
return Result;
}
/**********************************************************
* make a spibus interrupt handler
* needs to handle interrupts for transmit delay
* and then go into byte transmit mode with
* timer1 baudrate delay as interrupt handler
* else
* needs to handle interrupts for byte read and detect preamble
* then handle reading a packet
* PB - We can use this interrupt handler as a transmit scheduler
* because the CC1000 continuously clocks in data, regarless
* of whether it's good or not. Thus, this routine will be called
* on every 8 ticks of DCLK.
**********************************************************/
async event result_t SpiByteFifo.dataReady(uint8_t data_in) {
signal RadioSendCoordinator.blockTimer();
signal RadioReceiveCoordinator.blockTimer();
if (bInvertRxData)
data_in = ~data_in;
#ifdef ENABLE_UART_DEBUG
UARTPutChar(RadioState);
#endif
switch (RadioState) {
case TX_STATE:
{
call SpiByteFifo.writeByte(NextTxByte);
TxByteCnt++;
switch (RadioTxState) {
case TXSTATE_PREAMBLE:
if (!(TxByteCnt < preamblelen)) {
NextTxByte = SYNC_BYTE;
RadioTxState = TXSTATE_SYNC;
}
break;
case TXSTATE_SYNC:
NextTxByte = NSYNC_BYTE;
RadioTxState = TXSTATE_DATA;
TxByteCnt = -1;
// for Time Sync services
signal RadioSendCoordinator.startSymbol(8, 0, txbufptr);
break;
case TXSTATE_DATA:
if ((uint8_t)(TxByteCnt) < txlength) {
NextTxByte = ((uint8_t *)txbufptr)[(TxByteCnt)];
usRunningCRC = crcByte(usRunningCRC,NextTxByte);
// Time Sync
signal RadioSendCoordinator.byte(txbufptr, (uint8_t)TxByteCnt);
}
else {
NextTxByte = (uint8_t)(usRunningCRC);
RadioTxState = TXSTATE_CRC;
}
break;
case TXSTATE_CRC:
NextTxByte = (uint8_t)(usRunningCRC>>8);
RadioTxState = TXSTATE_FLUSH;
TxByteCnt = 0;
break;
case TXSTATE_FLUSH:
if (TxByteCnt > 3) {
if (bAckEnable) {
TxByteCnt = 0;
RadioTxState = TXSTATE_WAIT_FOR_ACK;
}
else {
RadioTxState = TXSTATE_DONE;
}
}
break;
case TXSTATE_WAIT_FOR_ACK:
if(TxByteCnt == 1){
call SpiByteFifo.rxMode();
call CC1000Control.RxMode();
}
if (TxByteCnt > 3) {
RadioTxState = TXSTATE_READ_ACK;
TxByteCnt = 0;
search_word = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -