请教Ti关于TX-if-CCA的问题
在CC1100E的手册Page49提到,可采用CCA方式以避免载波冲突,具体方法为先进入RX状态,然后直接TX发送。这里面的MCSM1应该如何设置?RSSI的阈值在哪个寄存器设置且一般设置为多少?如果采用相对阈值又是如何设置的?发出STX指令后,如何检查是成功或者是继续保持在RX状态?
看SimpliciTI协议栈的family1下的Mrfi_radio.c中的MRFI_Transmit(),已经完整的实现了TX-IF-CCA的功能。
边看代码边研究吧,你想知道的MCSM1设置,RSSI阀值都有。
uint8_t MRFI_Transmit(mrfiPacket_t * pPacket, uint8_t txType)
{
#ifdef NWK_PLL
bspIState_t s;
#endif
uint8_t ccaRetries;
uint8_t returnValue = MRFI_TX_RESULT_SUCCESS;
/* radio must be awake to transmit */
MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF );
/* Turn off reciever. We can ignore/drop incoming packets during transmit. */
Mrfi_RxModeOff();
MRFI_PrepareToTx( pPacket );
/* ------------------------------------------------------------------
* Immediate transmit
* ---------------------
*/
if (txType == MRFI_TX_TYPE_FORCED)
{
//#ifdef NWK_PLL
// BSP_ENTER_CRITICAL_SECTION(s);
//#endif
// MRFI_CompleteTxPrep( pPacket );
#ifdef NWK_PLL
do
{
BSP_ENTER_CRITICAL_SECTION(s);
if( stx_active == false ) // if the channel was changed
{
BSP_EXIT_CRITICAL_SECTION(s);
Mrfi_RxModeOff(); // turn off the radio
MRFI_PrepareToTx( pPacket ); // setup transmission again
continue; // restart the loop
}
MRFI_CompleteTxPrep( pPacket );
} while( 0 );
#endif
/* Issue the TX strobe. */
mrfiSpiCmdStrobe( STX );
#ifdef NWK_PLL
BSP_EXIT_CRITICAL_SECTION(s);
#endif
/* Wait for transmit to complete */
Mrfi_DelayUsecLong( MRFI_MAX_TRANSMIT_TIME_us / 1000,
MRFI_MAX_TRANSMIT_TIME_us % 1000,
mrfi_TxImmediateDone );
/* Clear the interrupt flag */
MRFI_CLEAR_SYNC_PIN_INT_FLAG();
}
else
{
/* ------------------------------------------------------------------
* CCA transmit
* ---------------
*/
MRFI_ASSERT( txType == MRFI_TX_TYPE_CCA );
/* set number of CCA retries */
ccaRetries = MRFI_CCA_RETRIES;
/* For CCA algorithm, we need to know the transition from the RX state to
* the TX state. There is no need for SYNC signal in this logic. So we
* can re-configure the GDO_0 output from the radio to be PA_PD signal
* instead of the SYNC signal.
* Since both SYNC and PA_PD are used as falling edge interrupts, we
* don't need to reconfigure the MCU input.
*/
MRFI_CONFIG_GDO0_AS_PAPD_SIGNAL();
/* ===============================================================================
* Main Loop
* =============
*/
for (;;)
{
/* Radio must be in RX mode for CCA to happen.
* Otherwise it will transmit without CCA happening.
*/
/* Can not use the Mrfi_RxModeOn() function here since it turns on the
* Rx interrupt, which we don't want in this case.
*/
mrfiSpiCmdStrobe( SRX );
/* wait for the rssi to be valid. */
#ifdef MRFI_TIMER_ALWAYS_ACTIVE
MRFI_WaitTimeoutUsec(MRFI_RSSI_VALID_DELAY_US, Mrfi_ValidateRSSI);
#else // MRFI_TIMER_ALWAYS_ACTIVE
MRFI_RSSI_VALID_WAIT();
#endif // MRFI_TIMER_ALWAYS_ACTIVE
#ifdef NWK_PLL
BSP_ENTER_CRITICAL_SECTION(s);
if( stx_active == false ) // if the channel was changed
{
BSP_EXIT_CRITICAL_SECTION(s);
Mrfi_RxModeOff(); // turn off the radio
MRFI_PrepareToTx( pPacket ); // setup transmission again
continue; // restart the cca loop
}
MRFI_CompleteTxPrep( pPacket );
#endif
/*
* Clear the PA_PD pin interrupt flag. This flag, not the interrupt itself,
* is used to capture the transition that indicates a transmit was started.
* The pin level cannot be used to indicate transmit success as timing may
* prevent the transition from being detected. The interrupt latch captures
* the event regardless of timing.
*/
MRFI_CLEAR_PAPD_PIN_INT_FLAG();
/* Issue the TX strobe. */
mrfiSpiCmdStrobe( STX );
#ifdef NWK_PLL
BSP_EXIT_CRITICAL_SECTION(s);
#endif
/* Delay long enough for the PA_PD signal to indicate a
* successful transmit. This is the 250 XOSC periods
* (9.6 us for a 26 MHz crystal) See section 19.6 of 2500 datasheet.
* Found out that we need a delay of atleast 20 us on CC2500 and
* 25 us on CC1100 to see the PA_PD signal change.
*/
Mrfi_DelayUsec(25);
/* PA_PD signal goes from HIGH to LOW when going from RX state.
* This transition is trapped as a falling edge interrupt flag
* to indicate that CCA passed and the transmit has started.
*/
if (MRFI_PAPD_INT_FLAG_IS_SET())
{
/* ------------------------------------------------------------------
* Clear Channel Assessment passed.
* ----------------------------------
*/
/* Clear the PA_PD int flag */
MRFI_CLEAR_PAPD_PIN_INT_FLAG();
Mrfi_DelayUsecLong( MRFI_MAX_TRANSMIT_TIME_us / 1000,
MRFI_MAX_TRANSMIT_TIME_us % 1000,
mrfi_TxCCADone );
/* transmit done, break */
break;
}
else
{
/* ------------------------------------------------------------------
* Clear Channel Assessment failed.
* ----------------------------------
*/
/* Turn off radio and save some power during backoff */
/* NOTE: Can't use Mrfi_RxModeOff() - since it tries to update the
* sync signal status which we are not using during the TX operation.
*/
MRFI_STROBE_IDLE_AND_WAIT();
/* flush the receive FIFO of any residual data */
mrfiSpiCmdStrobe( SFRX );
/* Retry ? */
if (ccaRetries != 0)
{
#ifdef MRFI_TIMER_ALWAYS_ACTIVE
stx_active = false;
#endif
/* delay for a random number of backoffs */
Mrfi_RandomBackoffDelay();
MRFI_PrepareToTx( pPacket ); // setup transmission again
/* decrement CCA retries before loop continues */
ccaRetries--;
}
else /* No CCA retries are left, abort */
{
/* set return value for failed transmit and break */
returnValue = MRFI_TX_RESULT_FAILED;
break;
}
} /* CCA Failed */
} /* CCA loop */
}/* txType is CCA */
/* Done with TX. Clean up time... */
/* Radio is already in IDLE state */
#ifdef NWK_PLL
stx_active = false;
// Packet transmitted, regardless of packet type, remove reference.
sTxTimeStampAddr = NULL;
#endif
/*
* Flush the transmit FIFO. It must be flushed so that
* the next transmit can start with a clean slate.
*/
mrfiSpiCmdStrobe( SFTX );
/* Restore GDO_0 to be SYNC signal */
MRFI_CONFIG_GDO0_AS_SYNC_SIGNAL();
/* If the radio was in RX state when transmit was attempted,
* put it back to Rx On state.
*/
if(mrfiRadioState == MRFI_RADIO_STATE_RX)
{
Mrfi_RxModeOn();
}
return( returnValue );
}
是否解决了你的问题,请确认
这段以前看过,但一直是看得头大。现在我是这样处理的:
MCSM1=0x30; //发现设置为其它也可以类似地处理
IOCCFG2=0x0E;
TI_CC_SPIStrobe(TI_CCxxx0_SFRX);
TI_CC_SPIStrobe(TI_CCxxx0_SRX); //开接收
delay_ms(1);
while (TI_CC_GDO2_PxIN & TI_CC_GDO2_PIN); //如有载波信号,则延时继续等待
RFSendPacket(TxBuf,leng); //直接进入发送
delay_us(809);
status1 = TI_CC_SPIReadStatus(TI_CCxxx0_MARCSTATE); //读取芯片状态
判断是否发送成功。
这里发现一个特点:如果有外部的同频信号干扰,则程序会长时间停止在TX状态,而当外部同频信号消失后会立即完成TX功能,此时若发送成功(对侧也收到了发送的内容)则status1 与设定的MCSM1的BIT0~1相同,若发送失败(对侧未收到)则status1 =0x0D表示RX状态。
但这里面并没有对RSSI的阈值的设置,目前是按TI的软件设置为默认的AGCCTRL1=0x40。
您好!根据您这段程序的设置,我在调试有关CCA空闲信道检测的时候,为什么我在调试的过程中不管有无接收到数据包(即不管信道是否空闲)
while (TI_CC_GDO2_PxIN & TI_CC_GDO2_PIN); 我的程序一直停止在这一句上面(TI_CC_GDO2_PxIN & TI_CC_GDO2_PIN一直为‘0’)。我的QQ为76018335,期待您的回复。谢谢!