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: Implementing WakeOnRadio RX/Tx in Easylink

Part Number: CC1310

Hi, everybody!

I'm trying to implement WakeOnRadio TX/RX to Easylink of existing project, but can't get TX packet correctly received even in SmartRF Studio

As requested I'm using rfWakeOnRadioTx/rfWakeOnRadioRx example to get all this thing working and SmartRF studio and receiving part of our

device to debug.

Biggest difference from TI examples, mentioned above, that we are using 5kpbs SimpleLink Long Range modulation. Also I wouldn't like to copy structures, using initializeTxAdvCmdFromTxCmd due to memory considerations, so, I'm trying to fill rfc_CMD_PROP_TX_ADV_t from scratch:

// CMD_PROP_TX_ADV
// Proprietary Mode Transmit Command
rfc_CMD_PROP_TX_ADV_t RF_cmdPropTxAdv =
{
.commandNo = CMD_PROP_TX_ADV,
.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 = 0x1,
// .pktConf.bVarLen = 0x1, // no such field in CMD_PROP_TX_ADV
.pktLen = 0x14, // SET APPLICATION PAYLOAD LENGTH
.syncWord = 0x930B51DE,
.pPkt = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
};

than - fill requested fields according TI example:

    //store application callback
    txCb = cb;

    txBuffer[0]=txPacket->len + addrSize + 1;
    memcpy(txBuffer+1, txPacket->dstAddr, addrSize);
    memcpy(txBuffer + addrSize + 1, txPacket->payload, txPacket->len);

    //packet length to Tx includes address
    EasyLink_cmdPropTxAdv.pktLen = txPacket->len + addrSize + 1;
    EasyLink_cmdPropTxAdv.pPkt = txBuffer;
    EasyLink_cmdPropTxAdv.preTime = WOR_PREAMBLE_TIME_RAT_TICKS(WOR_WAKEUPS_PER_SECOND);
    EasyLink_cmdPropTxAdv.preTrigger.triggerType = TRIG_REL_START;

    EasyLink_cmdPropTxAdv.pktConf.bFsOff = 0x0;
    EasyLink_cmdPropTxAdv.pktConf.bUseCrc = 0x1;
    EasyLink_cmdPropTxAdv.syncWord = 0x930B51DE;

Then - transmit

/* Send packet */
asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv,
RF_PriorityNormal, txDoneCallback, EASYLINK_RF_EVENT_MASK);

if (EasyLink_CmdHandle_isValid(asyncCmdHndl))
{
status = EasyLink_Status_Success;
}

//busyMutex will be released by the callback

return status;

Other settings are attached:

//*********************************************************************************
// Generated by SmartRF Studio version 2.6.1 (build #20)
// Tested for SimpleLink SDK version: CC13x0 SDK 1.30.xx.xx
// Device: CC1350 Rev. 2.1 (Rev. B)
// 
//*********************************************************************************


//*********************************************************************************
// Parameter summary
// Address: off 
// Address0: 0xAA 
// Address1: 0xBB 
// Frequency: 868.00000 MHz
// Data Format: Serial mode disable 
// Deviation: 5.000 kHz
// Packet Length Config: Variable 
// Max Packet Length: 255 
// Packet Length: 20 
// RX Filter BW: 49 kHz
// Symbol Rate: 19.99969 kBaud
// Sync Word Length: 32 Bits 
// TX Power: 14 dBm (requires define CCFG_FORCE_VDDR_HH = 1 in ccfg.c, see CC13xx/CC26xx Technical Reference Manual)
// Whitening: No whitening 

#define DEVICE_FAMILY_PATH DeviceFamily_constructPath
                              
#include <ti/devices/DeviceFamily.h>
#include DEVICE_FAMILY_PATH(driverlib/rf_mailbox.h)
#include DEVICE_FAMILY_PATH(driverlib/rf_common_cmd.h)
#include DEVICE_FAMILY_PATH(driverlib/rf_prop_cmd.h)
#include <ti/drivers/rf/RF.h>
#include DEVICE_FAMILY_PATH(rf_patches/rf_patch_cpe_sl_longrange.h)
#include DEVICE_FAMILY_PATH(rf_patches/rf_patch_rfe_sl_longrange.h)
#include DEVICE_FAMILY_PATH(rf_patches/rf_patch_mce_sl_longrange.h)
#include "smartrf_settings.h"


