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.

CC1121: CC1121 collosion detection is not working

Part Number: CC1121

Hi,

Have the following issue:

Our product is using 2 CC1121 radio's working on the same channel (frequency).

Our product is sending a beacon message every few mSec on Radio 2, while the other radio continue to RX.

In some scenario, a valid data is arriving and fetched into Radio1 FIFO. Radio2 is sending a beacon data (with higher signal strength) and the data is overwriting the valid data.

I would expected to get:

1. CRC error (in most cases indeed we are getting it)

2. Collision found signal, as the beacon sync word is inserted while a valid packet is received.

However, we are not getting the collision indication. (MDMCFG1 = 0x4E).

We don't have the option to get an interrupt on the collision (relevant gpio is not connected), but just read the flag from register DEM_STATUS when validate the received packet.

What is the exact scenario of collision?

what is the trigger for the flag in DEM_STATUS to reset (maybe I'm reading it too late)?

Currently a garbage data is enter into our system.

Thanks,

Dagan

  • Not sure I understand you statements:

    In some scenario, a valid data is arriving and fetched into Radio1 FIFO. Radio2 is sending a beacon data (with higher signal strength) and the data is overwriting the valid data.

     

    What do you define as valid data (is that CRC OK) and why do you say that valid data is overwritten?

     

    If you receive a valid sync word (from, let’s say TX1) the radio will start filling up the RX FIFO, with as many bytes as indicated by the length fields (variable packet length) or by the PKTLEN register (fixed packet length).

    If you have collision detect enabled, the radio will continue to look for sync, even if you have already started filling up the FIFO.

    If you are in the middle of receiving a packet, and another transmitter (TX2) sends a packet, two things can happen.

     

    1) The two packets interfere with each other. The data from TX2 will ruin the data you are receiving from TX1 and you will have CRC errors in your packet. Most likely the data in the beginning of the FIFO is OK (from TX1, but after the TX2 started to send, the data will only be garbage). You will NOT have a collision, since the data from TX1 is ruining the sync word from TX2, so that you do not detect it

     

    2) The data from TX2 is much stronger than the data from TX1. In this case, the data in the RX FIFO will first be the data from TX1, and after TX2 starts to send, the data in the RXFIFO will be the data from TX2 (including preamble and sync). The CRC will still fail, but COLLISION_FOUND would be asserted:


    The collision found does not give you any other info than telling you if a sync word has been found or not while you are in the middle of receiving a packet.

     

    If you want to be able to receive the data from TX2 in the scenario above (TX2 send a much stronger signal than TX1, you can try to use the RSSI_STEP_FOUND signal.

    This signal is asserted when there RSSI increases 3 or 6 db. The signal must be used as an interrupt to the MCU, so that you can read NUM_RXBYTES to figure out how many bytes are in the FIFO from the TX1 packet, and then send an SRX strobe to restart RX to be able to receive the new packet (TX2)

    I am not sure that a step of 3 or 6 dB is suffisioan to be able to receive the new packet without errors, so another approach is to use the CS signal, as explained in Section 6.10.1 (RSSI Based Detection) in the user guide

     

    BR

    Siri

     

  • Hi - thanks for your answer,

    A valid data is a data with CRC ok.

    My issue is strongly depended on the timing of the TX2 beacon data. let me explain every scenario:

    1. Normal scenario - Radio 1 is getting a good data with length of 0x2A, no TX2 data:

       2a 0a 65 02 00 00 92 03 ....  4e 4e 01 00 00

    2. CRC failure - Radio 1 is receiving a data, TX2 is sending it's beacon data in the midel resulting in CRC error - I will not pared the data

    3. The problematic scenario - Radio 1 is receiving a data, TX2 is sending it's beacon data that overwriting exactly the last 3 bytes of the good data:

       2a 0a 65 02 00 00 92 03 ....  4e 4e 02 BC FF


    In this scenario, a collision occurred. CRC is OK! (I guess the CRC is calculated only on the TX2 beacon data and therefore it's OK).

    I also read NUM_RXBYTES and it's 0x2A.

    However, I try to read the COLLISION_FOUND flag register, and it was with reset value (0)...

    I also try to use the RSSI_STEP_FOUND but the flag was never raised.

    So, why I'm failing to read the flag?

    What is causing this flag to get reset (assuming it's indeed set).

     

    Thanks,

    Dagan

  • Hi Dagan

    I have done a bit of testing and I have not been able to reproduce what you are reporting. I all cases where I get a collision, I get a CRC error and I can see the packets from TX2 in the FIFO together with the packet from TX1. The COLLISION_FOUND signal is asserted

    When the CRC is reported to be OK, the packet is indeed OK.

    To easier distinguish between the packets I send a long packet with 0x00, 0xFF, 0x00, 0xFF...... from TX1 and a short packet with 0x55, 0x55, 0x55, 0x55, 0x55 from TX2. TX2 sends with a much higher output power than TX1. On the receiver it looks like this:

    10:23:14.804 | 4d | 00 ff 00 ff 00 ........ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 | -87

    10:23:14.923 | 4d | 00 ff 00 ff 00 ........ff 00 ff 4a aa aa aa b2 61 6a 3b c0 aa aa aa aa aa bf e4 20 7f 00 ff 00 ff 00 | -87 CRC error

    10:23:15.038 | 4d | 00 ff 00 ff 00 ........ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 | -87

    10:23:15.076 | 05 | 55 55 55 55 55 | -59

    10:23:15.152 | 4d | 00 ff 00 ff 00 ........ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 | -87

    Can you please provide me with the register settings you are using and also provide me with the code you are using when reading out the RXFIFO and checking the CRC?

    Also, please provide me with the complete valid packet:

    2a 0a 65 02 00 00 92 03 .... 4e 4e 01 00 00

    The complete packet you receive when a collision occurred but CRC was OK:

    2a 0a 65 02 00 00 92 03 .... 4e 4e 02 BC FF

    And the complete Beacon packet.

    Remember that the radio is not restarting automatically just because a collision occurs so it is not possible that the CRC is calculated over the beacon packet from TX2 only.

    BR

    Siri

  • Hi Siri,

    (please see private message regarding the configuration)

    The code I'm using to Read out the FIFO:

    static SendDataStatus_t ValidateMsg(RadioSelect RadioNum)

    {

    uint8_t Offset = 0;
    PacketFailuresCountersSt *RadioPackFailPtr;
    uint8_t *RxBuff;

    //Assert the RadioNum parametre
    if (RadioNum != RADIO_1 && RadioNum != RADIO_2)
    {
      return SendData_Fail;
    }
    //Set pointers according to RadioNum
    if (RadioNum == RADIO_1)
    {
      RxBuff = RADIO1_RXBuffer;
      RadioPackFailPtr = &g_DiagContainer.RADIO1_PackFail;
    }
    else
    {
      RxBuff = RADIO2_RXBuffer;
      RadioPackFailPtr = &g_DiagContainer.RADIO2_PackFail;
    }
    RADIO_ByteCount[RadioNum] = 0;
    RADIO_BytesInRxBuff[RadioNum] = 0;

    //Reads the amount of bytes ready in the radio's RX FIFO
    for (int i = 0; i < 3; i++)
    {
      if (RADIO_Read(RadioNum, &RADIO_BytesInRxBuff[RadioNum], CC1121_NUM_RXBYTES, 1) != SPI_TRANSACTION_OK)
      {
        return SendData_Fail;
      }
      if (RADIO_BytesInRxBuff[RadioNum] > 0)
      {
        break;
      }
    }
    //Assert the amount of bytes ready in the RX FIFO
    if (RADIO_BytesInRxBuff[RadioNum] > 0 && RADIO_BytesInRxBuff[RadioNum] <= RX_BUFF_SIZE)
    {
      //Reads all ready bytes from the RX FIFO
      if (RADIO_Read(RadioNum, RxBuff, CC1121_BURST_RXFIFO, RADIO_BytesInRxBuff[RadioNum])!= SPI_TRANSACTION_OK)
      {
        return SendData_Fail;
      }
    }
    else //BytesInRxBuff assertion failed
    {
      if (RADIO_BytesInRxBuff[RadioNum] == 0)
      {
        return SendData_Abort;
      }
      return SendData_Fail;
    }

    //If it's a beacon
    if (RxBuff[0] == 2 && RxBuff[1] == 0xBC && RxBuff[2] == 0xFF)
    {
      return SendData_Abort;
    }

    uint8_t data_length = RxBuff[0] + 1; // length + packet length byte

    // RxBuff[0] is payload length
    // Payload length + 1 length byte + 2 status bytes = BytesInRxBuff
    RADIO_ByteCount[RadioNum] = (data_length + 2); // 2 status bytes (rssi and crc status)
    if (RADIO_ByteCount[RadioNum]-1 >= RX_BUFF_SIZE)
    {
      return SendData_Fail;
    }
    if (!(RxBuff[RADIO_ByteCount[RadioNum]-1] & 0x80)) // packet status byte 2: CRC data OK
    {
      return SendData_Fail;
    }
    if (RADIO_ByteCount[RadioNum] != RADIO_BytesInRxBuff[RadioNum])
    {
      RADIO_BytesInRxBuff[RadioNum] = 0;
      return SendData_Abort;
    }

    //Parse RX FIFO content - only first message in the buffer!!
    //Assert that at least Total length and protocol version can be read
    if (RADIO_BytesInRxBuff[RadioNum] < HEADER_IDENTIFIER_SIZE)
    {
      //Handle fault message
      RadioPackFailPtr->PacketTooSmall++;
      return SendData_Fail;
    }

    ...

     

    The interrupt handler: (one per Radio) I have CRC error handler if the GPIO signal raised.

    I also handle CRC error later in the code by reading the status byte bit[7] (see above code marked in yellow).

    void RADIO1_MCU_WAKEUP_IRQHandler(void)

    {

    // Sync word interrupt2 - GPIO2
    if (EXTI_GetFlagStatus(RADIO1_SPI_INT2_EXTI_LINE) == SET)
    {
      EXTI_ClearFlag(RADIO1_SPI_INT2_EXTI_LINE);
      EXTI_ClearITPendingBit(RADIO1_SPI_INT2_EXTI_LINE);
      LastSyncTimeR1 = u64Ticks;
    }


    // Crc failure interrupt1 - GPIO3
    else if (EXTI_GetFlagStatus(RADIO1_SPI_INT1_EXTI_LINE) == SET)
    {
      EXTI_ClearFlag(RADIO1_SPI_INT1_EXTI_LINE);
      EXTI_ClearITPendingBit(RADIO1_SPI_INT1_EXTI_LINE);
      LastSyncTimeR1 = 0;
    }


    // Marc state interrupt3 - GPIO0
    else if (EXTI_GetFlagStatus(RADIO1_SPI_INT3_EXTI_LINE) == SET)
    {
      LastSyncTimeR1 = 0;
      g_RXReadyCountR1++;

      //CRC_OK
      if(SendRadioEventFromISR(RADIO_1, g_RXReadyCountR1, RadioEvent_TagData))
      {
        // TBD
      }

      EXTI_ClearFlag(RADIO1_SPI_INT3_EXTI_LINE);
      EXTI_ClearITPendingBit(RADIO1_SPI_INT3_EXTI_LINE);
    }
    else
    {
      LastSyncTimeR1 = 0;
    }

    }

    I'm using variable length.

    The beacon message on radio2 (only two bytes + length byte): BC FF

    The full data message: 0a 65 02 00 00 92 03 a0 f7 09 02 a1 f4 09 49 23 01 00 a0 34 01 00 18 45 01 00 a1 f5 09 52 2b 01 00 a6 3c 01 00 4e 4e 01 00 00

    Thanks,

    Dagan

  • Hi Degan

    I am afraid it is not clear to me how your code works.

    You have an interrupt on the MCU_WAKEUP. This signal is only asserted when the radio enters IDLE mode, but you use RXOFF_MODE = RX, TXOFF_MODE = RX and TERM_ON_BAD_PACKET = 0, meaning that the radio will never go to IDLE state.

    Is the RADIO1_MCU_WAKEUP_IRQHandler the ISR for MCU_WAKEUP , or do you have other ISR? If yes, what do you do in the other ISRs?

    It is also not clear to me when in your application you call the ValidateMsg function

    My guess is that the combination of using offmodes != IDLE, having CRC autoflush enabled, and using the different interrupts, you might read the FIFO or NUM_RXBYTES at the wrong time.

    An indication of this is that you NUM_RXBYTES is 0x2A, but this should be 0x2C when you have received a valid packet, since you have status bytes appended.

    When you are in continuous RX and using autoflush, you should have an interrupt on CRC_OK. Only packet with CRC OK would be in your FIFO, and you should read the first byte to get the length (and not NUM_RXBYTES), as the length byte would give you info on how many bytes belongs to you packet. NUM_RXBYTES could include the next packet also, since the radio is always in RX.

    I am afraid it is hard for me to pinpoint what exactly can cause your problems, but I have tested the COLLISION_FOUND feature, and not found anything wrong with the implementation.

    I do not know how often you see this problem, but if it is easy to reproduce, could you test without the collision detect feature enabled? You could also try disabling the autoflush feature, or stop using off modes.

    Siri

  • Hi Siri,

    You are correct – the configuration seem to be wrong…

    Unfortunately, I'm debug a bug in a code that not written by me, so I wasn't aware of this condition in the datasheet "Please note that MCU_WAKEUP will only be asserted when the radio enters IDLE state".

    I will try to setup the interrupt on the PKT_CRC_OK and see if the problem reproduced or not.

    Thanks for your help – I will update you privately after testing it again.

    I will close the forum thread.

     

    Dagan