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.

CC1200: Reading received data to quickly after sometimes seem to cause change in transmit frequency

Part Number: CC1200
Other Parts Discussed in Thread: CC1120

We have a issue where we loose connection with some radios. Measuring the transmitted radio frequency, we noted that the transmit frequency suddenly shifted randomly, the shift is in the range 10-100 MHz!

- Reading back register settings after the frequecy shift, everything look like it was when it was initialized

- Sending a calibration strobe do not bring the frequency back

- Sending a reset strobe, and reinitialize the CC1200 works to bring the frequency back

- The issue seems to occur (more often) when we provoke package collisions

- We use an interrupt on the falling edge of PKT_SYNC_RXTX in receive mode to trigger a readout of the receive fifo

After a lot of trial and error testing, adding a millisecond delay from the falling edge of PKT_SYNC_RXTX until we start SPI to read the received data seems to make the operation stable. Any explanation to this behavior?

  • From the first part of your post it looks like this is a TX issue with the TX frequency shifting a number of MHz. 

    But your fix, the way I read it, is to change the timing in RX. How did that change the frequency in TX? 

  • I'm very confused about this too. I don't see understand how changing the receive handling can affect the frequency. As I said, there was a lot of trial and error to find this possible fix ...

    Can it be that the SPI access somehow interfere with the automatix rx->tx transition? Anyway, the change in frequency is a big mystery to me.

  • What is the flow? When is the device in RX and in TX and how is the transitions from RX to TX or the other way controlled? 

    Is it possible to reproduce what you are seeing with a minimum example program? 

  • The flow is similar to the cc120x_easy_link example. Normally the device is in rx mode, occasionally changing to tx to send data. Once the data is sent, the radio returns to rx mode.

    We recently changed to a faster microcontroller in the system. As a result, the time from PKT_SYNC_RXTX falling until SPI chip select was reduced from about 90 us to 20 us.

  • Is what you are seeing only an issue on new board with the fast MCU? I believe we have seen some issues with fast MCUs but that is typically dependent on how the program is written since it's more  important with fast MCUs to check that the radio is n the wanted state before issuing the next strobe. In this case it could sound like the VCO calibration is not done before you try to do next command. 

  • That makes sense! With reference to the receive routine in the cc120x_easy_link_rx.c routine, I tried to read the marcstate prior to the SRX-strobe. I notice that it sometimes is ENDCAL. I assume I should wait for it to be IDLE or RX (using RXOFF_MODE=RX)?

    // Wait for packet received interrupt
    if(packetSemaphore == ISR_ACTION_REQUIRED){

    // Read number of bytes in rx fifo
    cc120xSpiReadReg(CC120X_NUM_RXBYTES, &rxBytes, 1);

    // Check that we have bytes in fifo
    if(rxBytes != 0){

    // Read marcstate to check for RX FIFO error
    cc120xSpiReadReg(CC120X_MARCSTATE, &marcStatus, 1);

    // Mask out marcstate bits and check if we have a RX FIFO error
    if((marcStatus & 0x1F) == RX_FIFO_ERROR){

    // Flush RX Fifo
    trxSpiCmdStrobe(CC120X_SFRX);
    }
    else{

    // Read n bytes from rx fifo
    cc120xSpiReadRxFifo(rxBuffer, rxBytes);

    // Check CRC ok (CRC_OK: bit7 in second status byte)
    // This assumes status bytes are appended in RX_FIFO
    // (PKT_CFG1.APPEND_STATUS = 1.)
    // If CRC is disabled the CRC_OK field will read 1
    if(rxBuffer[rxBytes-1] & 0x80){

    // Update packet counter
    packetCounter++;
    }
    }
    }

    // Update LCD
    updateLcd(); // not used in my application, will not give any delay

    // Reset packet semaphore
    packetSemaphore = ISR_IDLE;

    // *****************************
    // Read/wait for marcstate here!
    // *****************************

    // Set radio back in RX
    trxSpiCmdStrobe(CC120X_SRX);

    }

  • You can add something like this into your code:

    /* Wait for calibration to be done (radio back in IDLE state) */
    do {
    cc112xSpiReadReg(CC112X_MARCSTATE, &marcState, 1);
    } while (marcState != 0x41);

    (from a CC1120 example)

    basically ensure that the chip is in the wanted state before proceeding to the next line.