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.

CC2640R2F-Q1: Excessive local RF noise causing radio problems.

Part Number: CC2640R2F-Q1
Other Parts Discussed in Thread: CC2640R2F, CC2640

Hi

We are testing a design containing a CC2640R2F, by deliberately causing lots of RF noise using a Signal Hound, wide band (80mHz) on the 2.4-2.480GHz band, at 13dBm, with badly matched antenna, about 3cm away from CC2640 antenna; to test for susceptibility and reliability.

The CC2640R2F opens up a receive path for indefinite reception, in high speed proprietary mode. The receive initiation and call back does not appear to be called on an error condition (need to double check this), but when checking the rfc_CMD_HS_RX_t structure, the .status attribute contains 0x3841 (No available Rx buffer at the start of a packet). The packet thru’put is very low (4 x 12byte packets every 20ms, all serviced very quickly), so not filling up the RF buffer queue.

The net result is that no packets are received after the deliberate noise source is stopped, as the radio has already terminated the reception command.

Could this deliberate noise be causing the radio engine within the CC2640 to get confused? Or overpowered? Or give up?

Kind regards

Gary Partis

  • Hi,

    It looks like you are using one of the HS modes. Can you please tell us the RF configuration you are testing? What does the noise source spectrum look like, is it modulated, are you sending packets with same syncword?

    Also, are you able to receive all packets without error when there is no noise source?

    You could also configure the RX command to receive an interrupt when sync word is received and this will help figure out if the device received a valid syncword.

    Regards,

     

  • Hi

    We are most definitely using a HS mode. Here are the relevant definitions:

    RF_Mode RF_ble5 =
    {
        .rfMode = RF_MODE_PROPRIETARY_2_4,
        .cpePatchFxn = &rf_patch_cpe_prop_prepare_fs,
        .mcePatchFxn = 0,
        .rfePatchFxn = 0
    };
    
    
    rfc_CMD_BLE5_RADIO_SETUP_t RF_cmdBle5RadioSetup_2mbps =
    {
        .commandNo = 0x1820,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .defaultPhy.mainMode = 0x1,
        .defaultPhy.coding = 0x0,
        .__dummy0 = 0x00,
        .config.frontEndMode = 0x0,
        .config.biasMode = 0x0,
        .config.analogCfgMode = 0x0,
        .config.bNoFsPowerUp = 0x0,
        .txPower = 0x9330,
        .pRegOverrideCommon = pOverridesCommon,
        .pRegOverride1Mbps = pOverrides1Mbps,
        .pRegOverride2Mbps = pOverrides2Mbps,
        .pRegOverrideCoded = pOverridesCoded
    };
    
    
    // Overrides for CMD_BLE5_RADIO_SETUP
    uint32_t pOverridesCommon[] =
    {
        // override_ble5_setup_override_common.xml
        // Rx: Set LNA IB trim value based on the selected defaultPhy.mainMode setting. (NOTE: The value 0x8 is a placeholder. The value to use should be set during run-time by radio driver function.)
        ADI_HALFREG_OVERRIDE(0,4,0xF,0x8),
        // Rx: Set LNA IB offset used for automatic software compensation to 0
        (uint32_t)0x00008883,
        // Synth: Use 24 MHz crystal, enable extra PLL filtering
        (uint32_t)0x02010403,
        // Synth: Set fine top and bottom code to 127 and 0
        HW_REG_OVERRIDE(0x4020, 0x7F00),
        // Synth: Configure faster calibration
        HW32_ARRAY_OVERRIDE(0x4004, 1),
        // Synth: Configure faster calibration
        (uint32_t)0x1C0C0618,
        // Synth: Configure faster calibration
        (uint32_t)0xC00401A1,
        // Synth: Configure faster calibration
        (uint32_t)0x21010101,
        // Synth: Configure faster calibration
        (uint32_t)0xC0040141,
        // Synth: Configure faster calibration
        (uint32_t)0x00214AD3,
        // Synth: Decrease synth programming time-out by 64 us (0x0300 RAT ticks = 192 us)
        (uint32_t)0x03000243,
        // Bluetooth 5: Set correct total clock accuracy for received AuxPtr assuming local sleep clock of 50 ppm
        (uint32_t)0x0E490823,
        // override_frontend_id.xml
        (uint32_t)0xFFFFFFFF
    };
    
    

    The noise source has a centre frequency of 2.44GHz, with a 40MHz symbol rate (to cover all 80 channels of 2.5GHz spectrum), FSK modulated with a cyclic data pattern of :

    0100000011111110101010011001110111010010110001101111011010110110010010001110000101111100101011100110100010011110001010000110000

    The sync word does not exist in the fixed bit stream; and when requesting RF_EventMdmSoft callbacks, none occur when only the noise source is present.

    Prior to the noise source, all packets are received correctly, and during & after the noise source packets are still normally received correctly. Just every so often, the radio does not receive anything.

    It is as if an error has occurred and no callback was made to announce the fast; then the radio receive is silently shutdown; but as we are awaiting a semaphore (posted from RX callback code) we essentially hang.

    Please note that we are using SDK version 1.50.0.58. If this is a known problem which has been fixed in a later SDK then we shall update the SDK; however, upgrading for the sake of upgrading may introduce other issues which may not become immediately apparent, thus causing further problems.

    Kind regards

  • Hi,

    Thank you for clarification.

    It is generally a good idea to update to the latest SDK version since they have many bug fixes. However, without knowing the root cause for the issue you are seeing, we do not know if upgrading to the latest SDK will fix it.

    Are you using fixed length packet or variable length packet? If you are using variable length packets, can you please try fixed length packets for debug and try to replicate this? Would you be able to figure out if the last packet received before the radio stops receiving packets was received with CRC error and do you have autoflush enabled for packets received with CRC error.

    What is the PER observed with noise?

    Regards,

  • Hi,

    Do you still need help with this or is the issue resolved?

    Regards,

  • Hi

    Apologies in the delay in replying. I have been away from the office.

    We are using variable length packets (from 12 to 65 bytes of payload, plus address, length, sync, preamble and CRC data). We flush packets with invalid CRCs, but have yet to capture if the packet prior to the hang, had a CRC error.

    However, I have further information on the problem we are seeing.

    We are using a RF_postCmd to open a receive stream, so no errors would be reported on command initiation.

    We are now enabling all callback events (ie. Event mask set to 0xffffffffffffffff), and occasionally get RF_EventRxBufFull but all entries in the RX FIFO are empty (ie. all statuses = 0 DATA_ENTRY_STATUS_PENDING).

    Previously, we did not catch this event type, so if it were to occur, it would have stopped the RX stream, and we’d be completely unaware of this.

    So, what “RX buffer” is the event referring to, when the 8-deep FIFO used to communicate received packets from the radio to the M3 application code, is completely empty?

    Kind regards

  • Hi again

    Something else has just occurred to me.

    As we are using variable length packets, and we have a max packet size which is specified in the RX queue structure; if the length byte got corrupted over the air, and it appeared to signify a larger packet than we can cope with, would that cause a RF_EventRxBufFull event?

    I am asking this as it would be unable to buffer the packet (assuming CRC matched etc etc).

    Kind regards

  • Hi SVS

    I am guessing you are on holiday/vacation.

    A bit more information. I increased the size of the radio packet FIFO to cover any packets upto 255 bytes (plus pre/post data such as length, timestamp etc); and the problem still occurs.

    To recap, when in receive mode, the callback function is called with the event "RF_EventRxBufFull", when all the FIFO slots in the packet buffer are empty. Why? And how do I stop it?

    Kind regards

  • Hello

    Yet more information.

    In the CC2640R2F Technical Reference Manual, section 23.6.4.7 (Generic Receiver Command), it states "If the packet being received did not fit in the RX queue, the packet is received to the end, but the received bytes are not stored. If the packet would normally not have been discarded from the RX buffer, the operation ends.". This is what we are seeing, but there are a full compliment of RX queue entries available.

    Further, nRxBufFull element of the rfc_hsRxOutput_s structure is incremented on each RF_EventRxBufFull event, and after 9 minutes on our test rig, it reached the value of 65. 9 minutes equates to 27000 receive commands, of which in this instance, 65 were terminated early, with a claimed "buffer full" status.

    In this instance there was no deliberate perturbation, so the "buffer full" event causing receive commands to stop, just seem to happen sporadically.

    Some test code was also written to keep a history of all call back event bitmaps, and there were no packets with bad CRCs immediately prior to the "buffer full" event.

    Is this a bug in the radio code which erroneously thinks there is no space remaining in the RX queue (or buffer, or FIFO, depending on terminology)?

    Kind regards

  • Hi Gary,

    I will try to look into this while SVS is out and get back to you. Would it be possible for you to share the code you use on the receiver side (or at least a snippet of the relevant parts (sending cmds, callbaks, RX settings etc.)? 

  • Hi Max

    Firstly, I can confirm the problem of the receive terminating prematurely, occurs on both SDK versions 1.50.0.58 and 3.10.0.15.

    The receive code, uses address filtering. There are also two types of receive, one which has a bounded end time using the RAT timer and one which is indefinite and stopped manually with a RF_cancelCmd(). Both types can terminate early with a “buffer full” condition.

    All packets are in the range of 12 to 65 bytes. The radio FIFO queue is set to 80 bytes per entry.

    Example of a timed reception

    RF_cmdRX->startTrigger.triggerType = TRIG_NOW;
    RF_cmdRX->endTrigger.triggerType = TRIG_ABSTIME;
    RF_cmdRX->endTrigger.pastTrig = 1;
    RF_cmdRX->endTime = GetRatTime( time );
    RF_cmdRX->condition.rule = COND_NEVER;
    RF_cmdRX->pNextOp = NULL;
    cmdHndl = RF_postCmd( rfHandle, (RF_Op*)RF_cmdRX, RF_PriorityHighest, &RxCallBack, 0xffffffffffffffffLL );
    

    Example of an indefinite reception

    RF_cmdRX->startTrigger.triggerType = TRIG_NOW;
    RF_cmdRX->endTrigger.triggerType = TRIG_NEVER;
    RF_cmdRX->condition.rule = COND_NEVER;
    RF_cmdRX->pNextOp = NULL;
    cmdHndl = RF_postCmd( rfHandle, (RF_Op*)RF_cmdRX, RF_PriorityHighest, &RxCallBack, 0xffffffffffffffffLL);
    

    The RF call back code

    static void RxCallBack( RF_Handle rfHandleParam, RF_CmdHandle cmdHandleParam, RF_EventMask eventMask )
    {
        if( eventMask & RF_EventRxEntryDone )
        {
            /* packet received, so inform non-IRQ task to pull from buffer */
            Semaphore_post( RTOS_sema_s24_msg_h );
        }
        else if( eventMask & ( RF_EventCmdCancelled | RF_EventCmdAborted | RF_EventCmdStopped ) )
        {
            /* must be a result of RF_cancelCmd() etc */
        }
        else if( eventMask & ( RF_EventCmdDone | RF_EventLastCmdDone ) )
        {
            /* command completed okay */
        }
        else if( eventMask & RF_EventMdmSoft )
        {
            /* sync word received */
        }
        else if( eventMask & RF_EventRxAborted )
        {
            /* packet reception stopped before packet was done */
        }
        else if( eventMask & RF_EventRxNOk )
        {
            /* packet received with CRC error */
        }
        else if( eventMask & RF_EventTxEntryDone )
        {
            /* transmit queue data entry state changed to "finished" */
        }
        else if( eventMask & RF_EventRxBufFull )
        {
            /* packet received that did not fit in the RX queue */
    
            /* this is a bad error, as why shouldn't the received */
            /* packet fit in the buffer....? */
    
    // debug information when buffer is claimed to be full - entries may be displayed in debugger
    rfc_dataEntry_t *entry0 = &rxDataEntryBuffer[0];
    rfc_dataEntry_t *entry1 = entry0->pNextEntry;
    rfc_dataEntry_t *entry2 = entry1->pNextEntry;
    rfc_dataEntry_t *entry3 = entry2->pNextEntry;
    rfc_dataEntry_t *entry4 = entry3->pNextEntry;
    rfc_dataEntry_t *entry5 = entry4->pNextEntry;
    rfc_dataEntry_t *entry6 = entry5->pNextEntry;
    rfc_dataEntry_t *entry7 = entry6->pNextEntry;
    
            Log_add_entry_and_reset( LOG_TYPE_RADIO_CALLBACK_BUFFER_FULL, RF_cmdRX->status );
        }
        else
        {
            /* If we get here, then we have a problem... */
    
            /* log status/error code */
            Log_add_entry_and_reset( LOG_TYPE_RADIO_CALLBACK_UNKNOWN, RF_cmdRX->status );
        }
    }
    

    The task which processes received packets

    while( true )
    {
    
        /* wait for packet received (informed from RX callback) */
        Semaphore_pend( RTOS_sema_s24_msg_h, BIOS_WAIT_FOREVER );
    
        /* suck queue dry */
        while( ( RFQueue_getDataEntry()->status == DATA_ENTRY_FINISHED ) || ( RFQueue_getDataEntry()->status == DATA_ENTRY_UNFINISHED ) )
        {
    
            /* is this packet something we can work with */
            if( RFQueue_getDataEntry()->status == DATA_ENTRY_FINISHED )
            {
    
                /* (very quickly) process packet here */
    
            }
    
            /* move to next buffer entry */
            RFQueue_nextEntry();
        }
    }
    

    Here is an example of early termination of a receive operation


    The trace, “Master Receive” is a timed receive window, and at the end, there is a short (early terminated) receive which triggers a break point when the call back event RF_EventRxBufFull occurs. The “Packet Processing” traces shows packets being processed under a separate task (activated via a counting semaphore).

    Under the same event, debug information was captured showing all 8 radio FIFO queue entries were empty (status = 0).

    Kind regards

  • Hi Gary,

    Could you share the complete RX cmd settings used (as seen in the RF settings file? In addition to this is would be helpful to know where/how you start a new RX operation (seems that there is RX windows without any processing at all).

    Would it also be possible for you to add the output structure to the RX command (pOutput assigned to a rfc_propRxOutput_s object) and share the information from this as well (this include for example nRxStopped and nRxBufFull)?

  • Hi

    Firstly, a quick word about the trace capture of LNA/TX lines. There was meant to be only data on one half of the receive windows, as I didn't have a full compliment of kit at the time. It was also beneficial in that it shows there was not an issue with callback and processing latency, as all previous packets have been processed well before the "buffer full" event, which appeared to occur on reception of a new packet.

    Here is the smartrf settings, as used in the testing. All dead code/structures etc have been removed.

    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(driverlib/rf_mailbox.h)
    #include "rf_hs_mailbox.h"
    #include "rf_hs_cmd.h"
    #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h)
    
    #include <ti/drivers/rf/RF.h>
    #include "smartrf_settings_predefined.h"
    #include "rf_patch_cpe_prop_prepare_fs.h"
    
    
    /******************************************************************************
     * The following comments and table, were generated by SmartRF Studio 2.11.0
     * and then pasted into this header file.
     */
    
    // TX Power table
    // The RF_TxPowerTable_DEFAULT_PA_ENTRY and RF_TxPowerTable_HIGH_PA_ENTRY macro is defined in RF.h.
    // The following arguments are required:
    // RF_TxPowerTable_DEFAULT_PA_ENTRY(bias, gain, boost coefficient)
    // RF_TxPowerTable_HIGH_PA_ENTRY(bias, ibboost, boost, coefficient, ldoTrim)
    // See the Technical Reference Manual for further details about the "txPower" Command field.
    // The PA settings require the CCFG_FORCE_VDDR_HH = 0 unless stated otherwise.
    RF_TxPowerTable_Entry txPowerTable[] =
    {
        {-21, RF_TxPowerTable_DEFAULT_PA_ENTRY( 7, 3, 0,  6) },
        {-18, RF_TxPowerTable_DEFAULT_PA_ENTRY( 9, 3, 0,  6) },
        {-15, RF_TxPowerTable_DEFAULT_PA_ENTRY(11, 3, 0,  6) },
        {-12, RF_TxPowerTable_DEFAULT_PA_ENTRY(11, 1, 0, 10) },
        { -9, RF_TxPowerTable_DEFAULT_PA_ENTRY(14, 1, 1, 12) },
        { -6, RF_TxPowerTable_DEFAULT_PA_ENTRY(18, 1, 1, 14) },
        { -3, RF_TxPowerTable_DEFAULT_PA_ENTRY(24, 1, 1, 18) },
        {  0, RF_TxPowerTable_DEFAULT_PA_ENTRY(33, 1, 1, 24) },
        {  1, RF_TxPowerTable_DEFAULT_PA_ENTRY(20, 0, 0, 33) },
        {  2, RF_TxPowerTable_DEFAULT_PA_ENTRY(24, 0, 0, 39) },
        {  3, RF_TxPowerTable_DEFAULT_PA_ENTRY(28, 0, 0, 45) },
        {  4, RF_TxPowerTable_DEFAULT_PA_ENTRY(36, 0, 1, 73) },
        {  5, RF_TxPowerTable_DEFAULT_PA_ENTRY(48, 0, 1, 73) },
        RF_TxPowerTable_TERMINATION_ENTRY
    };
    
    /*****************************************************************************/
    
    
    
    // TI-RTOS RF Mode Object
    RF_Mode RF_ble5 =
    {
        .rfMode = RF_MODE_PROPRIETARY_2_4,
        .cpePatchFxn = &rf_patch_cpe_prop_prepare_fs,
        .mcePatchFxn = 0,
        .rfePatchFxn = 0
    };
    
    
    
    // new patches and overrides from SmartRF Studio V2.11.0 (hacked - copy-n-pasted here)
    
    // Overrides for CMD_BLE5_RADIO_SETUP
    uint32_t pOverridesCommon[] =
    {
        // override_ble5_setup_override_common.xml
        // Rx: Set LNA IB trim value based on the selected defaultPhy.mainMode setting. (NOTE: The value 0x8 is a placeholder. The value to use should be set during run-time by radio driver function.)
        ADI_HALFREG_OVERRIDE(0,4,0xF,0x8),
        // Rx: Set LNA IB offset used for automatic software compensation to 0
        (uint32_t)0x00008883,
        // Synth: Use 24 MHz crystal, enable extra PLL filtering
        (uint32_t)0x02010403,
        // Synth: Set fine top and bottom code to 127 and 0
        HW_REG_OVERRIDE(0x4020, 0x7F00),
        // Synth: Configure faster calibration
        HW32_ARRAY_OVERRIDE(0x4004, 1),
        // Synth: Configure faster calibration
        (uint32_t)0x1C0C0618,
        // Synth: Configure faster calibration
        (uint32_t)0xC00401A1,
        // Synth: Configure faster calibration
        (uint32_t)0x21010101,
        // Synth: Configure faster calibration
        (uint32_t)0xC0040141,
        // Synth: Configure faster calibration
        (uint32_t)0x00214AD3,
        // Synth: Decrease synth programming time-out by 64 us (0x0300 RAT ticks = 192 us)
        (uint32_t)0x03000243,
        // Bluetooth 5: Set correct total clock accuracy for received AuxPtr assuming local sleep clock of 50 ppm
        (uint32_t)0x0E490823,
        // override_frontend_id.xml
        (uint32_t)0xFFFFFFFF
    };
    
    
    
    // Overrides for CMD_BLE5_RADIO_SETUP
    uint32_t pOverrides1Mbps[] =
    {
        // override_ble5_setup_override_1mbps.xml
        // Rx: Set LNA IB trim to normal trim value. (NOTE: The value 0x8 is a placeholder. The value to use should be set during run-time by radio driver function.)
        ADI_HALFREG_OVERRIDE(0,4,0xF,0x8),
        // Rx: Configure AGC to use gain table for improved performance
        HW_REG_OVERRIDE(0x6084, 0x05F8),
        (uint32_t)0xFFFFFFFF
    };
    
    
    
    // Overrides for CMD_BLE5_RADIO_SETUP
    uint32_t pOverrides2Mbps[] =
    {
        // override_ble5_setup_override_2mbps.xml
        // Rx: Set LNA IB trim to normal trim value. (NOTE: The value 0x8 is a placeholder. The value to use should be set during run-time by radio driver function.)
        ADI_HALFREG_OVERRIDE(0,4,0xF,0x8),
        (uint32_t)0xFFFFFFFF
    };
    
    
    
    // Overrides for CMD_BLE5_RADIO_SETUP
    uint32_t pOverridesCoded[] =
    {
        // override_ble5_setup_override_coded.xml
        // Rx: Set LNA IB trim to 0xF (maximum)
        ADI_HALFREG_OVERRIDE(0,4,0xF,0xF),
        // Rx: Override AGC target gain to improve performance
        HW_REG_OVERRIDE(0x6088, 0x001B),
        (uint32_t)0xFFFFFFFF
    };
    
    
    
    rfc_CMD_BLE5_RADIO_SETUP_t RF_cmdBle5RadioSetup_2mbps =
    {
        .commandNo = 0x1820,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .defaultPhy.mainMode = 0x1,
        .defaultPhy.coding = 0x0,
        .__dummy0 = 0x00,
        .config.frontEndMode = 0x0,
        .config.biasMode = 0x0,
        .config.analogCfgMode = 0x0,
        .config.bNoFsPowerUp = 0x0,
        .txPower = 0x9330,
        .pRegOverrideCommon = pOverridesCommon,
        .pRegOverride1Mbps = pOverrides1Mbps,
        .pRegOverride2Mbps = pOverrides2Mbps,
        .pRegOverrideCoded = pOverridesCoded
    };
    
    
    
    // CMD_TX_HS for R2
    rfc_CMD_HS_TX_t RF_cmdTxR2HS =
    {
        .commandNo = CMD_HS_TX,
        .status = 0x0000,
        .pNextOp = 0x00000000,
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .pktConf.bFsOff = 0x0,
        .pktConf.bUseCrc = 0x1,
        .pktConf.bVarLen = 0x1, //1: Transmit length as first half-word
        .pQueue = 0
    };
    
    
    
    // CMD_RX_HS for R2
    rfc_CMD_HS_RX_t RF_cmdRxR2HS =
    {
        .commandNo = CMD_HS_RX,
        .status = 0x0000,
        .pNextOp = 0x00000000,
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .pktConf.bFsOff = 0,
        .pktConf.bUseCrc = 1,
        .pktConf.bVarLen = 1,
        .pktConf.bRepeatOk = 0, //0: End operation after receiving a packet correctly
        .pktConf.bRepeatNok = 0, //0: End operation after receiving a packet with CRC error
        .pktConf.addressMode = 0,
        .rxConf.bAutoFlushCrcErr = 0,
        .rxConf.bIncludeLen = 1, // If 1, include the received length field in the stored packet; otherwise discard it
        .rxConf.bIncludeCrc = 0,
        .rxConf.bAppendStatus = 0,
        .rxConf.bAppendTimestamp = 0,
        .maxPktLen = 0,
        .address0 = 0,
        .address1 = 0,
        .__dummy0 = 0,
        .endTrigger.triggerType = 1,
        .endTrigger.bEnaCmd = 0,
        .endTrigger.triggerNo = 0,
        .endTrigger.pastTrig = 0,
        .endTime = 0,
        .pQueue = 0,
        .pOutput = 0
    };
    
    
    
    // CMD_FS
    rfc_CMD_FS_t RF_cmdFs_preDef =
    {
        .commandNo = 0x0815,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = COND_NEVER, //Always run next command (except in case of Abort)
        .condition.nSkip = 0x0,
        .frequency = 2405, //Frequency is chosen i tx.c and rx.c
        .fractFreq = 0x0000,
        .synthConf.bTxMode = 0x0,
        .synthConf.refFreq = 0x0,
        .__dummy0 = 0x00,
        .__dummy1 = 0x00,
        .__dummy2 = 0x00,
        .__dummy3 = 0x0000
    };
    
    
    
    extern RF_Mode RF_ble5;
    extern rfc_CMD_BLE5_RADIO_SETUP_t RF_cmdBle5RadioSetup_2mbps;
    RF_Mode *RF_mode = &RF_ble5;
    rfc_CMD_BLE5_RADIO_SETUP_t *RF_cmdSetup = &RF_cmdBle5RadioSetup_2mbps;
    rfc_CMD_FS_t *RF_cmdFrequency = &RF_cmdFs_preDef;
    rfc_CMD_HS_TX_t *RF_cmdTX = &RF_cmdTxR2HS;
    rfc_CMD_HS_RX_t *RF_cmdRX = &RF_cmdRxR2HS;
    

    Also, some in-code changes are made  some some structures :

        /* set up transmit structure(s) */
        RF_cmdTX->pQueue = &txDataQueue;
    
        /* set up receive structure(s) */
        RF_cmdRX->pOutput = &rxStatistics_R2hs;
        RF_cmdRX->pQueue = &rxDataQueue;
        RF_cmdRX->maxPktLen = MAX_LENGTH;
        RF_cmdRX->pktConf.bRepeatOk = 1;
        RF_cmdRX->pktConf.bRepeatNok = 1;
        RF_cmdRX->pktConf.addressMode = 1;
        RF_cmdRX->rxConf.bAutoFlushCrcErr = 1;
        RF_cmdRX->rxConf.bAppendTimestamp = 1;
        RF_cmdRX->rxConf.bAppendStatus = 1;
    
        /* select the subnet to filter (sets address0/address1 fields) */
        Radio_update_hw_filters( GetMasterId(), NET_MAN_SUBNET_ID );
    

    The "receive statistics" structure, on capturing a "buffer full" event is :

    If there is anything else you need to isolate this problem, please just ask.

    Kind regards#

  • Thanks Gary,

    Checking around internally, it seems like this should be related simply to the data entry size, what size are you using exactly? A colleague of mine recently discovered that there is an extra byte being appended on the length byte (we are still looking into if this is excepted or not), can you try to account for one or two bytes more in your buffers and see if that changes anything?

  • Hi Max

    I did consider something like this, as mentioned in an earlier post in this thread. I could (and did) program defensively against a rogue size up to 255 bytes by increasing buffer entries to ~270bytes each. This didn't cure the problem. But anyway, if we have an instance of 16bit size, as alluded to in your last post, then there is nothing I can do as there isn't enough memory for 64KBytes per buffer entry to cover all eventualities...

    My current setting for transmitting a packet is "bVarLen = 1" which says, "Transmit length as first half-word". Is a "word" 16 or 32bits, resulting 8 or 16bits result? All references to "bVarLen" in TRM refer to 1 byte for size.

    In the packets I receive, the length is at offset 0, and the payload from offset 2. Offset 1 generally contains a zero, so could be an extension of the size byte to 16bits.

    Could this be an issue of using the HS TX and RX commands instead of the normal TX and RX (which are too slow for our purposes)?

    Kind regards

  • Hi again Max

    If this is a case of a corrupted length byte (or bytes if 16bit), indicating a packet is larger than it actually is, so not being the space in a buffer entry (TRM alludes to these being the actual raw receive buffers, before CRC checks are made etc); could the "buffer full" event not stop the receive command?

    We can not simply restart a receive, as we have large linked chains of commands of which receive commands are only part.

    Kind regards

  • Hi Gary,

    I will need to get back to you on this early next week as I need to wait for a colleague to get back from vacation. From what I can tell, the HS commandos you are using has half-words length fields which would be 16-bits. I would however expect that the reception would restart if the package length is larger then the specified "maxPktLen". 

    I can see that you set it to "MAX_LENGTH", is this the same length as the the buffers you define for the packets? If that is the case, could you try to set it to "MAX_LENGTH - 10" (or something less then the actual packet size) too see if this makes a difference. I do not think this check takes the optional appended data into account.

    I do not think there is a way to make the "buffer full" not cause a stop event but again I would need to get back to you on this next week.

  • Hi Max

    I have performed some other varied testing, with some good (but not guaranteed) results. Just by upping the buffer size appears to improve reliability. It run for 3.5 days with no "buffer full". This however, as I am sure you can appreciate, is not a solution as there is no explanation why this behaved. :-(

    Also, deliberately reducing the buffer size to ensure it was too small did not result in "buffer full", as you implied/expected. It would be nice to know what is happening, why, and how to stop it...

    I look forward from some input from your colleague :-)

    Kind regards

  • Hi Garry,

    "buffer full" in this case would only really apply to one specific scenario which is that the packet payload (not including any header, length fields or other appended data) is within the "maxLen" value but the buffer size is not large enough to handle maxLen + appended bytes.

    In this case there is a few things to consider with the HS when setting the "maxLen" and actual buffer size. For example buffer size should to be maxLen + length of appended data (such as 2 bytes for length field etc) + 1 byte if maxLen is odd. The last one is due to the padding done by the radio in order to facilitate the HS commands as it work on half-words only in this mode. 

    This would mean that if you set maxLen to 255 and expect length to be appended, the buffers need to be 256 + 2 in order to receive the packet. If the buffer would also be 255 (buffer == maxLen) then a TX of 255 would be filtered out (as it is larger then the maxLen due to padding) and a packet of length 254 would case a "buffer full" as 254 + 2 lengthbytes = 256 (it passes the maxLen test but fails to fit into the buffer).

    Hope this is somewhat clarifying for your use case. You would need to make sure that maxLen != buffer length and that the buffer length is large enough to fit both the maxLen + appended bytes as these are not taken into account in the length check in the radio. Also note that maxLen should be EVEN in your application due to the padding, so if you expect up 255 bytes in your application, it need to be set to at least 256.

  • Hi Max

    We had come across the 16bit alignment (or blocking) by accident some months back so knew about that :-)

    We did however have an issue, as maxPktLen within the RX command was correct, the size of each entry in the radio queue did not take into account all the prepended and appended data (size, status and timestamp). Once we had made this change, it never appeared to go wrong any more :-)

    However, a colleague has reported that the issue has occurred again, so investigating if this is the same problem or something different.

    Kind regards

  • Hi Gary,

    Alright :) As for now, this is the only explanation I can give you so if you find that the issue you colleague is seeing is not the exact same issue please let us know!

  • Hi Max

    I am happy with the solution; so until I can replicate what my colleague is seeing, I am marking this thread as resolved :-)

    Kind regards