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.

CC1310: Retrieving RSSI from RF core

Part Number: CC1310

Hi,

I have investigated further regarding the locked thread that has the same title as this one and, although I still cannot reproduce the success that Siri has (even though she used my own settings), I have reproduced her suggested code flow and have more information to hopefully help you determine what is going on with my setup.

When posting the RF Rx command to the RF core, I can see, as Siri did, that the RSSI is at first invalid (-128). However, approx. 1.5ms later, valid RSSI values start being reported. When the other radio is transmitting, the reported RSSI values "jump" up to e.g. 80dBm, as I'd expect. The problem that I still have is that immediately that the call-back is entered, the reported RSSI values return to invalid (-128).

My suspicion is that this is because I only post a single RF Rx command - the RF Queue is otherwise empty as I do not know when the next transmission will be, whether it will be Rx or Tx or how long that transmission might be. When the call-back occurs, I see IRQ_RX_ENTRY_DONE and IRQ_LAST_COMMAND_DONE in the same call-back call.

  1. Could it be that the empty queue causes the RF core to perform garbage collection?
  2. If this is the case, can you recommend a simple workaround - i.e. one that preferably does not require me to add and then subsequently flush "dummy" commands to the RF core to prevent it from discarding data
  3. Regardless of the cause, why is it that RF_cmdRxHS.pOutput.lastRssi has a value of zero? I would expect this to always be populated before any garbage collection was done in the RF core.

Please see the attached image for more information.

TIA,

