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: Sending packets on fixed packet length mode triggers state fifo_underflow

Part Number: CC1101
Other Parts Discussed in Thread: TEST2

I'm trying to send packets of fixed length (40 bytes) using the cc1101.

I have the following code for testing, this is the only task which is being run on the esp32:

void senderTask(void *arg){
    static const char *TAG = "TX_TASK";

    ESP_ERROR_CHECK(cc1101_init(CS_PIN, MISO_PIN,MOSI_PIN, SCLK_PIN, SPI_CLOCK, VSPI_HOST, GDO0_PIN));

    int counter = 0;

    while (true){
        counter++;


        // BEGIN TEST
        ESP_LOGI(TAG, "msg: %u", counter);

            // wait IDLE,
        uint8_t reg_value = 0;
        do {
            reg_value = cc1101_readStatusReg(CC1101_MARCSTATE) & 00011111;
            if (reg_value != 0x01){
                cc1101_cmdStrobe(CC1101_SIDLE);
            }
        } while(reg_value != 0x01);


        // define data to send
        uint8_t data[40] = {39,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};


        ESP_LOGI(TAG, "---------FIXED PACKET LENGTH---------");
        // set fixed packet length mode
        cc1101_writeReg(CC1101_PKTCTRL0,0x00);

        // flush tx fifo
        cc1101_cmdStrobe(CC1101_SFTX);

        // write packet to fifo
        cc1101_writeBurstReg(CC1101_TXFIFO, data,sizeof(data));

        // check number of bytes written to the tx fifo
        reg_value = cc1101_readStatusReg(CC1101_TXBYTES);
        ESP_LOGI(TAG, "Number of bytes on tx fifo after burst write: %u", reg_value & 0b01111111);


        // print status before tx
        reg_value = cc1101_readStatusReg(CC1101_MARCSTATE) & 0b00011111;
        ESP_LOGI(TAG, "Status before tx: %u", reg_value);

        // send TX strobe
        cc1101_cmdStrobe(CC1101_STX);

        // wait packet sended
        vTaskDelay(100 / portTICK_PERIOD_MS);

        // print status after tx
        reg_value = cc1101_readStatusReg(CC1101_MARCSTATE) & 0b00011111;
        ESP_LOGI(TAG, "Status after tx: %u", reg_value);


        // reset
        cc1101_cmdStrobe(CC1101_SIDLE);
        reg_value = cc1101_readStatusReg(CC1101_MARCSTATE) & 0b00011111;
        ESP_LOGI(TAG, "Status after resetting to idle: %u", reg_value);




        ESP_LOGI(TAG, "---------VARIABLE PACKET LENGTH---------");
        // set variable packet length mode
        cc1101_writeReg(CC1101_PKTCTRL0,0x01);


        // flush tx fifo
        cc1101_cmdStrobe(CC1101_SFTX);

        // write packet to fifo
        cc1101_writeBurstReg(CC1101_TXFIFO, data,sizeof(data));

        // check number of bytes written to the tx fifo
        reg_value = cc1101_readStatusReg(CC1101_TXBYTES);
        ESP_LOGI(TAG, "Number of bytes on tx fifo after burst write: %u", reg_value & 0b01111111);

        // print status before tx
        reg_value = cc1101_readStatusReg(CC1101_MARCSTATE) & 0b00011111;
        ESP_LOGI(TAG, "Status before tx: %u", reg_value);

        // send TX strobe
        cc1101_cmdStrobe(CC1101_STX);

        // wait packet sended
        vTaskDelay(100 / portTICK_PERIOD_MS);

        // print status after tx
        reg_value = cc1101_readStatusReg(CC1101_MARCSTATE) & 0b00011111;
        ESP_LOGI(TAG, "Status after tx: %u", reg_value);



        // reset
        cc1101_cmdStrobe(CC1101_SIDLE);
        reg_value = cc1101_readStatusReg(CC1101_MARCSTATE) & 0b00011111;
        ESP_LOGI(TAG, "Status after resetting to idle: %u", reg_value);
        ESP_LOGI(TAG, "END LOOP\n\n"); 

        // END TEST

        // wait 1 second
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }

    // hang foreveeee
    while(true)vTaskDelay(100 / portTICK_PERIOD_MS);;

}

