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: Can EasyLink receive wMBus messages in C (and/or T) mode?

Part Number: CC1310
Other Parts Discussed in Thread: WMBUS,

I'm working on a project based on EasyLinkEcho (RX/TX) example (SimpleLink CC13x0 SDK v4.20.02.07 in CCS  12.0.0.00009).
In parallel I'm using wMBus stack (wmbus-cc13xx-rtos-2.0.0 in CCS 8.1.0.00011) on a different device set (also CC1310).

I'd like to create a collector device being capable of receiving both EasyLink based messages and wMBus telegrams (C mode & probably T mode).
I adapted smartrf_settings.c in EasyLink based on the C mode wMBus smartrf_settings (sf_cc13xx_868_95.c) but some parameters had to be excluded to be able to build the EasyLink based project in CCS 12.

#include <ti/devices/DeviceFamily.h>
#include DeviceFamily_constructPath(driverlib/rf_mailbox.h)
#include DeviceFamily_constructPath(driverlib/rf_common_cmd.h)
#include DeviceFamily_constructPath(driverlib/rf_prop_cmd.h)
#include <ti/drivers/rf/RF.h>
#include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_genfsk.h)
#include DeviceFamily_constructPath(rf_patches/rf_patch_rfe_genfsk.h)
#include "smartrf_settings.h"

uint32_t txShapeCMode[] = {0x00000000, 0x00000000, 0x00000000, 0x440F0200, 0xD9D8CA96, 0xD9D9D9D9};

// TI-RTOS RF Mode Object
RF_Mode RF_prop =
{
    .rfMode = RF_MODE_PROPRIETARY_SUB_1,
    .cpePatchFxn = &rf_patch_cpe_genfsk,
    .mcePatchFxn = 0,
    .rfePatchFxn = &rf_patch_rfe_genfsk,
};

// Overrides for CMD_PROP_RADIO_DIV_SETUP
uint32_t pOverrides[] =
{
	//Run the MCE and RFE patches
    MCE_RFE_OVERRIDE(1,0,0,1,0,0),
    // override_synth_prop_863_930_div5.xml
    // Synth: Set recommended RTRIM to 7
    HW_REG_OVERRIDE(0x4038,0x0037),
    // Synth: Set Fref to 4 MHz
    (uint32_t)0x000684A3,
    // Synth: Configure fine calibration setting
    HW_REG_OVERRIDE(0x4020,0x7F00),
    // Synth: Configure fine calibration setting
    HW_REG_OVERRIDE(0x4064,0x0040),
    // Synth: Configure fine calibration setting
    (uint32_t)0xB1070503,
    // Synth: Configure fine calibration setting
    (uint32_t)0x05330523,
    // Synth: Set loop bandwidth after lock to 20 kHz
    (uint32_t)0x0A480583,
    // Synth: Set loop bandwidth after lock to 20 kHz
    (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),
    // 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,
    // override_phy_rx_aaf_bw_0xd.xml
    // Rx: Set anti-aliasing filter bandwidth to 0xD (in ADI0, set IFAMPCTL3[7:4]=0xD)
    ADI_HALFREG_OVERRIDE(0,61,0xF,0xD),
    // override_phy_gfsk_rx.xml
    // Rx: Set LNA bias current trim offset to 3
    (uint32_t)0x00038883,
    // Rx: Freeze RSSI on sync found event
    HW_REG_OVERRIDE(0x6084,0x35F1),
    // override_phy_gfsk_pa_ramp_agc_reflevel_0x2e.xml
    // Tx: Configure PA ramping setting and set AGC reference level to 0x2E
    HW_REG_OVERRIDE(0x6088,0x082E),
    // Tx: Configure PA ramping setting and set AGC settle wait = (0x7+1)*2 = 16 samples
    HW_REG_OVERRIDE(0x608C,0x0407),
    // override_phy_rx_rssi_offset_5db.xml
    // Rx: Set RSSI offset to adjust reported RSSI by +5 dB
    (uint32_t)0x00FB88A3,
    // TX power override
    // Tx: Set PA trim to max (in ADI0, set PACTL0=0xF8)
    ADI_REG_OVERRIDE(0,12,0xF8),
	// AGC winsize 2 samples
    HW_REG_OVERRIDE(0x6064,0x1101),
    // CS threshold to �107 dBm
    HW_REG_OVERRIDE(0x6090,0xA095),
    // Let the patch control the correlator setting
    (uint32_t)0x00048103,
    // Clear state in internal radio register due to frequency change
    HW_REG_OVERRIDE(0x51F8,0x0000),
    HW_REG_OVERRIDE(0x52B4, 0x4000),
    // Set divider bias to disabled
    HW32_ARRAY_OVERRIDE(0x405C,1),
    (uint32_t)0x18000200,
    // TX shape in T-mode
    //0xC0040031,
    //(uint32_t)&txShapeTMode[0],
    // TX shape in C-mode
    0xC0040031,
    (uint32_t)&txShapeCMode[0],
    (uint32_t)0xFFFFFFFF,
};