// TI-RTOS RF Mode Object
RF_Mode RF_prop =
{
    .rfMode = RF_MODE_PROPRIETARY_SUB_1,
    .cpePatchFxn = &rf_patch_cpe_sl_longrange,
    .mcePatchFxn = &rf_patch_mce_sl_longrange,
    .rfePatchFxn = &rf_patch_rfe_sl_longrange,
};

// Overrides for CMD_PROP_RADIO_DIV_SETUP
static uint32_t pOverrides[] =
{
    // override_use_patch_simplelink_long_range.xml
    // PHY: Use MCE RAM patch, RFE RAM patch
    MCE_RFE_OVERRIDE(1,0,0,1,0,0),
    // override_synth_prop_863_930_div5_lbw60k.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 60 kHz
    (uint32_t)0x40410583,
    // Synth: Set loop bandwidth after lock to 60 kHz
    (uint32_t)0x32CC0603,
    // Synth: Set loop bandwidth after lock to 60 kHz
    (uint32_t)0x00010623,
    // 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_synth_disable_bias_div5.xml
    // Synth: Set divider bias to disabled
    HW32_ARRAY_OVERRIDE(0x405C,1),
    // Synth: Set divider bias to disabled (specific for loDivider=5)
    (uint32_t)0x18000200,
    // 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_0x14.xml
    // Tx: Configure PA ramping setting (0x41). Rx: Set AGC reference level to 0x14.
    HW_REG_OVERRIDE(0x6088,0x4114),
    // Tx: Configure PA ramping setting
    HW_REG_OVERRIDE(0x608C,0x8213),
    // override_phy_long_range_dsss2.xml
    // PHY: Configure DSSS SF=2
    HW_REG_OVERRIDE(0x505C,0x0100),
    // 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),
    (uint32_t)0xFFFFFFFF,
};


// CMD_PROP_RADIO_DIV_SETUP
// Proprietary Mode Radio Setup Command for All Frequency Bands
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 = 0x1,
    .modulation.deviation = 0x14,
    .symbolRate.preScale = 0xF,
    .symbolRate.rateWord = 0x3333,
    .rxBw = 0x21,
    .preamConf.nPreamBytes = 0x2,
    .preamConf.preamMode = 0x0,
    .formatConf.nSwBits = 0x20,
    .formatConf.bBitReversal = 0x0,
    .formatConf.bMsbFirst = 0x0,
    .formatConf.fecMode = 0x8,
    .formatConf.whitenMode = 0x0,
    .config.frontEndMode = 0x0,
    .config.biasMode = 0x1,
    .config.analogCfgMode = 0x0,
    .config.bNoFsPowerUp = 0x0,
    .txPower = 0xAB3F,
    .pRegOverride = pOverrides,
    .centerFreq = 0x0364,
    .intFreq = 0x8000,
    .loDivider = 0x05,
};

// CMD_FS
// Frequency Synthesizer Programming Command
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_PROP_TX
// Proprietary Mode Transmit Command
rfc_CMD_PROP_TX_t RF_cmdPropTx =
{
    .commandNo = 0x3801,
    .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 = 0x1,
    .pktConf.bVarLen = 0x1,
    .pktLen = 0x14, // SET APPLICATION PAYLOAD LENGTH
    .syncWord = 0x930B51DE,
    .pPkt = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
};

