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.

CCA problems on CC1101?

Other Parts Discussed in Thread: CC1101

I've been using the CCA feature on the CC1101 for months without any visible problem. In all cases, this feature was enabled in low-power motes transmitting short frames (< 15 bytes) every few seconds (or minutes). Now I'm working on a more ambitious project, an "always-in-RX-mode" device that listens for commands and immediately replies with a packet longer than 24 bytes.

In order to test this device, I'm sending around 3 commands per second to it. Well, the problem is that, after some packets received, the CC1101 stops sending responses and receiving commands.. After that, strobing the CC1101 with SRES sometime works but the IC shows the same problem after a few packets received. Then, my uC still works but the CC1101 remains blocked at MARCSTATE=RX (0x0D). Unpowering/repowering the CC1101 is the only action that seems to better unblock the situation although, as I said before, the problem ends by reappearing again.

The weird thing is that this only happens with CCA enabled. Otherwise, my device works flawlessly This device is being tested with the rest of motes unpowered so that the CCA mechanism should not find any obstacle.

And this is the critical piece of code, where transmissions are undertaken:

bool CC1101::sendData(CCPACKET packet)
{
  byte marcState;

  // Enter RX state
  setRxState();

  // Check that the RX state has been entered
  while ((readStatusReg(CC1101_MARCSTATE) & 0x1F) != 0x0D)
    delay(1);
  delayMicroseconds(500);

  // Set data length at the first position of the TX FIFO
  writeReg(CC1101_TXFIFO,  packet.length);
  // Write data into the TX FIFO
  writeBurstReg(CC1101_TXFIFO, packet.data, packet.length);
  // CCA enabled: will enter TX state only if the channel is clear
  cmdStrobe(CC1101_STX);

  // Check that TX state is being entered (state = RXTX_SETTLING)
  marcState = readStatusReg(CC1101_MARCSTATE) & 0x1F;
  if((marcState != 0x13) && (marcState != 0x14) && (marcState != 0x15))
  {
    setRxState();                 // Back to RX state
    return false;
  }

  // Wait for the sync word to be transmitted
  wait_GDO0_high();

  // Wait until the end of the packet transmission
  wait_GDO0_low();
 
  // Enter back into RX state
  setRxState();

  // Check that the TX FIFO is empty
  if((readStatusReg(CC1101_TXBYTES) & 0x7F) == 0)
    return true;

  return false;
}

Thanks in advance for your help!

