微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI无线射频设计 > CC2500偶尔出现不能接收的现象

CC2500偶尔出现不能接收的现象

时间:12-23 整理:3721RD 点击:

uchar8_t MRFI_Receive(uchar8_t *pPacket)
{
uchar8_t frameLen;
uchar8_t rxBytes;

/* ------------------------------------------------------------------
* Get RXBYTES
* -------------
*/

/*
* Read the RXBYTES register from the radio.
* Bit description of RXBYTES register:
* bit 7 - RXFIFO_OVERFLOW, set if receive overflow occurred
* bits 6:0 - NUM_BYTES, number of bytes in receive FIFO
*
* Due a chip bug, the RXBYTES register must read the same value twice
* in a row to guarantee an accurate value.
*/
{
uchar8_t rxBytesVerify;

rxBytesVerify = halSpiReadStatusReg( CCxxx0_RXBYTES );

do
{
rxBytes = rxBytesVerify;
rxBytesVerify = halSpiReadStatusReg( CCxxx0_RXBYTES );
}
while (rxBytes != rxBytesVerify);
}
/* ------------------------------------------------------------------
* FIFO empty?
* -------------
*/

/*
* See if the receive FIFIO is empty before attempting to read from it.
* It is possible nothing the FIFO is empty even though the interrupt fired.
* This can happen if address check is enabled and a non-matching packet is
* received. In that case, the radio automatically removes the packet from
* the FIFO.
*/
if (rxBytes == 0)
{
/* receive FIFO is empty - do nothing, skip to end */
frameLen = 0;
}
else
{
/* receive FIFO is not empty, continue processing */

/* ------------------------------------------------------------------
* Process frame length
* ----------------------
*/

/* read the first byte from FIFO - the packet length */
halSpiReadBurstReg(CCxxx0_RXFIFO,&frameLen,MRFI_LENGTH_FIELD_SIZE);

/*
* Make sure that the frame length just read corresponds to number of bytes in the buffer.
* If these do not match up something is wrong.
*
* This can happen for several reasons:
* 1) Incoming packet has an incorrect format or is corrupted.
* 2) The receive FIFO overflowed. Overflow is indicated by the high
* bit of rxBytes. This guarantees the value of rxBytes value will not
* match the number of bytes in the FIFO for overflow condition.
* 3) Interrupts were blocked for an abnormally long time which
* allowed a following packet to at least start filling the
* receive FIFO. In this case, all received and partially received
* packets will be lost - the packet in the FIFO and the packet coming in.
* This is the price the user pays if they implement a giant
* critical section.
* 4) A failed transmit forced radio to IDLE state to flush the transmit FIFO.
* This could cause an active receive to be cut short.
*
* Also check the sanity of the length to guard against rogue frames.
*/
if ((rxBytes != (frameLen + MRFI_LENGTH_FIELD_SIZE + MRFI_RX_METRICS_SIZE)) ||
((frameLen + MRFI_LENGTH_FIELD_SIZE) > MRFI_MAX_FRAME_SIZE) ||
(frameLen < MRFI_MIN_SMPL_FRAME_SIZE)
)
{
/* mismatch between bytes-in-FIFO and frame length */
//rt_kprintf("\nrxBytes = %d,frameLen = %d\n",rxBytes,frameLen);
/*
* Flush receive FIFO to reset receive. Must go to IDLE state to do this.
* The critical section guarantees a transmit does not occur while cleaning up.
*/
MRFI_STROBE_IDLE_AND_WAIT();
halSpiStrobe(CCxxx0_SFRX);

frameLen = 0;

/* flush complete, skip to end */
}
else
{
/* bytes-in-FIFO and frame length match up - continue processing */

/* ------------------------------------------------------------------
* Get packet
* ------------
*/

halSpiReadBurstReg(CCxxx0_RXFIFO,pPacket + MRFI_LENGTH_FIELD_SIZE,frameLen + MRFI_RX_METRICS_SIZE);
*pPacket = frameLen;
}
}
/* Done with RX. Clean up time... */

/* Radio is already in IDLE state */

//! CC2500 clr rx buffer,this cmd is necessary
halSpiStrobe(CCxxx0_SFRX);

MRFI_RxOn();

return frameLen;
}

void MRFI_RxOn(void)
{
//! enable receive
mrfiRadioState = MRFI_RADIO_STATE_RX;

halSpiStrobe(CCxxx0_SRX);
}

这个是我接收数据处理的部分,参考了SimpelicTi的接收部分,CC2500的配置同SmartRF 提供250Kbps的配置基本一致

GDO0中断触发MRFI_Receive。

现在存在如下问题:

如果短时间内,同时有多个CC2500在发数据,在接收数据的CC2500就偶尔会出现突然收不到数据的情况,直到程序自检发现,超过1分钟未收到数据就会作如下处理之后又恢复正常。

/* disable EX0 */
DISABLE_EX0();

//! CC2500 Enter idle mode
MRFI_STROBE_IDLE_AND_WAIT();
//! frequency correct
halSpiStrobe(CCxxx0_SCAL);
//! Clear RX buffer
halSpiStrobe(CCxxx0_SFRX);
//! Turn on the receiver
MRFI_RxOn();

/* enable EX0 */
ENABLE_EX0();

开始以为,可能是某次接收数据异常,C2500未正确进入到接收模式,于是在接收中断处理MRFI_Receive后又多加入了如下操作:

//! flush the receive FIFO
halSpiStrobe(CCxxx0_SFRX);

halSpiStrobe(CCxxx0_SIDLE);
halSpiStrobe(CCxxx0_SCAL);

//! send strobe to enter receive mode
halSpiStrobe(CCxxx0_SRX);

但是这样处理后,还是存在突然无法接收问题。

现在我自己的理解像是这样的情况:CC2500某次接收异常,但是未触发单片机的外部中断(要么是GDO0根本就没有变化,要么是变化不足以触发单片机中断),但是CC2500此时已经不在接收状态了,又因为进不了中断,所以无法正常恢复到接收状态,直到系统自检后恢复正常。

请教一下各位大神,是否也遇到有类似的情况,或者是我的处理上哪里还存在缺陷;或者确实存在和我理解的一致的情况(未进入中断),如果是这样,那么就只能增加自检的频率来解决吗?

问题比较急,这个问题会严重影响我们产品的稳定性和体验,麻烦大家帮帮忙

谢谢!

首先先确认一下CC2500是否工作正常,使用SmartRF studio7检测一下,如果收发正常,在检测一下中断引脚的电压大小和波形,最后再检查代码

同时可靠接收多个发送的无线数据难度大,可以采用主机论寻工作。

多个同时发送时,空中包相互干扰,接收到的可能是错包,你代码做的工作是进入idle, 然后清Rx Buffer, 然后就好了。估计就是Rx buffer收到错包,但是中断不给MCU, 

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top