// CMD_PROP_RX
// Proprietary Mode Receive Command
rfc_CMD_PROP_RX_t RF_cmdPropRx =
{
    .commandNo = 0x3802,
    .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 = 0x1,
    .pktConf.bVarLen = 0x1,
    .pktConf.bChkAddress = 0x0,
    .pktConf.endType = 0x0,
    .pktConf.filterOp = 0x0,
    .rxConf.bAutoFlushIgnored = 0x0,
    .rxConf.bAutoFlushCrcErr = 0x0,
    .rxConf.bIncludeHdr = 0x1,
    .rxConf.bIncludeCrc = 0x0,
    .rxConf.bAppendRssi = 0x0,
    .rxConf.bAppendTimestamp = 0x0,
    .rxConf.bAppendStatus = 0x1,
    .syncWord = 0x930B51DE,
    .maxPktLen = 0xFF, // MAKE SURE DATA ENTRY IS LARGE ENOUGH
    .address0 = 0xAA,
    .address1 = 0xBB,
    .endTrigger.triggerType = 0x1,
    .endTrigger.bEnaCmd = 0x0,
    .endTrigger.triggerNo = 0x0,
    .endTrigger.pastTrig = 0x0,
    .endTime = 0x00000000,
    .pQueue = 0, // INSERT APPLICABLE POINTER: (dataQueue_t*)&xxx
    .pOutput = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
};