One iteration of the loop outputs the following:

I (220632) TX_TASK: msg: 180
I (220632) TX_TASK: ---------FIXED PACKET LENGTH---------
I (220642) TX_TASK: Number of bytes on tx fifo after burst write: 40
I (220642) TX_TASK: Status before tx: 1
I (220742) TX_TASK: Status after tx: 22
I (220742) TX_TASK: Status after resetting to idle: 1
I (220742) TX_TASK: ---------VARIABLE PACKET LENGTH---------
I (220752) TX_TASK: Number of bytes on tx fifo after burst write: 40
I (220762) TX_TASK: Status before tx: 1
I (220862) TX_TASK: Status after tx: 1
I (220862) TX_TASK: Status after resetting to idle: 1
I (220862) TX_TASK: END LOOP

As you can see, for the same data, using fixed packet length results in the status being 22 (tx_underflow) while with variable packet cc1101 returns to state 1 (idle) without problem. I don't understand why is this happening. Can someone explain me?

As far as i understand from the datasheet, after sending a fixed packet length, cc1101 should return to idle state by default.

Thank you in advance.

If needed, here is the register values which are written to initialize the cc1101:

/* Address Config = No address check */
/* Base Frequency = 433.919830 */
/* CRC Autoflush = false */
/* CRC Enable = false */
/* Carrier Frequency = 433.919830 */
/* Channel Number = 0 */
/* Channel Spacing = 199.951172 */
/* Data Format = Normal mode */
/* Data Rate = 0.0247955 */
/* Deviation = 47.607422 */
/* Device Address = 0 */
/* Manchester Enable = false */
/* Modulated = true */
/* Modulation Format = GFSK */
/* PA Ramping = false */
/* Packet Length = 40 */
/* Packet Length Mode = Variable packet length mode. Packet length configured by the first byte after sync word */
/* Preamble Count = 4 */
/* RX Filter BW = 58.035714 */
/* Sync Word Qualifier Mode = 16/16 sync word bits detected */
/* TX Power = 10 */
/* Whitening = false */
// RF settings for CC1101
// generated from smartRF 7

