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.

CC1350: RF core stops receiving in proprietary mode.

Part Number: CC1350

Hello All,

I am using CC1350 in proprietary mode in the 915 Mhz band.  I have a network that includes a collector and sensors with repeaters in between.  I am running into problems with the repeaters.  The repeaters listen and buffer received packets.  Then at a random time interval after reception the packets will be retransmitted. Everything seems to work as expected but occasionally the receive functionality in the RF Core seems to go offline.  The repeater can still send its status packets and I see them coming in on the collector, but no other repeated traffic is showing up and the Watchdog timer, which is reset whenever a packet is received will time out resetting the device.  My Watchdog timer is set for 6 minutes so for a significant bit of time the repeater will not capture RX packets but still send out the status packets.

I have tried many different RF command variations from the application processor, but they do not seem to effect the error.  The error also occurs more frequently whenever there is more RF traffic.  The system is not time synchronized, so there can be packet collisions.  Any insight would be appreciated.

This project has been going on for a while so I am using SimpleLink CC13x0 SDK version 1.60.0.21.

Here is the relevant code that sends commands to the RF Core.

static void rfTaskFunction(UArg arg0, UArg arg1)
{
    /* create an Event object. All events are binary */
    rfTaskEvent = Event_create(NULL, NULL);
    if (rfTaskEvent == NULL) {
    System_abort("Event create failed");
    }

    RF_Params rfParams;
    RF_Params_init(&rfParams);

    if( RFQueue_defineQueue(&dataQueue,
                            rxDataEntryBuffer,
                            sizeof(rxDataEntryBuffer),
                            NUM_DATA_ENTRIES,
                            MAX_LENGTH_EC + NUM_APPENDED_BYTES))
    {
        /* Failed to allocate space for all data entries */
        while(1);
    }

    /* Modify CMD_PROP_RX command for application needs */
    RF_cmdPropRx.pQueue = &dataQueue;           /* Set the Data Entity queue for received data */
    RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;  /* Discard ignored packets from Rx queue */
    RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 0;   /* Discard packets with CRC error from Rx queue */
    RF_cmdPropRx.maxPktLen = MAX_LENGTH_EC;        /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
    RF_cmdPropRx.pktConf.bRepeatOk = 0;         /* End Rx after receiving a packet correctly */
    RF_cmdPropRx.pktConf.bRepeatNok = 0;        /* End Rx after receiving a packet with CRC error */
    RF_cmdPropRx.pOutput = (uint8_t*)&rxStatistics; /* Set up RX command to output statistics data */
    RF_cmdPropRx.pktConf.bUseCrc = 0;               /* 0: Do not check CRC */


    /* Setup RF Properties Transmit */
    RF_cmdPropTx.pktLen = HW_PACKET_LENGTH * REP_NUM;
    RF_cmdPropTx.pPkt = packetEC_Tx;
    RF_cmdPropTx.startTrigger.triggerType = TRIG_REL_SUBMIT;           /* Trigger packet Tx command relative to submit */
    RF_cmdPropTx.startTrigger.pastTrig = 1;
    RF_cmdPropTx.startTime = PAIR_REPLY_DELAY;
    RF_cmdPropTx.pktConf.bUseCrc = 0;                       /* Do not append CRC */

    /* Request access to the radio */
    rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);

    /* Set the frequency */
    RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);


    /* Start initial Rx command in RF core */
    RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &Rx_callback, RF_EventRxEntryDone);

    /* Setup  periodic callback for transmit delay timer */
    Util_constructClock(&TransmitPeriodicClock, TransmitPeriodicHandler, TRANSMIT_PERIODIC_TIMEOUT, TRANSMIT_PERIODIC_TIMEOUT, false, 0);
    Util_startClock(&TransmitPeriodicClock);

    Util_constructClock(&rssiTimerClock, RSSI_TimoutHandler, RSSI_HDC_PERIOD, RSSI_HDC_PERIOD, false, 0);        // Setup RSSI clock with High Duty Cycle Timing.
    Util_startClock(&rssiTimerClock);


    UInt repeaterEvents;
    RF_CmdHandle rxCmdHndl;
    bool txReady;

    while(1)
    {

        repeaterEvents = Event_pend(rfTaskEvent, RF_AND_EVENTS, RF_OR_EVENTS, BIOS_WAIT_FOREVER);


        if(repeaterEvents & RSSI_SEND_EVENT)
        {
            PIN_setOutputValue(pinHandle, HW_PIN_RLED, LED_ON);

            /* Force abort gracefully */
            RF_cancelCmd(rfHandle, rxCmdHndl, 0);

            SendRSSI_Packet(&packetHw);

            /* Send Rx command to RF core */
            rxCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &Rx_callback, RF_EventRxEntryDone);
            PIN_setOutputValue(pinHandle, HW_PIN_RLED, LED_OFF);
        }


        if(repeaterEvents & RF_RX_EVENT)
        {
            /* Blink Green LED to indicate RX */
            PIN_setOutputValue(pinHandle, HW_PIN_GLED, LED_ON);

#ifdef WATCHDOG_ON
            Watchdog_clear(watchdogHandle);
#endif


            RF_cancelCmd(rfHandle, rxCmdHndl, 0);

            /* Process Packet Received from RF */
            RF_Packet_Process();

            /* Send Rx command to RF core */
            rxCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &Rx_callback, RF_EventRxEntryDone);
            PIN_setOutputValue(pinHandle, HW_PIN_GLED, LED_OFF);
        }


        if(repeaterEvents & TX_TMR_TIMEOUT_EVENT)
        {
            txReady = RF_Tx_Ready();

            if(txReady)
            {
                /* Blink Yellow LED to indicate RX */
                PIN_setOutputValue(pinHandle, HW_PIN_YLED, LED_ON);

                /* Force abort gracefully */
                RF_cancelCmd(rfHandle, rxCmdHndl, 0);

                 /* Send packet */
                 RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0);

                 /* Send Rx command to RF core */
                 rxCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &Rx_callback, RF_EventRxEntryDone);
                 PIN_setOutputValue(pinHandle, HW_PIN_YLED, LED_OFF);
            }

        }

    }
}