Packet transmit ok, but Smart RF Studio registering Received Not OK packet (default settings for 5kpbs SimpleLink Long Range modulation. 

From receiver point of view:

1. Initialize rfc_CMD_PROP_RX_ADV_SNIFF_t struct (if we use rfc_CMD_PROP_TX_ADV_t - obvious to use rfc_CMD_PROP_RX_ADV_SNIFF_t  command - as I understand TI datasheets, non-ADV and ADV TX/RX commands have different packet structure  why your examples using ADV TX command in TX side and normal RX command on RX side)

2. Config sniffer parameters using configureSniffCmd from RX example of TI:

/* Configures Sniff-mode part of the RX_SNIFF command based on mode, datarate and wakeup interval */
void configureSniffCmd(rfc_CMD_PROP_RX_ADV_SNIFF_t* rxSniffCmd, enum CarrierSenseMode mode, uint32_t datarate, uint8_t wakeupPerSecond, uint8_t syncWordSymbols) {
/* Enable or disable RSSI */
if ((mode == CarrierSenseMode_RSSI) || (mode == CarrierSenseMode_RSSIandPQT)) {
rxSniffCmd->csConf.bEnaRssi = 1;
} else {
rxSniffCmd->csConf.bEnaRssi = 0;
}

/* Enable or disable PQT */
if ((mode == CarrierSenseMode_PQT) || (mode == CarrierSenseMode_RSSIandPQT)) {
rxSniffCmd->csConf.bEnaCorr = 1;
rxSniffCmd->csEndTrigger.triggerType = TRIG_REL_START;
} else {
rxSniffCmd->csConf.bEnaCorr = 0;
rxSniffCmd->csEndTrigger.triggerType = TRIG_NEVER;
}

/* General Carrier Sense configuration */
rxSniffCmd->csConf.operation = 1; /* Report Idle if RSSI reports Idle to quickly exit if not above
RSSI threshold */
rxSniffCmd->csConf.busyOp = 0; /* End carrier sense on channel Busy (the receiver will continue when
carrier sense ends, but it will then not end if channel goes Idle) */
rxSniffCmd->csConf.idleOp = 1; /* End on channel Idle */
rxSniffCmd->csConf.timeoutRes = 1; /* If the channel is invalid, it will return PROP_DONE_IDLE_TIMEOUT */

/* RSSI configuration */
rxSniffCmd->numRssiIdle = 1; /* One idle RSSI samples signals that the channel is idle */
rxSniffCmd->numRssiBusy = 1; /* One busy RSSI samples signals that the channel is busy */
rxSniffCmd->rssiThr = (int8_t)WOR_RSSI_THRESHOLD; /* Set the RSSI threshold in dBm */

/* PQT configuration */
rxSniffCmd->corrConfig.numCorrBusy = 1; /* One busy PQT samples signals that the channel is busy */
rxSniffCmd->corrConfig.numCorrInv = 1; /* One busy PQT samples signals that the channel is busy */

/* Calculate basic timing parameters */
uint32_t symbolLengthUs = 4*(1000000UL/datarate);
uint32_t preambleSymbols = (1000000UL/wakeupPerSecond)/(symbolLengthUs*4);
// uint8_t syncWordSymbols = RF_cmdPropRadioDivSetup.formatConf.nSwBits;

/* Represents the time in which we need to receive corrConfig.numCorr* correlation peaks to detect preamble.
* When continously checking the preamble quality, this period has to be wide enough to also contain the sync
* word, with a margin. If it is not, then there is a chance the SNIFF command will abort while receiving the
* sync word, as it no longer detects a preamble. */
uint32_t correlationPeriodUs = (syncWordSymbols + CORR_PERIOD_SYM_MARGIN)*symbolLengthUs; // OK!!!

/* Represents the time where we will force a check if preamble is present (only done once).
* The main idea is that his should be shorter than "correlationPeriodUs" so that if we get RSSI valid, but
* there is not a valid preamble on the air, we will leave RX as quickly as possible. */
uint32_t csEndTimeUs = (CS_END_TIME_MIN_TIME_SYM*symbolLengthUs + CS_END_TIME_MIN_TIME_STATIC_US);

/* Represents the maximum time from the startTrigger to when we expect a sync word to be received. */
uint32_t rxEndTimeUs = (preambleSymbols + syncWordSymbols + RX_END_TIME_SYM_MARGIN)*symbolLengthUs;

/* Set sniff mode timing configuration in sniff command in RAT ticks */
rxSniffCmd->corrPeriod = (uint16_t)(correlationPeriodUs * US_TO_RAT_TICKS);
rxSniffCmd->csEndTime = (uint32_t)(csEndTimeUs * US_TO_RAT_TICKS);
rxSniffCmd->startTrigger.triggerType = TRIG_ABSTIME;
rxSniffCmd->startTrigger.pastTrig = 1;

rxSniffCmd->endTrigger.triggerType = TRIG_REL_START;
rxSniffCmd->endTime = (uint32_t)(rxEndTimeUs * US_TO_RAT_TICKS);
}

Here is another problem with datarate parameter. calculateSymbolRate function from RX example give us 20000 bps
datarate but in fact it is 5000 only, because 20000 it is symbol rate, but not datarate...

There are also a lot of "magic" constants like:

#define WOR_WAKE_UP_MARGIN_S 0.05f
#define WOR_WAKE_UP_INTERVAL_RAT_TICKS(x) ((uint32_t)(4000000*(1.0f/(x) - (WOR_WAKE_UP_MARGIN_S))))


/* Calculate sniff mode parameters */
#define US_TO_RAT_TICKS 4
#define CORR_PERIOD_SYM_MARGIN 16
#define RX_END_TIME_SYM_MARGIN 40 //8
#define CS_END_TIME_MIN_TIME_SYM 30
#define CS_END_TIME_MIN_TIME_STATIC_US 150

That also might be changed if datarate and symbol rate are different.


After changing all this we getting such spaghetty-code (sorry for this - it is under debug) it is broken part of Easylink_receiveAsync function:

rxCb = cb;

pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer;
//data entry rx buffer includes hdr (len-1Byte), addr (max 8Bytes) and data
pDataEntry->length = 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH;
pDataEntry->status = 0;
dataQueue.pCurrEntry = (uint8_t*) pDataEntry;
dataQueue.pLastEntry = NULL;
EasyLink_cmdPropRxAdv.pQueue = &dataQueue; /* Set the Data Entity queue for received data */
EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics;

/* if (absTime != 0)
{
EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_ABSTIME;
EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1;
EasyLink_cmdPropRxAdv.startTime = absTime;
}
else
{
EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_NOW;
EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1;
EasyLink_cmdPropRxAdv.startTime = 0;
}

if (asyncRxTimeOut != 0)
{
EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_ABSTIME;
EasyLink_cmdPropRxAdv.endTime = RF_getCurrentTime() + asyncRxTimeOut;
}
else
{
EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_NEVER;
EasyLink_cmdPropRxAdv.endTime = 0;
} */

//Clear the Rx statistics structure
memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t));

// !!!!!! Configure sniffer !!!!!
/* Calculate datarate from prescaler and rate word */

// uint32_t datarate = calculateSymbolRate(EasyLink_cmdPropRadioSetup.divSetup.symbolRate.preScale,
// EasyLink_cmdPropRadioSetup.divSetup.symbolRate.rateWord);

uint32_t datarate=5000;

EasyLink_cmdPropRxAdv.rxConf.bAutoFlushIgnored = 1;
EasyLink_cmdPropRxAdv.rxConf.bAutoFlushCrcErr = 1;