// CMD_PROP_RADIO_DIV_SETUP
rfc_CMD_PROP_RADIO_DIV_SETUP_t RF_cmdPropRadioDivSetup =
{
    .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 = 0x0,
    .modulation.deviation = 0xB4, // T-Mode: 0xC8, C-Mode: 0xB4. /* According to swra522d we have to change the deviation setting for C-meters */
    .symbolRate.preScale = 0xC,
    .symbolRate.rateWord = 0xCCCD,
    .rxBw = 0x27,
    .preamConf.nPreamBytes = 0x4,
    .preamConf.preamMode = 0x0,
    .formatConf.nSwBits = 0x10,
    .formatConf.bBitReversal = 0x0,
    .formatConf.bMsbFirst = 0x1,
    .formatConf.fecMode = 0x0,
    .formatConf.whitenMode = 0x0,
    .config.frontEndMode = 0x0,
    .config.biasMode = 0x1,
    .config.analogCfgMode = 0x0,
    .config.bNoFsPowerUp = 0x0,
    .pRegOverride               = pOverrides,
    .txPower                    = 0xA73F,
    .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 = 0xF334,
    .synthConf.bTxMode = 0x0,
    .synthConf.refFreq = 0x0,
    .__dummy0 = 0x00,
    .__dummy1 = 0x00,
    .__dummy2 = 0x00,
    .__dummy3 = 0x0000,
};

// CMD_PROP_TX
rfc_CMD_PROP_TX_t RF_cmdPropTx =
{
    .commandNo = 0x3803,
    .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,
    .pktConf.bFsOff = 0x0,
    .pktConf.bUseCrc = 0x0,
    // .pktConf.bCrcIncSw = 0x0,
    // .pktConf.bCrcIncHdr = 0x0,
    // .numHdrBits = 0x00,
    .pktLen = 0x0000,
    // .startConf.bExtTxTrig = 0x0,
    // .startConf.inputMode = 0x0,
    // .startConf.source = 0x0,
    // .preTrigger.triggerType = 0x0,
    // .preTrigger.bEnaCmd = 0x0,
    // .preTrigger.triggerNo = 0x0,
    // .preTrigger.pastTrig = 0x0,
    // .preTime = 0x00000000,
    .syncWord = 0x0000543D,
    .pPkt = 0, /*INSERT APPLICABLE POINTER: (uint8_t*)&xxx */
};