Here is my RX callback function.

void Rx_callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{
    if (e & RF_EventRxEntryDone)
    {
        rxRatVal = RF_getCurrentTime();


        /* Get current unhandled data entry */
         currentDataEntry = RFQueue_getDataEntry();

         /* Handle the packet data, located at &currentDataEntry->data:
          * - Length is the first byte with the current configuration
          * - Data starts from the second byte */
         packetLength      = *(uint8_t*)(&currentDataEntry->data);
         packetDataPointer = (uint8_t*)(&currentDataEntry->data + 1);

         /* Copy the payload to the packet variable */
         memcpy(packetEC_Rx, packetDataPointer, packetLength);

         /* Move to next dataEntry */
          RFQueue_nextEntry();

          Event_post(rfTaskEvent, RF_RX_EVENT);

    }
}

The RSSI_SEND_EVENT is triggered once a minute to send info on network health.  

The TX_TMR_TIMEOUT_EVENT is triggered once every 10 millisecond to see if a previously received packet is ready to be retransmitted.

Is there any problems with my usage of RF commands that would cause a RX lockup but still allow TX operations to continue?

Are there any know issues that could cause the RF core to have an RX lockup?

Thanks

  • Hi Joshua,

    A few questions:

    1) Are you seeing this on the repeater, sensor or collector devices? (Or all?)

    2) What is the status of the Rx command when this happens?

    3) It's possible to monitor the Tx and Rx pins with a logic analyzer. You can use this to check at what point the Rx stops or is not re-scheduled. Please see the user's guide:

    https://dev.ti.com/tirex/content/simplelink_cc13x0_sdk_4_10_01_01/docs/proprietary-rf/proprietary-rf-users-guide/proprietary-rf-guide/debugging-index.html#debugging-rf-output

    Cheers,

    Marie H.

  • Hello Marie,

    I have been able to figure out the problem looking at the status code for the RX command.  I was getting a PROP_ERROR_RXBUF status error.  I am not sure how the RFQueue entry was not getting released because every time the Rx_callback is run the  RFQueue_nextEntry(); command is run to free that entry.

    To resolve the problem I simply check the RX command status to see if PROP_ERROR_RXBUF error has occurred.  If so I then free the RFQueue entry before posting the RX command to the RF core.  I also check if the next entry is free in case both the queue entries are not in the DATA_ENTRY_PENDING state.  This seems to have fixed my problem with no more RX lockups occurring.

    /* Send Rx command to RF core */
    if(RF_cmdPropRx.status == PROP_ERROR_RXBUF) // Check if Free RFQueue entry
    {
        uint8_t entryStatus = RFQueue_nextEntry();
        if(entryStatus != DATA_ENTRY_PENDING)           // Test if Queue entry is free
        {
            RFQueue_nextEntry();        // Free next entry
        }
    }
    
    rxCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &Rx_callback, RF_EventRxEntryDone);

    Thanks,

    Josh

  • Thank you for posting the solution!

    Cheers,
    Marie H.