• TI Thinks Resolved

LAUNCHXL-CC1352P: Rf_cmdPropRx stops calling Callback after PROP_ERROR_RXBUFF

Prodigy 90 points

Replies: 3

Views: 69

Part Number: LAUNCHXL-CC1352P

Recently we tried to increase amount of messages flowing through our test network, and every time we started tests one by one every board stopped receiving messages. We checked command status and it was PROP_ERROR_RXBUFF. What I understand from description of this error (No available Rx buffer at the start of a packet) is that assigned queue was too small and RFCore tried to put new message in it but it was full. What I don't understand is why after this error occurs, posted Rf_cmdPropRx doesn't call callback when any new packet is being transmitted by other board. After flushing all commands and posting Rf_cmdPropRx its status changes to ACTIVE (0x02) and we are even able to get proper rssi read, but no received message callback after this error. Is there any way to somehow configure RFCore to not block receiving messages after this error? 

  • I cannot see why you should not be able to receive any callback after having the PROP_ERROR_RXBUFF status. I have done several tests using the rfPacketRX example from the SDK, and modified it so that it have gotten status set to PROP_ERROR_RXBUFF, but in all cases I can always receive the next packet.

    To be able to get an overflow, I made the buffers 5 bytes to small for the larges packets the radio could receive:

    #pragma DATA_ALIGN (rxDataEntryBuffer, 4);
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES - 5)];
    .
    .
    .
    .
    if( RFQueue_defineQueue(&dataQueue,
                                rxDataEntryBuffer,
                                sizeof(rxDataEntryBuffer),
                                NUM_DATA_ENTRIES,
                                MAX_LENGTH + NUM_APPENDED_BYTES - 5))
    {
        /* Failed to allocate space for all data entries */
        while(1);
    }

    The default code example will not enter RX again if it for some reason (for example if status is PROP_ERROR_RXBUFF), so I modified it to run the RX command again in case it exits RX:

    while(1)
    {
        /* Enter RX mode and stay forever in RX */
        RF_EventMask terminationReason = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRx,
                                                   RF_PriorityNormal, &callback,
                                                 RF_EventRxEntryDone);
    
        switch(terminationReason)
        {
            case RF_EventLastCmdDone:
                // A stand-alone radio operation command or the last radio
                // operation command in a chain finished.
                break;
            case RF_EventCmdCancelled:
                // Command cancelled before it was started; it can be caused
                // by RF_cancelCmd() or RF_flushCmd().
                break;
            case RF_EventCmdAborted:
                // Abrupt command termination caused by RF_cancelCmd() or
                // RF_flushCmd().
                break;
            case RF_EventCmdStopped:
                // Graceful command termination caused by RF_cancelCmd() or
                // RF_flushCmd().
                break;
            default:
                // Uncaught error event
                while(1);
        }
        
        uint32_t cmdStatus = ((volatile RF_Op*)&RF_cmdPropRx)->status;
        switch(cmdStatus)
        {
            case PROP_DONE_OK:
                // Packet received with CRC OK
                break;
            case PROP_DONE_RXERR:
               // Packet received with CRC error
                break;
            case PROP_DONE_RXTIMEOUT:
                // Observed end trigger while in sync search
                break;
            case PROP_DONE_BREAK:
                // Observed end trigger while receiving packet when the command is
                // configured with endType set to 1
                break;
            case PROP_DONE_ENDED:
                // Received packet after having observed the end trigger; if the
                // command is configured with endType set to 0, the end trigger
                // will not terminate an ongoing reception
                break;
            case PROP_DONE_STOPPED:
                // received CMD_STOP after command started and, if sync found,
                // packet is received
                break;
            case PROP_DONE_ABORT:
                // Received CMD_ABORT after command started
                break;
            case PROP_ERROR_RXBUF:
                // No RX buffer large enough for the received data available at
                // the start of a packet
                error++;
                break;
            case PROP_ERROR_RXFULL:
                // Out of RX buffer space during reception in a partial read
                break;
            case PROP_ERROR_PAR:
                // Observed illegal parameter
                break;
            case PROP_ERROR_NO_SETUP:
                // Command sent without setting up the radio in a supported
                // mode using CMD_PROP_RADIO_SETUP or CMD_RADIO_SETUP
                break;
            case PROP_ERROR_NO_FS:
                // Command sent without the synthesizer being programmed
                break;
            case PROP_ERROR_RXOVF:
                // RX overflow observed during operation
                break;
            default:
                // Uncaught error event - these could come from the
                // pool of states defined in rf_mailbox.h
                while(1);
        }
    }

    I can with this code send packets that are not room for in the data entry and status will be set to PROP_ERROR_RXBUFF, but the next packet I send of proper size, will be received OK.

    If you are not able to solve your problems based on the code I have posted, you should make a small example based on one of the default examples in the SDK, that fails, so that we can do some debugging here.

    BR

    Siri

     

  • In reply to Siri:

    The problem is that we never sent packets that could exceed buffer length of one entry. And Rx commands maxPktLen was also set to avoid PROP_ERROR_RXBUFF. The board just randomly stops receiving new packets. We were able to somehow solve this problem. Before solving the problem, callback from rx command had simple processing and placing received packets in queue written by us, so it went from dataQueue to processing it to our own structure and then into our queue. Now the callback does nothing and lowest priority task just checks status of current data entry and does the same thing as the callback used to. Is it possible that because operations in radio callback was so long something could just went wrong? My assumption is that when a lot of short packets were being received not every callback was called and some packets was left in the queue and after some time the queue was full because only callback was taking those messages from queue and after omitting NUM_DATA_ENTRIES callbacks queue was full with not processed packets.

  • In reply to Piotr Klimkowski:

    First of all, you RX code should not only handle the packets you are sending. It should handle all kinds of packets. That means that even if your transmitter never sends a packet longer than 30 bytes, the receiver can find sync word in noise and interpret the next receive data (noise) as the length byte. If this is a value larger than 30, you either needs to filter it away using length filtering, or you need to make sure that your data entries are large enough to receive the complete packet (length byte + 255 data bytes + status byte).

    If you have made sure that the data entries are large enough to handle the packet sizes that you have allowed the radio to received, you still need to make sure that you are emptying the data entries fast enough so that there is room for the next packets received.