Sean.

  • Hi Sean,

    Related to the other thread I answered to, have you tried appending the RSSI to the packet with bAppendRssi? Is it even an option in your application?

    Let me know if that could work for you.

    Regards,

    Arthur

  • Hi Arthur,

    Many thanks for such a speedy response.

    rfc_CMD_HS_RX_s (see .\simplelink_cc13x0_sdk_4_20_02_07\source\ti\devices\cc13x0\driverlib\rf_hs_cmd.h) does not offer the bAppendRssi member, unfortunately, so that is not an option.

    TIA,

    Sean.

  • Hi Sean,

    My mistake.

    However, it seems like the rssi is automatically added to the content of rfc_CMD_HS_RX_s's status field, and you can decode it using the following structure: http://downloads.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/tirtos/2_20_01_08/exports/tirtos_full_2_20_01_08/products/cc13xxware_2_04_02_17240/doc/driverlib/structrfc__hs_rx_status__s.html

    Regards,

    Arthur

  • Hi Arthur,

    Thanks again for getting back to me so soon.

    Unfortunately, the status field is not automatically added to the rfc_CMD_HS_RX_s structure. For this, you need to use bAppendStatus, which isn't working for me. See https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1269597/cc1310-bappendstatus-for-rfc_cmd_hs_rx_s/4808697#4808697, which you have commented on.

    It appears that the only way to resolve this issue is to first resolve the other one (in the link mentioned), which I'll work on today and report back to you.

    Regards,

    Sean.

  • Hi Arthur,

    having now resolved the bAppendStatus issue of https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1269597/cc1310-bappendstatus-for-rfc_cmd_hs_rx_s/4808697#4808697, the RF core reports that an extra two bytes are returned with the received data. However, when I inspect these bytes, they are both 0x00. Please see the attached image, which explains.

    This is consistent with all other discoveries I've made, noted above; RF_cmdRxHS.pOutput.lastRssi always reads 0x00 and RF_getRssi() returns valid values only while a reception is underway, reverting to -128 as soon as the callback is entered.

    I am seeing a consistent picture, regardless of which method I use to retrieve the RSSI.

    TIA,

    Sean.

  • Hi Arthur,

    Please see the following attached image, which shows more of this behaviour, but with bAppendTimestamp and RF_cmdRxHS.pOutput.timeStamp also (i.e. NUM_APPENDED_BYTES = 6), which can be seen working correctly.

    The issue I'm seeing is exclusively with RSSI.

    A couple of ideas:

    1. I am using DATA_ENTRY_TYPE_PTR - is this relevant? I cannot use any other data type.
    2. If overrides are relevant, please see another recent post of mine, which details all of my settings: e2e.ti.com/.../4808311

    TIA,

    Sean.

  • Hi Arthur,

    I've investigated further with this today with some success but I need you to explain why I'm seeing what I am, please.

    I decided to experiment with bUseCrc and ultimately discovered that rfc_hsRxStatus_s does get appended to my data (so I now see good RSSI bytes) but not immediately after, as I'd expect it to. In reality, I see two NULL bytes after my payload (as you can see from the images I attached earlier), which is only then followed by the appended bytes that I asked for.

    1. Why do these NULL bytes appear at the end of my data?
    2. Will they always be there or will they be absent under certain conditions?
    3. I have bAppendStatus, bIncludeCrc and bAppendTimeStamp. Where is it documented in which order these will appear after my payload?
    4. For the settings noted in question 3, I originally set NUM_APPENDED_BYTES to 2 (status) + 4 (timestamp) + 2 (CRC) = 8 but this failed, resulting in RF_cmdRxHS.pOutput->nRxBufFull. I couldn't find any documentation on the CRC size for rfc_CMD_HS_RX_s so I thought it may be a 32-bit CRC and so set NUM_APPENDED_BYTES to 2 (status) + 4 (timestamp) + 4 (CRC) = 10. Perversely, everything then worked, yet I've discovered that the CRC really is a 16-bit CRC. What is happening here?
    5. Apologies for contaminating this thread with another topic but over what data is the CRC calculated for RF_cmdRxHS? I have a data stream of 44048300000000000001FEFEFEFEFE80 (in Hex, not ASCII) and the 2-bytes I see as a result of bIncludeCrc are 0x193E. Can you explain this, please, as my calculations don't agree with this? Are the reported appended CRC bytes those that the receiving RF core calculated on receipt of the corrupt packet or those of the transmitting RF core on transmission of the correct packet? Is the CRC calculated over just the dataEntry payload or also e.g. Sync Word, Preamble, etc.?

    TIA,

    Sean.

  • Hi Sean,

    As you might have noticed, the High-Speed mode is not well documented, so it will take me some time to come up with all those answers, but I will come back to you on that tomorrow.

    But as of now, I do have an answer to questions three and four, the order seems to be as follows:

    1. CRC (4 bytes)
    2. status (2 bytes)
    3. timestamp (4 bytes)

    Why do you think the CRC might be actually 16 bits, could you show me an example?

    Regards,

    Arthur

  • Hi Arthur,

    Thanks for pursuing this.

    There are two reasons that I believe the CRC is 16-bit; one is an assumption, the other is evidence-based:

    1. (assumption) - the only discussion of CRCs that I am aware of is this, which talks about 16-bit and 8-bit CRCs (but not 32-bit): https://software-dl.ti.com/simplelink/esd/simplelink_cc13x0_sdk/4.10.02.04/exports/docs/proprietary-rf/proprietary-rf-users-guide/proprietary-rf/packet-format.html
    2. (evidence) - when I "print" (via a digital scope) the values of the appended bytes that I requested (status, CRC, timestamp), I can account for everything except the leading pair of NULL bytes if I consider the CRC to be 16-bit. That is to say:
      1. One byte linearly tracks the true RSSI as I add and remove attenuation in the RF path
      2. Its neighbouring byte is set to 0x01 when a CRC error occurs (i.e. bCrcErr is set)
      3. TWO (not four) bytes appear to be random numbers with each reception (where different payload data is being sent) - i.e. consistent with a CRC.
      4. 4 bytes, when considered as a complete unit, increase in value linearly over time (i.e. timestamp behaviour)
      5. The attached image explains this best.

    Note that the two NULL bytes are present even without setting bUseCrc and bIncludeCrc, so it cannot be the case that e.g. the CRC is a 4-byte field but only getting two of its bytes populated - it really does appear that the CRC is a 2-byte field.

    Regards,

    Sean.

  • Hi Sean,

    I see.. it does not seem to match with the implementation so I will have to verify that.

    The HS_CMD does have its own packet format, so it does not follow the one you shared.

    I will come back to you next week on that.

    In the mean time, do you have the option to increase the rxEntry packet and try to check for any trailing bytes that might make sense?

    Regards,

    Arthur

  • Hi Sean,

    I did get to verify that the CRC seems to be show as a 16 bit one, and that the offset seems to vary according to the bVarLen configuration.

    I do not have a definitive explanation yet though, but I am thinking it has to do with the total length of the appended bits.

    Hopefully, we will get to the bottom of this soon.

    Regards,

    Arthur

  • Hi Arthur,

    Thanks for continuing with this.

    I increased NUM_APPENDED_BYTES (as you requested) by 4 and "printed" those out - I only see 4 trailing NULL bytes, so it looks like the RF core really is using a 16-bit CRC (which you've now confirmed - thanks) - there is no "hidden" trailing data that I was failing to access. Please see attached, the only remaining mystery of which is those 2 NULL bytes sandwiched between the end of the user payload and the requested appended bytes.

    I wondered if the NULL bytes were the result of the RF core padding its output to the nearest 4-byte boundary, which is evidently critical, as the following necessary code from all TI examples suggests:

    #define RF_QUEUE_QUEUE_ALIGN_PADDING(length)  ((4 - (length % 4)) % 4) // Padding offset

    which is then used to define the dimensions of the RF Data Entry Queue:

    #define RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(numEntries, dataSize, appendedBytes)                                                    \
    (numEntries*(RF_QUEUE_DATA_ENTRY_HEADER_SIZE + /* dataSize + */ appendedBytes + RF_QUEUE_QUEUE_ALIGN_PADDING(RF_QUEUE_DATA_ENTRY_HEADER_SIZE + /* dataSize + */ appendedBytes)))

    The reason that I had not, until now, considered this to be relevant is that I am using DATA_ENTRY_TYPE_PTR, so the data payload itself does not reside in memory with the RF Data Entry Queue - my assumption being that it is only the latter that requires careful 4-byte boundary alignment. Is this assumption wrong?

    Just to summarise what I need help with:

    1. An explanation for the two NULL bytes
    2. Knowledge of the CRC polynomial, seed, XORing and bytes over which it is calculated, ideally with an example (the data packet I noted in an earlier post would be perfect)

    TIA,

    Sean.

  • Hi Sean,

    If need be, we can actually configure the CRC to be 32 bits. I think there might have been a mixup in the settings you have been provided at some point.

    Before I go on to figure out the CRC settings, could you please confirm that the packet you want me to check with the following?

    uint8_t hsm_packet[] = {0x44, 0x04, 0x83, 0x00,
                             0x00, 0x00, 0x00, 0x00,
                             0x00, 0x01, 0xFE, 0xFE,
                             0xFE, 0xFE, 0xFE, 0x80};

    Regards,

    Arthur

  • I have not read through all the posts here, but wanted to mention a couple of things.

    The general high speed mode (1.5 mbps) uses the normal prop API, not the HSM API. This is for the 4 Mbps settings.

    When reading the RSSI (received signal strength) the radio must be in Active mode. Reading the RSSI in the callback means that you are trying to read the RSSI when the radio is NOT in RX, hence the value is invalid.

    Siri

  • Hi Arthur,

    Thanks for confirming. Yes, this is the user payload I'd like an example for.

    If my CC1310 is configurable for 32-bit CRC, that would be ideal, since it would considerably reduce the possibility of false-positives slipping through.

    TIA,

    Sean.

  • Hi Siri,

    Thanks for the information. This aligns with the example you sent me, which I discovered returned valid RSSI values until the callback, as you say. However, why is it that rfc_CMD_HS_RX_s.pOutput.lastRssi is always invalid (or zero, I cannot remember) - surely that should get populated during the RX active period that resulted in the population of all the other rfc_hsRxOutput_s fields? Something is still awry.

    Also, I can see how Arthur has gotten confused, if that is the case - rfc_hsRxOutput_s is defined within rf_hs_cmd.h; it would be easy to confuse "hs" for HSM, which I often have to remind myself are not the same thing.

    Thanks again for your guidance,

    Sean.

  • Hi Clark

    There are so many references to different posts here so I am still confused as to what you are actually trying to do and where you see problems.

    Is it the RSSI when using the 1.5 Mbps PHY that is the issue? 

    Which API are you using?

    Siri

  • Just to verify that the RSSI is OK I tested this with both the 1.5 mbps ghs PHY and with the 4 mbps PHY.

    I used the HS API for both tests. I Think it is OK to use the standard PROP API together with 1.5 mbps, but I used hte same API for both.

    Settings and code below:

    Settings:

    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(driverlib/rf_mailbox.h)
    #include DeviceFamily_constructPath(driverlib/rf_hs_mailbox.h)
    #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h)
    #include DeviceFamily_constructPath(driverlib/rf_hs_cmd.h)
    #include <ti/drivers/rf/RF.h>
    #include DeviceFamily_constructPath(rf_patches/rf_patch_mce_hsp_4mbps.h)
    #include DeviceFamily_constructPath(rf_patches/rf_patch_rfe_hsp_4mbps.h)
    #include DeviceFamily_constructPath(rf_patches/rf_patch_mce_ghs.h)
    #include DeviceFamily_constructPath(rf_patches/rf_patch_rfe_ghs.h)
    #include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_ghs.h)
    #include "smartrf_settings.h"
    
    RF_Mode RF_prop_hsp_4mbps =
    {
        .rfMode = RF_MODE_PROPRIETARY_SUB_1,
        .cpePatchFxn =  0,
        .mcePatchFxn =  &rf_patch_mce_hsp_4mbps,
        .rfePatchFxn =  &rf_patch_rfe_hsp_4mbps,
    };
    
    RF_Mode RF_prop_ghs =
    {
         .rfMode       =  RF_MODE_PROPRIETARY_SUB_1,
         .cpePatchFxn  =  &rf_patch_cpe_ghs,
         .mcePatchFxn  =  &rf_patch_mce_ghs,
         .rfePatchFxn  =  &rf_patch_rfe_ghs,
    };
    
    // Overrides for CMD_RADIO_SETUP
    uint32_t shapeovr[] = {0x00000000, 0x00000000, 0x00000000, 0x12010000, 0x72685C43, 0x8986817A};
    
    uint32_t pOverrides_hsp_4mbps[] =
    {
         MCE_RFE_OVERRIDE(1,0,0,1,0,0),
         ADI_HALFREG_OVERRIDE(0,61,0xF,0x0),
         ADI_REG_OVERRIDE(1,4,0x9F),
         ADI_HALFREG_OVERRIDE(1,7,0x4,0x4),
         HW_REG_OVERRIDE(0x4038,0x003A),
         HW_REG_OVERRIDE(0x4020,0x7F00),
         HW_REG_OVERRIDE(0x4064,0x0040),
         0x000604A3,
         0xB1070503,
         0x05330523,
         0x0A480583,
         0x7AB80603,
         0x00108463,
         0x02010403,
         0x04B00243,
         0x00038883,
         0xC0040031,
         (uint32_t) &shapeovr[0],
         0xC0040021,
         (uint32_t) (0x00000035),
         0x000388A3,
         HW_REG_OVERRIDE(0x50B4,0x6666),
         HW_REG_OVERRIDE(0x50B8,0x000C),
         (uint32_t)0xFFFFFFFF,
    };
    
    // Overrides for CMD_PROP_RADIO_DIV_SETUP
    uint32_t pOverrides_ghs[] =
    {
        // PHY: Use MCE RAM patch, RFE RAM patch
        MCE_RFE_OVERRIDE(1, 0, 0, 1, 0, 0),
        // Rx: Set anti-aliasing filter bandwidth to Maximum
        ADI_HALFREG_OVERRIDE(0,61,0xF,0x0),
        // Synth: Set recommended RTRIM to 7
        HW_REG_OVERRIDE(0x4038,0x0037),
        // Synth: Configure fine calibration setting
        HW_REG_OVERRIDE(0x4020,0x7F00),
        // Synth: Configure fine calibration setting
        HW_REG_OVERRIDE(0x4064,0x0040),
        // Synth: Set Fref to 4 MHz
        (uint32_t)0x000684A3,
        // Synth: Configure fine calibration setting
        (uint32_t)0xC0040141,
        (uint32_t)0x0533B107,
        // Synth: Set loop bandwidth after lock
        (uint32_t)0xA480583,
        (uint32_t)0x7AB80603,
        // Synth: Configure VCO LDO (in ADI1, set VCOLDOCFG=0x9F to use voltage input reference)
        ADI_REG_OVERRIDE(1,4,0x9F),
        // Synth: Configure synth LDO (in ADI1, set SLDOCTL0.COMP_CAP=1)
        ADI_HALFREG_OVERRIDE(1,7,0x4,0x4),
        // Rx: Set LNA bias current trim offset to 3
        (uint32_t)0x00038883,
        // Rx: Set RSSI offset to adjust reported RSSI
        (uint32_t)0x00FB88A3,
        // Synth: Use 24 MHz XOSC as synth clock, enable extra PLL filtering
        (uint32_t)0x02010403,
        // Synth: Configure extra PLL filtering
        (uint32_t)0x00108463,
        // Synth: Increase synth programming timeout (0x04B0 RAT ticks = 300 us)
        (uint32_t)0x04B00243,
        //Configure thershold for Sync word detection
        HW_REG_OVERRIDE(0x5104,0x302B),
        //Set FIFO threshold
        (uint32_t) 0x002C82C3,
        (uint32_t) 0x002882D3,
        // Rx: Do not freeze RSSI on sync found event
        HW_REG_OVERRIDE(0x6084,0x25F1),
        // ****PA Ramping overrides
        HW_REG_OVERRIDE(0x6088,0x4121),
        HW_REG_OVERRIDE(0x608C,0x0A12),
        // ****Length of CW tone
        HW_REG_OVERRIDE(0x52B0,0x00F0),
        // DC estimation
        HW_REG_OVERRIDE(0x51F8,0x0F90),
        //Zero IF in TX
        (uint32_t) 0x00000343,
        // TX power override
        // Tx: Set PA trim to max (in ADI0, set PACTL0=0xF8)
        ADI_REG_OVERRIDE(0,12,0xF8),
        // End Override
        (uint32_t)0xFFFFFFFF,
    };
    
    // CMD_RADIO_SETUP
    rfc_CMD_RADIO_SETUP_t RF_cmdRadioSetup_hsp_4mbps =
    {
         .commandNo = CMD_RADIO_SETUP,
         .status = 0x0000,
         .pNextOp = 0x00000000,
         .startTime = 0x00000000,
         .startTrigger.triggerType = 0x0,
         .startTrigger.bEnaCmd = 0x0,
         .startTrigger.triggerNo = 0x0,
         .startTrigger.pastTrig = 0x0,
         .condition.rule = 0x1,
         .condition.nSkip = 0x0,
         .mode = 0x05,
         .loDivider = 5,
         .config.frontEndMode = 0x0,
         .config.biasMode = 0x1,
         .config.bNoFsPowerUp = 0,
         .txPower = 0x23F,
        .pRegOverride = pOverrides_hsp_4mbps,
    };
    
    // CMD_PROP_RADIO_DIV_SETUP
    rfc_CMD_PROP_RADIO_DIV_SETUP_t RF_cmdPropRadioDivSetup_ghs =
    {
        .commandNo = 0x3807,
        .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,
        .modulation.modType = 0x1,
        .modulation.deviation = 600,
        .symbolRate.preScale = 8,
        .symbolRate.rateWord = 262144,
        .rxBw = 48,
        .preamConf.nPreamBytes = 0x6,
        .preamConf.preamMode = 0x1,
        .formatConf.nSwBits = 0x20,
        .formatConf.bBitReversal = 0x0,
        .formatConf.bMsbFirst = 0x1,
        .formatConf.fecMode = 9,
        .formatConf.whitenMode = 0x0,
        .config.frontEndMode = 0x0,
        .config.biasMode = 0x1,
        .config.bNoFsPowerUp = 0x0,
        .txPower = 0xA63F,
        .pRegOverride = pOverrides_ghs,
        .centerFreq = 0x0364,
        .intFreq = 0x8000,
        .loDivider = 0x05,
    };
    
    // CMD_FS
    rfc_CMD_FS_t RF_cmdFs =
    {
        .commandNo = 0x0803,
        .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,
        .frequency = 0x0364,
        .fractFreq = 0x0000,
        .synthConf.bTxMode = 0x0,
        .synthConf.refFreq = 0x0,
        .__dummy0 = 0x00,
        .__dummy1 = 0x00,
        .__dummy2 = 0x00,
        .__dummy3 = 0x0000,
    };
    
    // CMD_RX_HS
    rfc_CMD_HS_RX_t RF_cmdRxHS =
    {
        .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,
        .pktConf.bRepeatNok = 0,
        .pktConf.addressMode = 0,
        .rxConf.bAutoFlushCrcErr = 0,
        .rxConf.bIncludeLen = 1,
        .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_TX_HS
    rfc_CMD_HS_TX_t RF_cmdTxHS =
    {
         .commandNo = 0x3841,
         .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,
         .pQueue = 0,
    };
    

    TX Code:

    /*
     * Copyright (c) 2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    #include <unistd.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "Board.h"
    #include "smartrf_settings/smartrf_settings.h"
    
    #include "RFQueue.h"
    
    /***** Defines *****/
    
    
    /* Packet TX Configuration */
    #define PAYLOAD_LENGTH          300
    #define DATA_ENTRY_HEADER_SIZE  8               // Constant header size of a Generic Data Entry
    #define MAX_LENGTH              PAYLOAD_LENGTH  // Set the length of the data entry
    #define NUM_DATA_ENTRIES_TX     1
    #define NUM_APPENDED_BYTES_TX   0
    #define NUMBER_OF_PACKETS       5
    
    /***** Prototypes *****/
    
    /***** Variable declarations *****/
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;
    
    static uint8_t *pPacket;
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (txDataEntryBuffer, 4);
    static uint8_t
    txDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES_TX,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES_TX)];
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    static uint8_t
    txDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES_TX,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES_TX)];
    #elif defined(__GNUC__)
    static uint8_t
    txDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES_TX,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES_TX)]
                                                      __attribute__((aligned(4)));
    #else
    #error This compiler is not supported.
    #endif
    
    static dataQueue_t dataQueue;
    static rfc_dataEntryGeneral_t* currentDataEntry;
    static uint16_t packetCounter = 0;
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] =
    {
        Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };
    
    /***** Function definitions *****/
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, pinTable);
        if (ledPinHandle == NULL)
        {
            while(1);
        }
    
    
        if( RFQueue_defineQueue(&dataQueue,
                                    txDataEntryBuffer,
                                    sizeof(txDataEntryBuffer),
                                    NUM_DATA_ENTRIES_TX,
                                    MAX_LENGTH + NUM_APPENDED_BYTES_TX))
        {
            /* Failed to allocate space for all data entries */
            while(true);
        }
    
        RF_cmdTxHS.pQueue = &dataQueue;
        RF_cmdTxHS.startTrigger.triggerType = TRIG_NOW;
    
        currentDataEntry = (rfc_dataEntryGeneral_t*)&txDataEntryBuffer;
        currentDataEntry->length = PAYLOAD_LENGTH;
        pPacket = &currentDataEntry->data;
    
        /* Generate the packet */
        uint16_t i;
        for (i = 0; i < PAYLOAD_LENGTH; i++)
        {
            pPacket[i] = (uint8_t)(i + 1);
        }
    
        // 1.5 mbps
        rfHandle = RF_open(&rfObject, &RF_prop_ghs, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup_ghs, &rfParams);
        
        // 4 mbps
        // rfHandle = RF_open(&rfObject, &RF_prop_hsp_4mbps, (RF_RadioSetup*)&RF_cmdRadioSetup_hsp_4mbps, &rfParams);
    
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        while(1)
        {
            while(packetCounter++ < NUMBER_OF_PACKETS)
            {
                PIN_setOutputValue(ledPinHandle, Board_PIN_LED1,1);
                RF_runCmd(rfHandle, (RF_Op*)&RF_cmdTxHS, RF_PriorityNormal, NULL, 0);
                PIN_setOutputValue(ledPinHandle, Board_PIN_LED1,0);
            }
            usleep(500000);
            packetCounter = 0;
        }
    }
    
    

    RX Code:

    /*
     * Copyright (c) 2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "Board.h"
    
    /* Application Header files */
    #include "RFQueue.h"
    #include "smartrf_settings/smartrf_settings.h"
    
    /***** Defines *****/
    
    /* Packet RX Configuration */
    #define DATA_ENTRY_HEADER_SIZE  8   /* Constant header size of a Generic Data Entry */
    #define MAX_LENGTH              300 /* Max length byte the radio will accept */
    #define NUM_DATA_ENTRIES        2   /* NOTE: Only two data entries supported at the moment */
    #define NUM_APPENDED_BYTES      8   /* RF_cmdRxHS.rxConf.bIncludeLen = 1
                                         * RF_cmdRxHS.rxConf.bAppendStatus = 1;
                                         * RF_cmdRxHS.rxConf.bAppendTimestamp = 1; */
    #define LENGTH_BYTE_SIZE        2
    
    
    /***** Prototypes *****/
    static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    /***** Variable declarations *****/
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;
    
    /* Buffer which contains all Data Entries for receiving data.
     * Pragmas are needed to make sure this buffer is 4 byte aligned (requirement from the RF Core) */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuffer, 4);
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)];
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)];
    #elif defined(__GNUC__)
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)]
                                                      __attribute__((aligned(4)));
    #else
    #error This compiler is not supported.
    #endif
    
    /* Receive dataQueue for RF Core to fill in data */
    static dataQueue_t dataQueue;
    static rfc_dataEntryGeneral_t* currentDataEntry;
    static uint16_t packetLength;
    static uint8_t* packetDataPointer;
    static rfc_hsRxOutput_t rxStatistics;
    
    
    static uint8_t packet[MAX_LENGTH + NUM_APPENDED_BYTES - LENGTH_BYTE_SIZE]; /* The length info (2 bytes) is stored in a separate variable */
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] =
    {
        Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    	PIN_TERMINATE
    };
    
    /***** Function definitions *****/
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, pinTable);
        if (ledPinHandle == NULL)
        {
            while(1);
        }
    
        if( RFQueue_defineQueue(&dataQueue,
                                rxDataEntryBuffer,
                                sizeof(rxDataEntryBuffer),
                                NUM_DATA_ENTRIES,
                                MAX_LENGTH + NUM_APPENDED_BYTES))
        {
            /* Failed to allocate space for all data entries */
            while(1);
        }
    
        RF_cmdRxHS.pOutput = &rxStatistics;
        RF_cmdRxHS.pQueue = &dataQueue;
        RF_cmdRxHS.rxConf.bAutoFlushCrcErr = 1;
        RF_cmdRxHS.maxPktLen = MAX_LENGTH;
        RF_cmdRxHS.pktConf.bRepeatOk = 0;
        RF_cmdRxHS.pktConf.bRepeatNok = 0;
    
        // Appended bytes
        RF_cmdRxHS.rxConf.bIncludeLen = 1;      // 2 bytes
        RF_cmdRxHS.rxConf.bIncludeCrc = 0;
        RF_cmdRxHS.rxConf.bAppendStatus = 1;    // 2 bytes appended
        RF_cmdRxHS.rxConf.bAppendTimestamp = 1; // 4 bytes appended
    
        // 1.5 mbps
        rfHandle = RF_open(&rfObject, &RF_prop_ghs, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup_ghs, &rfParams);
            
        // 4 mbps
        // rfHandle = RF_open(&rfObject, &RF_prop_hsp_4mbps, (RF_RadioSetup*)&RF_cmdRadioSetup_hsp_4mbps, &rfParams);
    
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        while(1)
        {
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdRxHS, RF_PriorityNormal, &callback, RF_EventRxEntryDone);
        }
    }
    
    void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        if (e & RF_EventRxEntryDone)
        {
            /* Toggle pin to indicate RX */
            PIN_setOutputValue(ledPinHandle, Board_PIN_LED2, !PIN_getOutputValue(Board_PIN_LED2));
    
            /* Get current unhandled data entry */
            currentDataEntry = RFQueue_getDataEntry();
    
            /* Handle the packet data, located at &currentDataEntry->data */
            packetLength      = ((*(uint8_t*)(&currentDataEntry->data + 1)) << 8) |  (*(uint8_t*)(&currentDataEntry->data));
            packetDataPointer = (uint8_t*)(&currentDataEntry->data + 2);
    
            /* Copy the payload + optional status byte to the packet variable */
            memcpy(packet, packetDataPointer, (packetLength + NUM_APPENDED_BYTES - LENGTH_BYTE_SIZE));
    
            RFQueue_nextEntry();
        }
    }
    

    Note that on in RX, I have turned off the repeat mode to avoid running into problems when setting breakpoint in the callback to monitor the packet:

    at the end of the packet, a 2 byte long status byte and a 4 byte long timestamp is appended.

    the first byte in the status byte is the RSSI.

    As you can see, the RSSI and timestamp appended is equal to the statistics received with that packet.

    Siri

  • Hi Siri,

    Sorry for the confusion.

    My original issue was that rfc_CMD_HS_RX_s.pOutput.lastRssi was always reading 0x00. I then tried to access rfc_hsRxStatus_s.rssi but the only way to access this is via bAppendStatus. I then discovered that bAppendStatus was not working, until I set NUM_APPENDED_BYTES to 4 (when 2 should have been the correct value for the 2-byte rfc_hsRxStatus_s field). Having done this, I now see the two status bytes, which includes a good/reasonable RSSI value, but they are preceded by two NULL bytes for some reason (see previous attachments).

    Regardless of all the things I've tried and encountered, I do not understand how rfc_CMD_HS_RX_s.pOutput.lastRssi can ever be 0x00 or 0x80 (i.e. -128; INVALID). Surely, when the RF core receives data over the air, it sets lastRssi to some valid value and only ever changes that field when the next reception occurs, which will be another valid value. Is this not the case?

    TIA,

    Sean.

  • Thanks for running your checks, Siri. I have the same API and PHY as you:

    rfc_CMD_PROP_RADIO_DIV_SETUP_t TempSetupDiv;
    
    // TI-RTOS RF Mode Object (includes patches for high speed operation)
    // https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz/f/156/p/628551/2363574#2363574
    static const RF_Mode RfSettings_RF_prop_hs_4fsk =
    {
    .rfMode = RF_MODE_PROPRIETARY_SUB_1,
    .cpePatchFxn = &rf_patch_cpe_ghs,
    .mcePatchFxn = &rf_patch_mce_ghs,
    .rfePatchFxn = &rf_patch_rfe_ghs,
    };
    
    static RF_Mode RfMode;
    
    static const RfSettings_PhyMode_Map_t PhyModeMap[] = {
        { // 1.5Mbps
            .phyMode = VOLSHARE_REGMAP_PHY_900M_750KSYM_4FSK,
            .setup = &Cc1310_Rf900vol_PHY_900M_750KSYM_4fsk_g,
            .rfMode = &RfSettings_RF_prop_hs_4fsk
        },
    }
    
    phyMode = VOLSHARE_REGMAP_PHY_900M_750KSYM_4FSK;
    
    setupRom = NULL;
    for(map = PhyModeMap; map->phyMode != PHYMODE_INVALID; map++)
    {
        if(map->phyMode == phyMode)
        {
            setupRom = (void*)(map->setup);
            break;
        }
    }
    
    RfMode.rfMode = map->rfMode->rfMode;
    RfMode.cpePatchFxn = map->rfMode->cpePatchFxn;
    RfMode.mcePatchFxn = map->rfMode->mcePatchFxn;
    RfMode.rfePatchFxn = map->rfMode->rfePatchFxn;
    
    handle = RF_open(&RfObject, &RfMode, (RF_RadioSetup*)&TempSetupDiv, &RfParams);

  • you do not need to set  NUM_APPENDED_BYTES to more than 2, if you are only appending the status byte. If you do that, you have mis-configured something else.

    Have you tested my at all? Are you able to see any problems with it?

    In my code, I only add 2 for the status byte. In addition I add 2 for the length, and 4 for the timestamp (a total of 8), since

    // Appended bytes
    RF_cmdRxHS.rxConf.bIncludeLen = 1; // 2 bytes
    RF_cmdRxHS.rxConf.bAppendStatus = 1; // 2 bytes appended
    RF_cmdRxHS.rxConf.bAppendTimestamp = 1; // 4 bytes appended

    I have never seen that lastRssi has been 0 or 0x80.

    What are the rest of the statistics in this case?

    Are you able to see this result with my code as well?

    For us to spend more time on this, we need a way to reproduce the issue, and right now I am not able to.

    Siri

  • Hi Siri,

    Sorry for the delay in getting back to you - I was called to other work.

    I have discovered the issue with RSSI not being reported: I only see the rssi field of rfc_hsRxStatus_s.status if I set bUseCrc on at least the receiving CC1310. This is not what I would expect (why can I not inspect RSSI without using the CC1310 CRC feature?) and I cannot find any documentation that notes this behaviour. This behaviour applies to rfc_hsRxOutput_s.lastRssi also. Please see the attached image, which describes my observations.

    The difference in code between the two scenarios of the attached image is this:

    // #### RSSI is only accessible if CRC is used?!
    if(!(RxPacketCounter++ % 4))
    {
        RF_cmdRxHS.pktConf.bUseCrc = 1;
    }
    else
    {
        RF_cmdRxHS.pktConf.bUseCrc = 0;
    }

    Please advise.

    TIA,

    Sean.

  • Hi Sean,

    I had a look at the implementation of the patch, and it indeed looks like that when using the HS commands, we only ever append the RSSI to the packet when bUseCrc is set to one.

    I do not know why it would be that way, but it does verify your observations.

    Regards,

    Arthur

  • Hi Arthur,

    Thanks for checking this so quickly and for confirming my observations.

    It's incredibly frustrating that such material is apparently not documented anywhere, but this is not your fault; this is TI's Sales Dept. throwing their Engineers under the bus, by all appearances.

    Thanks again,

    Sean.