EasyLink_cmdPropRxAdv.pktConf.bCrcIncHdr = 0x1,
EasyLink_cmdPropRxAdv.pktConf.endType = 0x0, 
EasyLink_cmdPropRxAdv.pktConf.filterOp = 0x1,

/* Configure Sniff-mode part of the RX_SNIFF command */
configureSniffCmd(&EasyLink_cmdPropRxAdv, WOR_MODE, datarate, WOR_WAKEUPS_PER_SECOND, EasyLink_cmdPropRadioSetup.divSetup.formatConf.nSwBits);


EasyLink_cmdPropRxAdv.startTime = RF_getCurrentTime();
// EasyLink_cmdPropRxAdv.startTime += WOR_WAKE_UP_INTERVAL_RAT_TICKS(WOR_WAKEUPS_PER_SECOND);

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv,
RF_PriorityNormal, rxDoneCallback, EASYLINK_RF_EVENT_MASK);

if (EasyLink_CmdHandle_isValid(asyncCmdHndl))
{
status = EasyLink_Status_Success;
}

//busyMutex will be released in callback

return status;

Please note on bolded commented line.

In such stage we could receive something. .status field in callback function give us error PROP_DONE_RXERR after complete receive.

I have noted, that receive is completed before transmission completed in transmit side (controlling by LED), that means, that preamble

and syncWord receive OK, but some problems with packet structure. But if I uncomment commented line above, I will get only 

PROP_DONE_IDLETIMEOUT error in status field each half a second... Than means, that preabmle is detected, but no syncWord found...

I'm completely *ucked with this... May be this is some stupid mistake here in some bit-wise parameters, but I broken my eyes finding

problems in WoR...

Thank you in advance

Looking forward for your reply



  • Hi Andrew,

    To start with, you are not able to do WOR with SLR as the PHY do not use normal preamble, this means you can not use the correlator to find the preamble. You could possibly use RSSI only, but it would not work very well due to the sensitivity of SLR (you would basically always be awake).

    I would recommend you start of with the WOR example, find an appropriate PHY and get everything to work fine there. I would then try to move over to EasyLink step by step (first TX; then RX). Keep in mind that EasyLink sometimes does "EasyLink magic" which means you don't have the same control as when doing it yourself like in the WOR examples. If you don't really need EasyLink and want to do WOR, I would recommend you try to base your application on the RF driver only.

    This application note contains some good information on long range mode PHYs and what the difference between different PHYs is:

    www.ti.com/.../swra642

    Maybe you could leverage the "Legacy Long Range Mode" PHY for this, but I would not guarantee that it works well.
  • Ok. Now it is clear. Could you please explain meaning and how to recalculate these "magic numbers", depending on Symbol Rate:

    #define WOR_WAKE_UP_MARGIN_S 0.005f

    /* Calculate sniff mode parameters */

    #define CORR_PERIOD_SYM_MARGIN 16
    #define RX_END_TIME_SYM_MARGIN 8
    #define CS_END_TIME_MIN_TIME_SYM 30
    #define CS_END_TIME_MIN_TIME_STATIC_US 150

    I'm using RF parameters now:

    // Parameter summary
    // Address: off
    // Address0: 0xAA
    // Address1: 0xBB
    // Frequency: 868.00000 MHz
    // Data Format: Serial mode disable
    // Deviation: 19.000 kHz
    // Packet Length Config: Variable
    // Max Packet Length: 128
    // Packet Length: 20
    // RX Filter BW: 78 kHz
    // Symbol Rate: 10.00061 kBaud
    // Sync Word Length: 32 Bits


    I often get PROP_DONE_RXTIMEOUT (1 good packet per 5-7 bad one) instead of receiving valid packet. Seems, after changing speed I also need to recalculate these parameters.

    Hope you could help.

    Thank you in advance

    Looking forward for your reply
  • Hi Andrew,

    The timing parameters are described in the README of the example, as preamble is key, I would expect you to have to tweak these when changing symbol rate. I recommend you start from README and try to adjust them based on the information there.

    Unfortunately they can seem to be very magic indeed, we are working on getting an application note together which would cover the subject on a more detailed level.