#define CC1101_DEFVAL_IOCFG2            0x29    // GDO2 Output Pin Configuration
#define CC1101_DEFVAL_IOCFG1            0x2E    // GDO1 Output Pin Configuration
#define CC1101_DEFVAL_IOCFG0            0x06    // GDO0 Output Pin Configuration
#define CC1101_DEFVAL_FIFOTHR           0x47    // RX FIFO and TX FIFO Thresholds
#define CC1101_DEFVAL_SYNC1             0xD3    // Sync Word, High Byte
#define CC1101_DEFVAL_SYNC0             0x91    // Sync Word, Low Byte
#define CC1101_DEFVAL_PKTLEN            0x28    // Packet Length
#define CC1101_DEFVAL_PKTCTRL1          0x00    // Packet Automation Control
#define CC1101_DEFVAL_PKTCTRL0          0x01    // Packet Automation Control
#define CC1101_DEFVAL_ADDR              0x00    // Device Address
#define CC1101_DEFVAL_CHANNR            0x00    // Channel Number
#define CC1101_DEFVAL_FSCTRL1           0x0F    // Frequency Synthesizer Control
#define CC1101_DEFVAL_FSCTRL0           0x00    // Frequency Synthesizer Control
#define CC1101_DEFVAL_FREQ2             0x10    // Frequency Control Word, High Byte
#define CC1101_DEFVAL_FREQ1             0xB0    // Frequency Control Word, Middle Byte
#define CC1101_DEFVAL_FREQ0             0x71    // Frequency Control Word, Low Byte
#define CC1101_DEFVAL_MDMCFG4           0xF0    // Modem Configuration
#define CC1101_DEFVAL_MDMCFG3           0x00    // Modem Configuration
#define CC1101_DEFVAL_MDMCFG2           0x12    // Modem Configuration
#define CC1101_DEFVAL_MDMCFG1           0x22    // Modem Configuration
#define CC1101_DEFVAL_MDMCFG0           0xF8    // Modem Configuration
#define CC1101_DEFVAL_DEVIATN           0x47    // Modem Deviation Setting
#define CC1101_DEFVAL_MCSM2             0x07    // Main Radio Control State Machine Configuration
#define CC1101_DEFVAL_MCSM1             0x30    // Main Radio Control State Machine Configuration
#define CC1101_DEFVAL_MCSM0             0x04    // Main Radio Control State Machine Configuration
#define CC1101_DEFVAL_FOCCFG            0x36    // Frequency Offset Compensation Configuration
#define CC1101_DEFVAL_BSCFG             0x6C    // Bit Synchronization Configuration
#define CC1101_DEFVAL_AGCCTRL2          0x03    // AGC Control
#define CC1101_DEFVAL_AGCCTRL1          0x40    // AGC Control
#define CC1101_DEFVAL_AGCCTRL0          0x91    // AGC Control
#define CC1101_DEFVAL_WOREVT1           0x87    // High Byte Event0 Timeout
#define CC1101_DEFVAL_WOREVT0           0x6B    // Low Byte Event0 Timeout
#define CC1101_DEFVAL_WORCTRL           0xF8    // Wake On Radio Control
#define CC1101_DEFVAL_FREND1            0x56    // Front End RX Configuration
#define CC1101_DEFVAL_FREND0            0x10    // Front End TX Configuration
#define CC1101_DEFVAL_FSCAL3            0xE9    // Frequency Synthesizer Calibration
#define CC1101_DEFVAL_FSCAL2            0x2A    // Frequency Synthesizer Calibration
#define CC1101_DEFVAL_FSCAL1            0x00    // Frequency Synthesizer Calibration
#define CC1101_DEFVAL_FSCAL0            0x1F    // Frequency Synthesizer Calibration
#define CC1101_DEFVAL_RCCTRL1           0x41    // RC Oscillator Configuration
#define CC1101_DEFVAL_RCCTRL0           0x00    // RC Oscillator Configuration
#define CC1101_DEFVAL_FSTEST            0x59    // Frequency Synthesizer Calibration Control
#define CC1101_DEFVAL_PTEST             0x7F    // Production Test
#define CC1101_DEFVAL_AGCTEST           0x3F    // AGC Test
#define CC1101_DEFVAL_TEST2             0x81    // Various Test Settings
#define CC1101_DEFVAL_TEST1             0x35    // Various Test Settings
#define CC1101_DEFVAL_TEST0             0x09    // Various Test Settings
#define CC1101_DEFVAL_PARTNUM           0x00    // Chip ID
#define CC1101_DEFVAL_VERSION           0x04    // Chip ID
#define CC1101_DEFVAL_FREQEST           0x00    // Frequency Offset Estimate from Demodulator
#define CC1101_DEFVAL_LQI               0x00    // Demodulator Estimate for Link Quality
#define CC1101_DEFVAL_RSSI              0x00    // Received Signal Strength Indication
#define CC1101_DEFVAL_MARCSTATE         0x00    // Main Radio Control State Machine State
#define CC1101_DEFVAL_WORTIME1          0x00    // High Byte of WOR Time
#define CC1101_DEFVAL_WORTIME0          0x00    // Low Byte of WOR Time
#define CC1101_DEFVAL_PKTSTATUS         0x00    // Current GDOx Status and Packet Status
#define CC1101_DEFVAL_VCO_VC_DAC        0x00    // Current Setting from PLL Calibration Module
#define CC1101_DEFVAL_TXBYTES           0x00    // Underflow and Number of Bytes
#define CC1101_DEFVAL_RXBYTES           0x00    // Overflow and Number of Bytes
#define CC1101_DEFVAL_RCCTRL1_STATUS    0x00    // Last RC Oscillator Calibration Result
#define CC1101_DEFVAL_RCCTRL0_STATUS    0x00    // Last RC Oscillator Calibration Result