// CMD_PROP_RX
rfc_CMD_PROP_RX_t RF_cmdPropRx =
{
    .commandNo = 0x3804,
    .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,
    .pktConf.bFsOff = 0x0,
    .pktConf.bRepeatOk = 0x0,
    .pktConf.bRepeatNok = 0x0,
    .pktConf.bUseCrc = 0x0,
    // .pktConf.bCrcIncSw = 0x0,
    // .pktConf.bCrcIncHdr = 0x0,
    .pktConf.endType = 0x0,
    .pktConf.filterOp = 0x0,
    .rxConf.bAutoFlushIgnored = 0x0,
    .rxConf.bAutoFlushCrcErr = 0x0,
    .rxConf.bIncludeHdr = 0x0,
    .rxConf.bIncludeCrc = 0x0,
    .rxConf.bAppendRssi = 0x0,
    .rxConf.bAppendTimestamp = 0x0,
    .rxConf.bAppendStatus = 0x0,
    .syncWord = 0x0000543D,
    // .syncWord1 = 0x00000000,
    .maxPktLen = 0x0000,
    // .hdrConf.numHdrBits = 0x0,
    // .hdrConf.lenPos = 0x0,
    // .hdrConf.numLenBits = 0x0,
    // .addrConf.addrType = 0x0,
    // .addrConf.addrSize = 0x0,
    // .addrConf.addrPos = 0x0,
    // .addrConf.numAddr = 0x0,
    // .lenOffset = 0x00,
    .endTrigger.triggerType = 0x0,
    .endTrigger.bEnaCmd = 0x0,
    .endTrigger.triggerNo = 0x0,
    .endTrigger.pastTrig = 0x0,
    .endTime = 0x00000000,
    // .pAddr = 0, /*INSERT APPLICABLE POINTER: (uint8_t*)&xxx */
    .pQueue = 0, /*INSERT APPLICABLE POINTER: (dataQueue_t*)&xxx */
    .pOutput = 0, /*INSERT APPLICABLE POINTER: (uint8_t*)&xxx */
};

However, the EasyLink receiver does not receive data from the wMBus "Meter" (wmbus stack for CC1310 with APL_CC13XX_Meter_T2_C2 and "wmbus_setMode(WMBUS_MODE_C2);" rather than the default "wmbus_setMode(WMBUS_MODE_T2);").
A test in advance based on a wMBus "Collector" (wmbus stack for CC1310 with Serial_CC13XX_Collector_C2) successfully receives the sent packages.

In SmartRF Studio 7 with continuous RX a spike (-20dBm) can be seen but no packet received there either.
SmartRF Settings:

Unfortunately I was not able to confirm my settings but found a statement that packets should be receivable here: how to configure Smart RF studio for T&C mode?

1) What settings should be used in SmartRF Studio to receive a packet sent from a wMBus device in C Mode (and/or T Mode)?

2) Is it possible to use EasyLink Abstraction layer ("EasyLink_receiveAsync") to receive wMBus (C Mode and/or T Mode) telegrams?
2.1) If yes, how can I achieve it?
2.2) If not, what could be possible solutions to use a simple RX/TX framework and wMBus in parallel on collector side (data can be processed on higher level later)?

Thanks in advance!

  • 1) What settings should be used in SmartRF Studio to receive a packet sent from a wMBus device in C Mode (and/or T Mode)?

    It is not possible to receive wMBus packets with SmartRF Studio.

    These settings require a patch that is not available in SmartRF Studio, and SMartRF Studio does not support the packet format used by wMBus

    2) Is it possible to use EasyLink Abstraction layer ("EasyLink_receiveAsync") to receive wMBus (C Mode and/or T Mode) telegrams?

    No, this is not possible, unless you re-write EasyLink completely, and then you can just as well start from scratch. In wMBus, you will need to program the radio to be in infinite RX mode, and then, after receiving some bytes, you need to check if the received packet is C mode or T mode. When you know that, you will know where in the packet the length byte is to be found (different place for the different modes), and then you can re-program the packet length of the radio. The CRC is not supported, and needs to be calculated in SW.

    2.1) If yes, how can I achieve it?

    See above. We do not have any code examples showing how this can be done, as the packet format etc. is described in the standard, which is not something we can share.


    2.2) If not, what could be possible solutions to use a simple RX/TX framework and wMBus in parallel on collector side (data can be processed on higher level later)?

    As written above, if you want some SW that can receive both wmbus packets and some prop packets, I would recommend you starting from scratch with your implementation.

    Siri