Daniel.

  • It could be that your RSSI threshold is set to low, so channel noise will stop you from getting a clear channel.Have you checked that you get a CCA signal(0x09)  when you are in RX? You can also use the Carrier Sense signal (0x0E) to check this.

    Reading the MARCSTATE right after you have issued a STX strobe may give you a false reading of the MARCSTATE( See the CC1101 errata), so when you run the code below you might fail the if statement and then you set the radio back into RX and your function will return a false statement.

      // CCA enabled: will enter TX state only if the channel is clear
      cmdStrobe(CC1101_STX);

      // Check that TX state is being entered (state = RXTX_SETTLING)
      marcState = readStatusReg(CC1101_MARCSTATE) & 0x1F;
      if((marcState != 0x13) && (marcState != 0x14) && (marcState != 0x15))
      {
        setRxState();                 // Back to RX state
        return false;
      }

     I would rater poll for the end of transmission by waiting for MARCSTATE = IDLE (or RX depending on TXOFF_MODE).

     

  • Thanks a lot Martin for your advices. I've been able to do some progresses thanks to them.

    Indeed, the problem was in the RSSI threshold. Setting CCA_MODE to 2 (Unless currently receiving a packet) instead of 3 (If RSSI below threshold unless currently receiving a packet) works without problems. CARRIER_SENSE_ABS_THR is set to 0000. Martin, which is the usual value for this parameter if I want to full-enable CCA?

    Besides, I've found something weird when I try to poll MARCSTATE as you suggest:

    Since TXOFF_MODE is set to 0, I'm now waiting for MARCSTATE = IDLE (0x01) but I'm never getting that value. Instead, I'm reading TX (0x13) when transmission is completed and RX (0x0D) when the problem related to this post happens. Nothing else, except that before reaching the TX state, MARCSTATE takes the value RXTX_SWITCH (0x15) for a moment.

    So by the moment I'm still keeping my old check on marcstate.

    Thanks again!

  • Hi

    When CARRIER_SENSE_ABS_THR = 0 the carrier sense threshold is set to be the same as MGN_TARGET.  See section 17.4 of the data sheet for adjusting carrier sense. The carrier sense threshold depends on the environment you are operating in. If there is high noise floor in your channel you might want to increase the CARRIER _SENSE_ABS__THR above the MAGN_TARGET.

    It is right that the MARCSTATE will be RX(0x0D) when you do not have a CCA. The radio will continue to be in RX until the signal on your channel drops under the carrier sense threshold. Then the radio will continue to TX. I do not understand why it stays in TX after the packet have been sent if TXOFF_MODE = 0x00. Have you checked that you have data in your TXFIFO before you strobe TX(read TXBYTES register)? If the FIFO is empty when you strobe TX the radio will start sending preamble until something is written to the TXFIFO. With an empty FIFO, the radio will continuously send preamble and never go back to IDLE unless you send a IDLE strobe.

  • I've checked that STX is never strobed with TXFIFO empty. On the other hand, I now know that the CC1101 IC stalled due to a TX FIFO overflow. For some reason, the CCA engine often fails due to a wrong RSSI condition so I'm now flushing the TX FIFO whenever the transmission fails and... problem solved... apart from the fact that the RSSI condition does not met many times. I think I'm going to remove the RSSI condition from the CCA settings (MCSM1.CCA_MODE =  2 instead of 3) .

    On the other hand I neither know why MARCSTATE does not change to IDLE after sending a packet... I have to do it manually by issuing a SIDLE strobe.

    Thank you very much Martin for your great support.

    Daniel.

  • Hi,

    I read the thread and thought of something. If you do not have a CCA, the TX will not occur (according to user manual you have to strobe stx again in order to attempt to send the packet once more). Your if statement will be true, and you return false. But the data you loaded into the TX FIFO will still be there. So next time you call your function, the same thing may happen again - and the FIFO will be loaded with even more bytes (eventually tx fifo overflow occurs). If you have a CCA though (the second time), the previous packet will now be sent. But the packet you actually wanted to send is still in the TX FIFO.

    Part of your code, with possible modification:

      // Set data length at the first position of the TX FIFO
      writeReg(CC1101_TXFIFO,  packet.length);
      // Write data into the TX FIFO
      writeBurstReg(CC1101_TXFIFO, packet.data, packet.length);
      // CCA enabled: will enter TX state only if the channel is clear
      cmdStrobe(CC1101_STX);

      // Check that TX state is being entered (state = RXTX_SETTLING)
      marcState = readStatusReg(CC1101_MARCSTATE) & 0x1F;
      if((marcState != 0x13) && (marcState != 0x14) && (marcState != 0x15))
      {

        => FLUSH YOUR TX FIFO HERE, THE DATA YOU LOADED SHOULD BE REMOVED
        setRxState();                 // Back to RX state
        return false;
      }



    Best Regards

    Hans Christian

  • hello Daniel,

    my firmware also want to use cca feature. The code is almost same to your past above.

    but  my program will stop at  below line and never quit.

     // Wait for the sync word to be transmitted
      wait_GDO0_high();


    Did you have the issue?


    Wenbing


  • This only happened to me when the MCU gets interrupted whilst waiting for GDO0 to go high. Try to disable interrupts.

  • 1.    I tried to disable interrupts but still block. I am wonder if ISR does nothing to GDO0 when interrupt enabled, non-interrupt GDO0 operations should not be impacted.

    2.  By the way, CS threshold question for you.

     I want to investigate CS threshold. I use two board. one board acts as transmitter, the other as receiver. Transmitter board always send packet and receiver board always receive packet.  In receiver board, read RSSI register to calculate CS threshold by below formula:

    if RSSI_dec >= 128 , then RSSI_dbm = (RSSI_dec - 256/2   - RSSI_Offset.  if RSSI_dec < 128 , then RSSI_dbm = (RSSI_dec/2   - RSSI_Offset.

    RSSI_dbm is calculated when transmitter board send packet or does not send packet. So I got RSSI_dbm value under clean channel or dirty channel. example: 

    clean channel:    RSSI_dbm = -104dbm

    dirty channel:      RSSI_dbm = -95dbm

    based on calculated RSSI_dbm to configure CS threshold register: MAX_DVGA_GAIN, MAX_LNA_GAIN, MAGN_TARGET, CARRIER_SENSE_REL_THR, CARRIER_SENCE_ABS_THR. 

    I choice RSSI_dbm = -97.5dbm as threshold.  So MAX_DVGA_GAIN=0, MAX_LNA_GAIN=0,MAGN_TARGET=7,CARRIER_SENSE_REL_THR=0,CARRIER_SENCE_ABS_THR=0.

    Am I right for CS threshold configuration?

    many thanks, wenbing

  • Hello Daniel,

    I used scope to mearsure GDO0 waveform and found GDO0 behavior is right. Actually my code add GDO0 time out processing as below:

    ....

    // Check MARCSTATE status 

    printf(" Debug message");

    while(!GDO0)

    {

        if(timeout) break;

    ....

    }

    Because debug message output takes some delay , GDO0 pulse missed  and GDO0 timer out happens.

    Send packet processing is terminated by timer out.

    The issue is fixed by the debug message output is removed.

    Thanks, Wenbing