// change power output
#define CC1101_DEFVAL_PATABLE 0xc0

  • Hi

    I am not able to reproduce you problem:

    I tested the following settings:

    static const registerSetting_t preferredSettings[]= 
    {
        {CC1101_IOCFG2, 0x29},
        {CC1101_IOCFG1, 0x2E},
        {CC1101_IOCFG0, 0x06},
        {CC1101_FIFOTHR, 0x47},
        {CC1101_SYNC1, 0xD3},
        {CC1101_SYNC0, 0x91},
        {CC1101_PKTLEN, 0x28},
        {CC1101_PKTCTRL1, 0x00},
        {CC1101_PKTCTRL0, 0x00},
        {CC1101_ADDR, 0x00},
        {CC1101_CHANNR, 0x00},
        {CC1101_FSCTRL1, 0x0F},
        {CC1101_FSCTRL0, 0x00},
        {CC1101_FREQ2, 0x10},
        {CC1101_FREQ1, 0xB0},
        {CC1101_FREQ0, 0x71},
        {CC1101_MDMCFG4, 0xF0},
        {CC1101_MDMCFG3, 0x00},
        {CC1101_MDMCFG2, 0x12},
        {CC1101_MDMCFG1, 0x22},
        {CC1101_MDMCFG0, 0xF8},
        {CC1101_DEVIATN, 0x47},
        {CC1101_MCSM2, 0x07},
        {CC1101_MCSM1, 0x30},
        {CC1101_MCSM0, 0x04},
        {CC1101_FOCCFG, 0x16},
        {CC1101_BSCFG, 0x6C},
        {CC1101_AGCCTRL2, 0x03},
        {CC1101_AGCCTRL1, 0x40},
        {CC1101_AGCCTRL0, 0x91},
        {CC1101_WOREVT1, 0x87},
        {CC1101_WOREVT0, 0x6B},
        {CC1101_WORCTRL, 0xFB},
        {CC1101_FREND1, 0x56},
        {CC1101_FREND0, 0x10},
        {CC1101_FSCAL3, 0xE9},
        {CC1101_FSCAL2, 0x2A},
        {CC1101_FSCAL1, 0x00},
        {CC1101_FSCAL0, 0x1F},
        {CC1101_RCCTRL1, 0x41},
        {CC1101_RCCTRL0, 0x00},
        {CC1101_FSTEST, 0x59},
        {CC1101_PTEST, 0x7F},
        {CC1101_AGCTEST, 0x3F},
        {CC1101_TEST2, 0x81},
        {CC1101_TEST1, 0x35},
        {CC1101_TEST0, 0x09},
    };

    void main(void) {
    
        // Initialize MCU and peripherals
        initMCU();
    
        // Write radio registers
        registerConfig();
        
        uint8 txBuffer[40] = {39,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
    
        // Connect ISR function to GPIO2
        ioPinIntRegister(IO_PIN_PORT_1, GPIO0, &radioTxISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO0, IO_PIN_FALLING_EDGE);
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO0);
    
        // Enable interrupt
        ioPinIntEnable(IO_PIN_PORT_1, GPIO0);
    
        // Infinite loop
        while(TRUE) 
        {
            // Write packet to TX FIFO
            cc1101SpiWriteTxFifo(txBuffer,sizeof(txBuffer));
                    
            cc1101SpiReadReg(CC1101_TXBYTES, &temp, 1);   // temp = 0x28
            
            // 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);
                    
            cc1101SpiReadReg(CC1101_TXBYTES, &temp, 1);   // temp = 0
            cc1101SpiReadReg(CC1101_MARCSTATE, &temp, 1); // Temp = 0x01 (IDLE)
                    
            // Clear semaphore flag
            packetSemaphore = ISR_IDLE;
        }
    }

    I have verified the temp values read with the debugger.

    The only difference is that I use an interrupt to actually make sure that the packet is being sent (you should not use a SW delay for this)

    Other problems with your code is that you are not calibrating the synth as far as I can see.

    Also, I do not understand why you use a fixed length of 40 when your packet is only 16 bytes long.

    Siri

  • Thank you for your help, I finally found my issue. Shame on me.

    I had forgot to call my setRegisters() fucntion and this made PKTLEN to be set to the default 255. This explains why variable packet length worked but fixed packet length didn't. (As it was expecting a packet of 255 bytes)