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.

CC1125: Receiver drops packets if gap between packets is too small

Part Number: CC1125
Other Parts Discussed in Thread: CC1101, , CC1120

I have a fleet of older devices using the CC1101, transmitting packets at 869MHz, 56kbps, 2FSK. It sends packets which are 61 bytes long and with virtually no gap between packets. These can be received fine on our old CC1101-based receiver but not on the redesigned receiver which uses the CC1125.

The new receiver drops every other packet, and setting a GPIO port to output PKT_SYNC_RXTX shows that the chip is not detecting alternate syncs. If I put a 2ms gap between packet transmissions then it all starts working again. BTW I have checked that the received packet is being read out well before the next sync start is due.

Any clues where to start looking?

  • The CC1125 needs fewer preamble bits than the CC1101 to be able to detect sync word, so if it works with CC1101 it should work with CC1125 as well.
    I do not know anything about your settings on either the CC1101 or CC1125, but I assume that you are using RXOFF_MODE = RX on the CC1101 (set in the MCSM1 register) and that you are doing the same on the CC1125 (Set in RFEND_CFG1)? If this is not the case, you should try that.

    If you are not able to get it up and running, I would need your register settings on both devices, so that I can do some testing here myself.

    BR

    Siri
  • Thanks for getting back. Yes I am using RXOFF_MODE = RX.

    These are the CC1101 transmitter settings:
    __flash const ui8 Init_Config_Registers[CONFIG_REG_ARRAY_SIZE] =
    {
    (ui8)0x47u, /* IOCFG2 - Assert GDO2 when packet Rx */
    (ui8)0x2Eu, /* IOCFG1 */
    (ui8)0x42u, /* IOCFG0 - Assert GD00 when TXFIFO is >= Threshold */
    (ui8)0x0Fu, /* FIFOTHR - Rx Threshold = 64, Tx Threshold = 1 */
    (ui8)0x91u, /* SYNC1 */
    (ui8)0xD3u, /* SYNC0 */
    (ui8)0x3Fu, /* PKTLEN - For variable packet length. max length = 63 */
    (ui8)0x88u, /* PKTCTRL1 */
    (ui8)0x05u, /* PKTCTRL0 - Variable packet length */
    (ui8)0x00u, /* ADDR */
    (ui8)0x00u, /* CHANNR */
    (ui8)0x08u, /* FSCTRL1 */
    (ui8)0x00u, /* FSCTRL0 */
    (ui8)0x21u, /* FREQ2 - 869.850 MHz */
    (ui8)0x74u, /* FREQ1 - 869.850 MHz */
    (ui8)0xADu, /* FREQ0 - 869.850 MHz */
    (ui8)0x9Bu, /* MDMCFG4 */
    (ui8)0x22u, /* MDMCFG3 */
    (ui8)0x82u, /* MDMCFG2 */
    (ui8)0x32u, /* MDMCFG1 */
    (ui8)0xF8u, /* MDMCFG0 */
    (ui8)0x40u, /* DEVIATN */
    (ui8)0x07u, /* MCSM2 - Rx timeout disabled */
    (ui8)0x0Cu, /* MCSM1 - Stay in Rx after valid packet Rx */
    (ui8)0x38u, /* MCSM0 */
    (ui8)0x1Du, /* FOCCFG */
    (ui8)0x1Cu, /* BSCFG */
    (ui8)0x07u, /* AGCCTRL2 */
    (ui8)0x48u, /* AGCCTRL1 */
    (ui8)0xB2u, /* AGCCTRL0 */
    (ui8)0x86u, /* WOREVT1 */
    (ui8)0x6Bu, /* WOREVT0 */
    (ui8)0xF8u, /* WORCTRL */
    (ui8)0x56u, /* FREND1 */
    (ui8)0x10u /* FREND0 */
    };

    And these are the CC1125 receiver settings:
    Chip is reset to defaults before sending the config.
    const PROGMEM registerSetting_t carrierSmartlog[] = {
    {CC112X_IOCFG3, GPIOx_CFG_HW0}, //GPIO3 IO Pin Configuration
    {CC112X_IOCFG2, GPIOx_CFG_HW0}, //GPIO2 IO Pin Configuration
    {CC112X_IOCFG1, GPIOx_CFG_HIGHZ}, //GPIO1 IO Pin Configuration
    {CC112X_IOCFG0, GPIOx_CFG_HIGHZ}, //GPIO0 IO Pin Configuration
    {CC112X_DEVIATION_M, 0xA0}, //Frequency Deviation Configuration
    {CC112X_MODCFG_DEV_E, 0x05}, //Modulation Format and Frequency Deviation Configur..
    {CC112X_DCFILT_CFG, 0x15}, //Digital DC Removal Configuration
    {CC112X_FREQ_IF_CFG, 0x3A}, //RX Mixer Frequency Configuration
    {CC112X_IQIC, 0x00}, //Digital Image Channel Compensation Configuration
    {CC112X_CHAN_BW, 0x41}, //Channel Filter Configuration
    {CC112X_MDMCFG0, 0x05}, //General Modem Parameter Configuration Reg. 0
    {CC112X_SYMBOL_RATE2, 0x9D}, //Symbol Rate Configuration Exponent and Mantissa [1..
    {CC112X_SYMBOL_RATE1, 0x74}, //Symbol Rate Configuration Mantissa [15:8]
    {CC112X_SYMBOL_RATE0, 0x0C}, //Symbol Rate Configuration Mantissa [7:0]
    {CC112X_AGC_REF, 0x3C}, //AGC Reference Level Configuration
    {CC112X_AGC_CS_THR, 0xEF}, //Carrier Sense Threshold Configuration
    {CC112X_AGC_CFG1, 0xA9}, //Automatic Gain Control Configuration Reg. 1
    {CC112X_AGC_CFG0, 0xC0}, //Automatic Gain Control Configuration Reg. 0
    {CC112X_SETTLING_CFG, 0x03}, //Frequency Synthesizer Calibration and Settling Con..
    {CC112X_FS_CFG, 0x12}, //Frequency Synthesizer Configuration
    {CC112X_PA_CFG2, 0x3F}, //Power Amplifier Configuration Reg. 2
    {CC112X_PA_CFG0, 0x7B}, //Power Amplifier Configuration Reg. 0
    {CC112X_IF_MIX_CFG, 0x00}, //IF Mix Configuration
    {CC112X_TOC_CFG, 0x0A}, //Timing Offset Correction Configuration
    {CC112X_FS_DIG1, 0x00}, //Frequency Synthesizer Digital Reg. 1
    {CC112X_FS_DIG0, 0x5F}, //Frequency Synthesizer Digital Reg. 0
    {CC112X_FS_CAL0, 0x0E}, //Frequency Synthesizer Calibration Reg. 0
    {CC112X_FS_DIVTWO, 0x03}, //Frequency Synthesizer Divide by 2
    {CC112X_FS_DSM0, 0x33}, //FS Digital Synthesizer Module Configuration Reg. 0
    {CC112X_FS_DVC0, 0x17}, //Frequency Synthesizer Divider Chain Configuration ..
    {CC112X_FS_PFD, 0x50}, //Frequency Synthesizer Phase Frequency Detector Con..
    {CC112X_FS_PRE, 0x6E}, //Frequency Synthesizer Prescaler Configuration
    {CC112X_FS_REG_DIV_CML, 0x14}, //Frequency Synthesizer Divider Regulator Configurat..
    {CC112X_FS_SPARE, 0xAC}, //Frequency Synthesizer Spare
    {CC112X_XOSC5, 0x0E}, //Crystal Oscillator Configuration Reg. 5
    {CC112X_XOSC1, 0x07}, //Crystal Oscillator Configuration Reg. 1
    {CC112X_RFEND_CFG1, 0x3f}, //RF End Configuration Reg. 1
    {CC112X_EOL, 0x00} //End of list
    };
    const PROGMEM registerSetting_t carrier_869[] = {
    {CC112X_FS_CFG, 0x12}, //Frequency Synthesizer Configuration
    {CC112X_FREQ2, 0x6C}, //Frequency Configuration [23:16]
    {CC112X_FREQ1, 0xBB}, //Frequency Configuration [15:8]
    {CC112X_FREQ0, 0x33}, //Frequency Configuration [7:0]
    {CC112X_EOL, 0x00} //End of list
    };
    const PROGMEM registerSetting_t basebandSmartlog[] = {
    {CC112X_SYNC1, 0x91}, //Sync Word Configuration [7:0]
    {CC112X_SYNC0, 0xD3}, //Sync Word Configuration [15:8]
    {CC112X_SYNC_CFG1, 0x0B}, //Sync Word Detection Configuration Reg. 1
    {CC112X_SYNC_CFG0, 0x0B}, //Sync Word Length Configuration Reg. 0
    {CC112X_PREAMBLE_CFG1, 0x18}, //Preamble Length Configuration Reg. 1
    {CC112X_PREAMBLE_CFG0, 0x2A}, //Preamble Length Configuration Reg. 0
    {CC112X_PKT_CFG2, 0x00}, //Packet Configuration Reg. 2
    {CC112X_PKT_CFG1, 0x05}, //Packet Configuration Reg. 1
    {CC112X_PKT_CFG0, 0x20}, //Packet Configuration Reg. 0
    {CC112X_PKT_LEN, 0x7F}, //Packet Length Configuration
    {CC112X_EOL, 0x00} //End of list
    };

    GPIO0 is set to assert on CRC_OK (config 7) but I have also tried PKT_SYNC_RXTX (config 6) to be sure that it's not just CRC failure. For the missing packets there is no GPIO0 assertion in either configuration.

    Also of interest, the transmitter loads a packet, then waits for the state machine to drop back to IDLE state before loading up the next packet for transmission. Packets are 61 bytes long but transmission is started after loading the first 8 bytes into the FIFO. I have also tried without this early TX start and it doesn't fix the problem.

    I now have a logic analyser hooked up to the SPI bus of both devices, so I can see what's going in and out of both chips. Occasionally 2 consecutive packets make it through but I can't see any pattern to why that should happen.
  • Since you have a logic analyzer, you can try to output PA_PD on the CC1101 (asserted when the radio is in TX) and LNA_PD on the CC1125 (asserted when in RX). Then you can verify that the receiver is actually in RX mode while the transmitter is transmitting.

    I will also do some testing here. Can you please measure the packet interval in Tx in your case (measure from 1 sync sent to the next) so that I can test with the same packet interval.

    Siri
  • At the moment I can only time from STX commands. The interval between successive transmissions is 10.59ms.
    Another data point, I was wrong about the early TX start. It does make a difference if I don't fire the STX strobe until the FIFO is full and the packet loss goes down to about 1 in 3, but it's irregular.
    I will try monitoring the PA_PD and LNA_PD as you suggest.
  • CC1101 IOCFG2 = 0x1B (PA_PD)
    CC1125 IOCFG2 = 0x18 (LNA_PD)

    I can see the CC1101 PA_PD line toggling as packets transmit.
    The CC1125 LNA_PD toggles while requesting a download, then remains low throughout the entire receive process.
  • Not sure what the problem could be.

    I took you setting and made a small example running on the TrxEB for both CC1101 and C1120 (Did not have a CC1125). Only did some changes to the GPIO settings.

    My packet interval is below 10.5 ms and I am able to receive all packets OK:

    CC1101:

    void main(void) {
    
        // Initialize MCU and peripherals
        initMCU();
    
        // Write radio registers
        registerConfig();
    
        // Initialize packet buffer of size PKTLEN + 1
        uint8 txBuffer[PKTLEN+1] = {0};
    
        // Connect ISR function to GPIO2
        ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &radioTxISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_FALLING_EDGE);
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    
        // Enable interrupt
        ioPinIntEnable(IO_PIN_PORT_1, GPIO2);
    
        createPacket(txBuffer);
    
        // Infinite loop
        while(TRUE) {
        
            // Wait for button push
            if(bspKeyPushed(BSP_KEY_ALL)) {
          
                // Continiously sent packets until button is pressed
                do {
            
                    // Write packet to TX FIFO
                    cc1101SpiWriteTxFifo(txBuffer,sizeof(txBuffer));
    
                    // Strobe TX to send packet
                    trxSpiCmdStrobe(CC1101_STX);
    
                    // Wait for interrupt that packet has been sent.
                    // (Assumes the GPIO connected to the radioRxTxISR function is
                    // set to GPIOx_CFG = 0x06)
                    while(packetSemaphore != ISR_ACTION_REQUIRED);
    
                    // Clear semaphore flag
                    packetSemaphore = ISR_IDLE;
    
                } while (!bspKeyPushed(BSP_KEY_ALL));
            }
        }
    }
    
    static void radioTxISR(void) {
    
        // Set packet semaphore
        packetSemaphore = ISR_ACTION_REQUIRED;
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    }

    CC1120:

    void main(void) {
    
        // Initialize MCU and peripherals
        initMCU();
    
        // Write radio registers
        registerConfig();
    
        uint8 rxBuffer[128] = {0};
        uint8 rxBytes;
        uint8 marcState;
    
        // Connect ISR function to GPIO2
        ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &radioRxISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_FALLING_EDGE);
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    
        // Enable interrupt
        ioPinIntEnable(IO_PIN_PORT_1, GPIO2);
    
        // Calibrate radio according to errata
        manualCalibration();
    
        // Set radio in RX
        trxSpiCmdStrobe(CC112X_SRX);
    
        // Infinite loop
        while(TRUE) {
    
            // Wait for packet received interrupt
            if(packetSemaphore == ISR_ACTION_REQUIRED) {
    
                // Read number of bytes in RX FIFO
                cc112xSpiReadReg(CC112X_NUM_RXBYTES, &rxBytes, 1);
    
                // Check that we have bytes in FIFO
                if(rxBytes != 0) {
    
                    // Read MARCSTATE to check for RX FIFO error
                    cc112xSpiReadReg(CC112X_MARCSTATE, &marcState, 1);
    
                    // Mask out MARCSTATE bits and check if we have a RX FIFO error
                    if((marcState & 0x1F) == RX_FIFO_ERROR) {
    
                        // Flush RX FIFO
                        trxSpiCmdStrobe(CC112X_SFRX);
                    } else {
    
                        // Read n bytes from RX FIFO
                        cc112xSpiReadRxFifo(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++;
                        }
                    }
                }
    
                // Reset packet semaphore
                packetSemaphore = ISR_IDLE;
            }
        }
    }
    
    static void radioRxISR(void) {
    
        // Set packet semaphore
        packetSemaphore = ISR_ACTION_REQUIRED;
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    }

    BR

    siri

  • I'm running in circles here. I tried with a different board and it worked straight away. Then I tried again and it started dropping packets. Power cycled the new board and it worked again but a second test started dropping packets. Now that it's been running for a while (and I guess the temperature is stable) it works OK for several minutes.

    The original board I was testing with never works properly, even after a fresh power on.

    This makes it look like a calibration problem, but I am using the SCAL strobe at power-on and I can do it on demand too. This does not fix the original board.

    Both boards stop receiving after a couple of minutes. In an effort to debug this I read the MARC STATE register every 10s and print it out on a serial port. Mostly the state is 0x61 as expected. Occasionally the output stops and it changes to 0x11 but, now that I am reading the register it recovers by itself and goes back to 0x61.

    When I read data back from the chip I am using the status byte returned on every SPI write, but I see your code is reading the MARC STATE register instead. Is there some magical side effect of reading that register? It certainly seems to fix the problem of reverting to IDLE when it should still be in RX.
  • first of all, If you have a device with PARTVERSION equal to 0x21, you need to perform the manual calibration as described in the errata, and not just doing an SCAL strobe.
    You can use the status byte instead of MARCSTATE to check for overflow.
    I also see that you are using CRC_AUTOFLUSH. Please note that when this feature is used, you need to make sure that there are bytes in the FIFO before trying to read it (if you are using PKT_SYNC_RXTX and not CRC_OK), as you should never try to read an empty FIFO.

    Since it sometimes works for a while, and then stop working you should take a closer look at how you are handling packets with CRC not OK etc. to make sure that faulty packets do not mess up anything. You should also check your HW since you have a board that does not work at all.

    Your comment about having MARCSTATE showing 0x61 does not make sense. If this is the case, MARC_2PIN_STATE shows RX state and MARC_STATE shows IDLE

    Siri
  • Nope, PARTVERSION is 0x23.

    I am using CRC_OK, but I will review the method being used.

    It is certainly possible there is a hardware problem, but both boards show the fault, one board shows it all the time and the other intermittently.

    My bad, I munged two values. During reception MARCSTATE mostly shows 0x6d and sometimes shows 0x11. The reason for dropping to IDLE turned out to be due to FIFO overflow, although I'm not sure what caused that. The reason reading MARCSTATE restarted RX mode was that my original code was using the last reported status, and in receive mode I'm not reading the status (there's a note in the user guide that repeated polling of the chip reduces receive sensitivity, which is why I'm looking at the GPIO line instead.

    Is it OK to send a sequence of strobes one after the other or do I have to wait for the radio to enter the requested state before sending the next strobe? e.g.
    SIDLE
    SFRX
    SRX
  • OK, I may have found the cause of the problem. Because this is an environment with a lot of loggers twittering away, I had the transmitter and receiver in a Tescom RF box to isolate them from the ambient transmissions. The logger is transmitting at maximum power, albeit without its antenna and the receiver (also without antenna) doesn't like being blasted with high power. If I move the transmitter outside the box and open it up just enough to let a small amount of stray RF in then all packets are received.

    So it seems that the receiver picks up a packet and then has to have a lie down for a few ms, misses the next one and then recovers to get the third, etc. Is there a way to make the receiver more tolerant of high power transmissions coming at it? This is unfortunately a realistic scenario as in the field both devices will have their antennae fitted and while usually the transmitter is some distance away, sometimes the technician will try to talk to it when it's on the desk next to him/her.
  • Not sure if I understand the setup.
    - You write that you have A RX and TX board, both without an antenna. In this scenario (when you lose every second packet) , what is the RSSI of the received packets?
    - I have never managed to saturate the receiver on CC112x (I have used an input signal way above the maximum limit and the chip still receives without an issue)
  • Just to clarify, I have the two boards, both with all their output matching circuitry but no antenna fitted to the RF output connector. These boards are sitting right next to each other in the Tescom box. In that situation I get major packet loss. When I put the transmitter outside the box and wedge the box open just a crack (I know, not very scientific) then I see a much reduced RSSI and there is no packet loss.

    I'm away from the bench until Monday and don't have those RSSI values to hand, but will have a look when I get back. When a packet is missed, there is no PKT_SYNC_RXTX output signal on GPIO so I assume that the sync detection is failing every second packet. Can I get an RSSI value in that case, with no sync detected? Or are you just asking for RSSI on the packets that do get through? Is there any other register I can monitor, or GPIO output I can enable to help debug this?

    I tried setting the AGC_CFG2.START_PREVIOUS_GAIN_EN bit as an experiment. That improved the packet receive rate a lot during high packets rate transmissions so only maybe 1 in 10 was dropped. So I think this is related to AGC somehow.
  • I'm mainly interested in the RSSI of the received packets, in both cases (when both are inside the box and when you move one of the devices outside the box). If you just have a open SMA connector on both boards the RSSI level should be fairly low and the AGC always start with max gain. You can also read out the resulting frontend gain with AGC_GAIN3.
  • This is the RSSI value stuffed into the FIFO after the packet data, and the AGC gain read out just before reading data from the fifo:
    Both Tx and Rx inside the Tescom box, CC1125 RSSI value = 0x37, AGC_GAIN3 = 0x27

    Rx (CC1125) inside the Tescom box, Tx outside, CC1125 RSSI value = 0x0f, AGC_GAIN3 = 0x27

    Because the receiver goes back to Rx mode after a packet is received that may mean that AGC_GAIN3 has already been set to maximum before I read the register?
  • For the RSSI values, could you use append status to ensure that you get the RSSI of the received packet?

    Also, could you calculate the RSSI in dBm?

  • I have re-run, this time with manual change back to Rx mode so I can read the AGC_GAIN3 value. RSSI is (and was previously) obtained using append status.

    Both Tx and Rx inside Tescom box: RSSI = 0x39 AGC_GAIN3 = 0x03
    Tx outside, Rx inside the box: RSSI = 0x1B, AGC_GAIN3 = 0x27

    I don't have any way of calibrating the RSSI to actual dBm.
  • How to calculate the value in dBm is given in www.ti.com/.../swra413.pdf

    If I read the numbers correctly the RSSI is -45 dBm which is not very high. As long as you use an IF different from zero the AGC will settle on 4 bit preamble so I find your findings a bit strange.

    Do you know if your CC1120 settings are "good"? Have you been able to do do a PER vs level type of measurement?

    Just to check if settings have an impact, could you test with the 38.4 kbps settings?
  • That design note essentially tells you how to add an offset to the RSSI register value to get true RSSI. I know how to add, I don't have the means to determine what number should be added. As far as I can see the offset of 102 in that DN is just an example.

    I don't see any packet errors in terms of CRC failure. As I said before, when RSSI is high AND packet rate is high then a lot of packets (approx 50%) get dropped because the sync detection fails to find the start of a packet. If there are gaps between packets OR if the signal strength is lower then packet detection works just fine.
  • - The RSSI offset on CC112x is independent of datarate. You may have to change the offset if you use a different frontend.
    - LNA_PD/ PA_PD: Did you try to monitor these signals?
    - Have you tried Siri's code
    - I assume that you have tested your code on a custom board. I get the impression that this does not behave the same each time you run the code. Have you tried to run this code on a EM?
    - SmartRF Studio has some limitations in how fast it's able to read out data but have you tried to use this as a sniffer at the same time you have a TX and RX board up to see if you receive the same or different packets.
    - Do you see some difference in performance if you make the packets shorter or longer
    - Would you be able to do the tests conducted with a know attenuation between the boards which will enable you to know at exactly which RSSI levels you get an issue at.
  • Does the RSSI offset make any difference to the way the CC112x works or does it just affect the value reported as RSSI?

    Yes, I monitored LNA_PD/PA_PD as reported earlier. LNA remains active all the time as the CC1125 board is only receiving, so it's not turning on the LNA too late and missing the start. Essentially I am using this as a sniffer.

    I have not tried Siri's code directly but I have checked that my code is doing all the same things. Mine is checking for CRC_OK rather than RXTX_SYNC, but I did also try that test too.

    Yes, this is on a custom board. It does the same thing each time I run it. The things that make a difference are the gap between packets and the signal strength. If the gap is short AND the signal is strong then RXTX_SYNC never activates for the missed packets. I don't think we have an EM for this chip, I'll see if we can get one.

    I have not tried changing packet length, but I can try that and see if it makes a difference.

    I haven't tried a conducted test. I'll give that a go too.
  • Please could you try Siri's code? Since we tested that here without seeing any issues this is way to test with the same software.

    It's unfortunately a bit difficult to support this case since we are not able to reproduce the same here and what you report contradict what we have seen of CC112x behavior in the past.
  • Any progress?
  • Alas no. The investigation is costing us too much time so there's been an executive decision to leave it as is and tell users not to put the units too close together.

    It's something I'd like to follow up on later when time permits but for now I have to leave it.

    Thanks for all your help and advice.

  • Hi TER:
    I have 2 question after read the whole post:
    1.Does the RSSI offset make any difference to the way the CC112x works or does it just affect the value reported as RSSI?
    2. Cause I use the Synchronous Serial Mode without the cc1125 to detect sync/preamble,does the AGC help our application, since I just disable the AGC behavior(AGC_CFG1.AGC_SYNC_BEHAVIOUR = 000 (No AGC gain freeze, keep computing /updating RSSI)
    Looking forward to your reply.