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: WOR Mode

Part Number: CC1101

Hello Team,

I'm posting on my customer's behalf, please see the customer inquiry below:

I am using the smart Rf studio software to configure my devices.
I am able to configure the CC1101 in WoR mode (periodically switching between Rx and sleep state) with an average consumption of 200 µA (measured with the CX3324A from keysight). The period (Event0) is about 1s and the Rx timeout is about 15 ms. I set an interrupt to GDO0 to show when the device gets a SyncWord.
My objective is to get an average consumption of 8,8 µA and a check of Rx data every second. It is written in the datasheet but there is no information about the configuration we should have except to have a 542 kHz filter bandwidth, a 250 kBaud data rate and a PLL calibration every 4th wakeup. I configure the first two things (data rate and filter bandwidth) but I don't know how to configure the PLL calibration every 4th wakeup but I don't know how to do it.
Whatever starting with my current configuration (with the average consumption of 200 µA) I thought that I need to lower the Rx timeout. Unfortunately that does not seem to work. With a Tx device sending a continuous packet I have to wait for 1 minutes to get the interruption on the Rx device (with a Rx timeout of 7 ms). A Rx timeout of 15 ms seems to me to be the limit acceptable. I read on the CC1101 Silicon Errata that "for timeouts less than approximately 11 ms, the timeout period is too short to switch to the 270.8 Hz clocking scheme". Is that linked to my problem ?
You'll find attached to this email the register configuration when I get the average consumption of 200 µA.
Thanks in advance.
Regards,
Renan
  • Hi Renan

    The settings used (RF wise) is the 250 kbps settings from SmartRF Studio, with MCSM0.FS_AUTOCAL = 11b

    RX polling once every second, means that tEvent0 = 1 s

     

    Setting WORCTRL.WOR_RES = 0, means that

    EVENT0 = tEvent0*(fxosc/750) = 34666 = 0x876A

    The current consumption in the data sheet is for the sniffing only, meaning that the RSSI is always below threshold so that no packets are being received. RX_TIME_RSSI = 1 meaning that the radio terminates RX as soon as it detects that there is nothing on the air.

    If there are a signal on the air, the radio will continue in RX, and the current consumption will be higher.

    With a sniff interval of 1 s and WOR_RES = 0, the following RX timeouts can be achieved:

    125, 62.5, 31.25, 15.63, 7.81, 3.91, 1.96 ms

    Transmitting a 10 byte long payload (including length byte) will take 640 us.

    That means that too be sure that you are able to receive all transmitted packets, a packet needs to be repeated more than 1500 times (back-to-back) to be able to detect it with a 1 s sniff interval.

    If you are not sending the packets back-to-back (TXOFF_MODE = TX) you risk that your receiver wakes up in-between packets, and terminates again since there will be no signal on the air above threshold between the packets.

  • Hello Siri,

    Please see my customer response below:

    Thank you for this response. I am currently trying to send the packet back-to-back but it does not seem to be working.
    I configured MCSM0.TXOFF_MODE=2 on my transmitter device. I send a packet count of 100 (just for the test) but on my current analyzer I see that the current is switching continuously between the TX state and Idle state.
    Do I have to configure something more to send all my packets back-to-back ?
    Regards,
    Renan
  • Hi Renan

    I made a small example code where I transmitted a 10 bytes long packet 100 times back to back.

    My code is below

    static const registerSetting_t preferredSettings[]= 
    {
      {CC1101_IOCFG2,      0x06},
      {CC1101_IOCFG0,      0x5B}, // High when in TX
      {CC1101_PKTCTRL0,    0x05},
      {CC1101_FSCTRL1,     0x12},
      {CC1101_FREQ2,       0x21},
      {CC1101_FREQ1,       0x62},
      {CC1101_FREQ0,       0x76},
      {CC1101_MDMCFG4,     0x2D},
      {CC1101_MDMCFG3,     0x3B},
      {CC1101_MDMCFG2,     0x93},
      {CC1101_DEVIATN,     0x62},
      {CC1101_MCSM0,       0x18},
      {CC1101_MCSM1,       0x32},// TXOFF_MODE = TX
      {CC1101_FOCCFG,      0x1D},
      {CC1101_BSCFG,       0x1C},
      {CC1101_AGCCTRL2,    0xC7},
      {CC1101_AGCCTRL1,    0x00},
      {CC1101_AGCCTRL0,    0xB0},
      {CC1101_WORCTRL,     0xFB},
      {CC1101_FREND1,      0xB6},
      {CC1101_FSCAL3,      0xEA},
      {CC1101_FSCAL2,      0x2A},
      {CC1101_FSCAL1,      0x00},
      {CC1101_FSCAL0,      0x1F},
      {CC1101_TEST0,       0x09},
    };
    
    
    #define ISR_ACTION_REQUIRED 1
    #define ISR_IDLE            0
    
    #define PKTLEN              10
    
    #define GPIO2               0x08
    #define GPIO0               0x80
    
    static uint8  packetSemaphore;
    static uint32 packetCounter = 0;
    
    static void initMCU(void);
    static void registerConfig(void);
    static void runTX(void);
    static void createPacket(uint8 txBuffer[]);
    static void radioTxISR(void);
    static void updateLcd(void);
    
    void main(void) {
    
        // Initialize MCU and peripherals
        initMCU();
    
        // Write radio registers
        registerConfig();
    
        // Enter runTX, never coming back
        runTX();
    }
    
    
    
    static void runTX(void) {
    
        // 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);
    
        // Update LCD
        updateLcd();
    
        // Infinite loop
        while(TRUE) {
          
            while(!(bspKeyPushed(BSP_KEY_ALL))); 
          
            createPacket(txBuffer);
          
            packetCounter = 0;
    
            // Write packet to TX FIFO
            cc1101SpiWriteTxFifo(txBuffer,sizeof(txBuffer));packetCounter++;
            cc1101SpiWriteTxFifo(txBuffer,sizeof(txBuffer));packetCounter++;
    
            // Strobe TX to send packet
            trxSpiCmdStrobe(CC1101_STX);
                    
            while (packetCounter++ < 100) {
    
                while(packetSemaphore != ISR_ACTION_REQUIRED);
                      
                // Clear semaphore flag
                packetSemaphore = ISR_IDLE;
                      
                cc1101SpiWriteTxFifo(txBuffer,sizeof(txBuffer));
            }
        }
    }
    
    static void radioTxISR(void) {
    
        // Set packet semaphore
        packetSemaphore = ISR_ACTION_REQUIRED;
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    }

    Since I used a packet length of 10, I could write 2 packets to the FIFO before strobing STX, and then, while one packet is being sent on the air, the next one is written to the FIFO.

    When using TXOFF_MODE = TX, the radio will transmit preamble as long as there are no data in the FIFO, so if you do not refill fast enough, you will have a long preamble between every packet.

    Not sure how you are able to enter TX mode when you are using TXOFF_MODE = TX.

    Below is a screenshot showing the timing:

    As you can see, it takes around 0.257 ms from GDO2  goes low (packet sent) until it goes high again (sync sent). This corresponds to the time it takes to send 4 bytes preamble and 4 bytes sync at 250 kbps.

    BR

    Siri

  • Hello Siri,

    Please my customer response below:

    Thank you for the information concerning the back to back sending packet. I’ll see how to implement it on my device.

    While I was waiting for your response I managed to configure my Tx device with a packet interval of 0 ms (actually I measured the timing and it is around 312 µs with a 390 µs packet duration). On the Rx device I measure an average consumption of 40 µA with an Rx timeout around 2 ms and a sleeping time around 996 ms (1 seconds minus the Rx timeout, event1 time and idle to Rx time). With this configuration I am able to get every Tx packet within the Rx state and to generate the interruption on GD0.

    Now I want to lower the consumption of my Rx device. I see on the datasheet that it should be possible to get an average consumption of 8,8 µA but there is no information about the configuration we should set. I can’t change the event0 time (fixed by my specifications). The Rx timeout is the lowest possible (duty cycle of 0,195%). I can change the event1 time and the idle to Rx time. Unfortunately with their lower value the theoretical consumption is still above the 8,8 µA (30 µA if I didn’t make any mistake).

    I want to precise that I measure the consumption during the sleeping state. It is around 0,5 µA. I did the same thing during the event1 time + idle to Rx time + Rx timeout and I measured 10 mA.

    What is the configuration I should have to achieve this infamous consumption of 8,8 µA ?

    Regards,

    Renan

  • Unfortunately I do not have any possibilities to do measurements myself at the moment, but what you need to check is how long the radio is in RX when you measuring.

    The current consumption mentioned in the data sheet is the average current consumption when there there are NO signal on the air, meaning that the time the radio spend in RX should be equal to the RSSI response time (See AN047: https://www.ti.com/lit/swra126 for details). If the RSSI threshold is set to low, and are below the noise floor, the radio wills tay in RX for the entire RX Timeout each time it wakes up, and the average current consumption will increase.

    Siri