This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC1101"死机"问题

Other Parts Discussed in Thread: CC1101, CC110L

测试系统为CC1101+stm32 MCU,一对一测试时,主机通过电脑串口收到指令后,向从机发送命令,从机收到指令后解析并返回响应,主机接收到从机响应后通过串口打印信息。电脑串口发送指令周期为250ms,持续运行2小时后测试系统正常(有丢包,但在正常范围内)。

增加到三组进行测试(每台设备都有唯一地址,每组两个设备通过通信协议中地址校验区分是否为同一组,以保证不会解析/响应其它设备命令),发现一般在20分钟内就会有一组设备出现异常,主从机都有可能。

程序配置为GDO0输出电平指示无线发送/接收状态,在测试异常情况下用万用表测量GDO0管脚电压,发现GDO0一直处于assert状态,那么程序就死在了查询GDO0状态的while(1)循环中,程序仿真发现是在发送时出现了异常。把其他正常通信设备关闭后,异常设备不能恢复正常通信。

多组测试情况下丢包率变高比较好理解,但按上述情况的话,好像硬件出了问题,导致死机。有相关经验大牛还请帮忙分析下!感谢~

  • 请问程序里面是不是有CCA,   LBT等防冲突的机制?每一次接收、发送完成之后会转入什么状态?

    感觉既然两个没有问题,三个有问题,更像是软件处理冲突导致的状态集变化没有处理好

  • 感谢@WBJ 解答,现在有cca,平时处于接收状态,发送完成后也转为接收状态。发送时相关代码如下


        CC1101SetIdle();//MUST BE IDLE MODE
        CC1101WriteCmd( CC1101_SFTX );

        CC1101WriteMultiReg( CC1101_TXFIFO, txbuffer, size );
        CC1101WriteCmd(CC1101_SIDLE);
        CC1101SetTRMode( TX_MODE );
        if( (CC1101ReadStatus(CC1101_PKTSTATUS)&0x10) == 0 )//cca
        {
            while( CC_IRQ_READ() != 0 );
            while( CC_IRQ_READ() == 0 );    
        }

        CC1101SetIdle();//MUST BE IDLE MODE
        CC1101WriteCmd( CC1101_SFTX );
        CC1101SetTRMode(RX_MODE);

    现在出问题的测试系统为3组,共6个设备。

    按照您说的,如果软件没有处理好冲突,会影响GDO0的输出状态吗?现在GDO0配置为0x06,什么情况下会一直处于assert状态?

  • assert应该是收到sync word的时候,

    可以用一个接收机接smartRF studio抓包看一下当前的空中信号发送状态,

    另外可以查一下如果收到错误的包的时候是否有做相应的flush的处理

  • @WBU 接收机得用官方的demo板是吗?如果买的话,国内比较快的正规渠道能说一下吗?

    射频接收这一块我刚看了下 ,应该是做了异常处理。以下是代码,劳烦给看下,感谢~

    INT8U CC1101RecPacket( INT8U *rxBuffer )
    {
        INT8U status[2];
        INT8U pktLen;
        INT16U x , j = 0;

        if ( CC1101GetRXCnt( ) != 0 )
        {
            pktLen = CC1101ReadReg(CC1101_RXFIFO);           // Read length byte
            if( ( CC1101ReadReg( CC1101_PKTCTRL1 ) & 0x03 ) != 0 )
            {
                x = CC1101ReadReg(CC1101_RXFIFO);
            }
            if( pktLen == 0 )           { return 0; }
            else                        { pktLen --; }
            CC1101ReadMultiReg(CC1101_RXFIFO, rxBuffer, pktLen); // Pull data
            CC1101ReadMultiReg(CC1101_RXFIFO, status, 2);   // Read  status bytes

            CC1101ClrRXBuff( );

            if( status[1] & CRC_OK ) {   return pktLen; }
            else                     {   return 0; }
        }
        else   {  return 0; }                               // Error
    }

    void CC1101ClrRXBuff( void )
    {
        CC1101SetIdle();//MUST BE IDLE MODE
        CC1101WriteCmd( CC1101_SFRX );
    }

  • 看代码似乎没有对异常情况做处理啊

    参考如下代码实现:

    // infinite loop
      while(1)
      {
        // wait for packet received interrupt
        if(packetSemaphore == ISR_ACTION_REQUIRED)
        {
          cc11xLSpiReadReg(CC110L_RXBYTES,&rxBytesVerify,1);
          
          do
          {
            rxBytes = rxBytesVerify;
            cc11xLSpiReadReg(CC110L_RXBYTES,&rxBytesVerify,1);
          }
          while(rxBytes != rxBytesVerify);
          
          
          // Check that we have bytes in FIFO
          if(rxBytes != 0) {
            
            // Read MARCSTATE to check for RX FIFO error
            cc11xLSpiReadReg(CC110L_MARCSTATE, &marcState, 1);
            
            // Mask out MARCSTATE bits and check if we have a RX FIFO ERROR (0x11)
            if((marcState & 0x1F) == RXFIFO_OVERFLOW) {
              
              // Flush RX FIFO
              trxSpiCmdStrobe(CC110L_SFRX);
            } else {
              
              cc11xLSpiReadRxFifo(rxBuffer,(rxBytes));
              
              // check CRC ok (CRC_OK: bit7 in second status byte)
              if(rxBuffer[rxBytes-1] & 0x80)
              {
                // toggle led
                halLedToggle(LED1);
                // update packet counter
                packetCounter++;
              }
            }
          }
          // reset packet semaphore
          packetSemaphore = ISR_IDLE;
          
          // set radio back in RX
          trxSpiCmdStrobe(CC110L_SRX);
          
        }
      }
  • 另外如果要RX接收端的话,可以用TI的Demo板或者可以连接smartrf studio的第三方板子做都可以。

    TI的demo板可以从官方的网站上购买,有433 868不同频段的供选择,例如433的link如下:

    http://www.ti.com/tool/cc1101dk433

  • @WBJ 感谢~ 调试时发现了另外一个小问题,向您请教下。清理信道评估代码 if( (CC1101ReadStatus(CC1101_PKTSTATUS)&0x10) == 0 ),在仿真调试时上述条件似乎一直都没有成立,CCA_MODE设置为If RSSI below threshold,AGC为默认设置,由于是多组异常测试,理论上仿真调试时会有信道被占用情况。清理信道评估代码编写流程有什么注意事项吗?