1. Import LAUNCHXL-CC1310 rfWakeOnRadioTx example from simplelink_cc13x0_sdk_3_20_00_23
2. Create a rfWakeOnRadioRx.c with the following code and save rfWakeOnRadioRx.c into project folder:
/***** Includes *****/
/* Standard C Libraries */
#include < stdlib.h >
/* XDCtools Header files */
#include < xdc/std.h >
#include < xdc/runtime/Assert.h >
/* BIOS Header files */
#include < ti/sysbios/BIOS.h >
#include < ti/sysbios/knl/Task.h >
/* TI-RTOS Header files */
#include < ti/drivers/rf/RF.h >
#include < ti/drivers/PIN.h >
#include < ti/drivers/pin/PINCC26XX.h >
#include < ti/drivers/UART.h >
/* Board Header files */
#include "Board.h"
/* Application Header files */
#include "RFQueue.h"
#include "smartrf_settings/smartrf_settings.h"
#include < ti/devices/DeviceFamily.h >
#include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
/***** Defines *****/
/* Wake-on-Radio wakeups per second */
#define WOR_WAKEUPS_PER_SECOND 2
/* Wake-on-Radio mode. Can be:
* - RSSI only
* - PQT, preamble detection
* - Both, first RSSI and then PQT if RSSI */
#define WOR_MODE CarrierSenseMode_RSSIandPQT
/* Threshold for RSSI based Carrier Sense in dBm */
#define WOR_RSSI_THRESHOLD ((int8_t)(-111))
/* Data Rate in use */
#define WOR_RF_PHY_DATARATE_50KBPS 0 // 2-GFSK 50Kbps
#define WOR_RF_PHY_DATARATE_100KBPS 1 // 2-GFSK 100Kbps
#define WOR_RF_PHY_DATARATE_200KBPS 2 // 2-GFSK 200Kbps
#define WOR_RF_PHY_DATARATE_300KBPS 3 // 2-GFSK 300Kbps
#define WOR_RF_PHY_DATARATE_400KBPS 4 // 2-GFSK 400Kbps
#define WOR_RF_PHY_DATARATE_500KBPS 5 // 2-GFSK 500Kbps
#define WOR_RF_PHY_DATARATE WOR_RF_PHY_DATARATE_50KBPS
/* Macro used to set actual wakeup interval */
#define WOR_WAKE_UP_MARGIN_S 0.005f
#define WOR_WAKE_UP_INTERVAL_RAT_TICKS(x) \
((uint32_t)(4000000*(1.0f/(x) - (WOR_WAKE_UP_MARGIN_S))))
/* TI-RTOS Task configuration */
#define RX_TASK_STACK_SIZE 1024
#define RX_TASK_PRIORITY 2
/* TX Configuration */
#define DATA_ENTRY_HEADER_SIZE 8 /* Constant header size of a Generic Data Entry */
#define MAX_LENGTH 31 /* 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 1 /* Length byte included in the stored packet */
/***** Type declarations *****/
/* General wake-on-radio RX statistics */
struct WorStatistics {
uint32_t doneIdle;
uint32_t doneIdleTimeout;
uint32_t doneRxTimeout;
uint32_t doneOk;
};
/* Modes of carrier sense possible */
enum CarrierSenseMode {
CarrierSenseMode_RSSI,
CarrierSenseMode_PQT,
CarrierSenseMode_RSSIandPQT,
};
/***** Variable declarations *****/
/* TX task objects and task stack */
static Task_Params rxTaskParams;
static Task_Struct rxTask;
static uint8_t rxTaskStack[RX_TASK_STACK_SIZE];
/* RF driver object and handle */
static RF_Object rfObject;
static RF_Handle rfHandle;
/* Pin driver object and handle */
extern PIN_Handle ledPinHandle;
extern PIN_State ledPinState;
/* General wake-on-radio sniff status statistics and statistics from the RF Core about received packets */
static volatile struct WorStatistics worStatistics;
static rfc_propRxOutput_t rxStatistics;
/*
* Application LED pin configuration table:
* - All LEDs board LEDs are off.
*/
static PIN_Config pinTable[] =
{
Board_PIN_LED0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
/* 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
/* RX Data Queue and Data Entry pointer to read out received packets */
static dataQueue_t dataQueue;
static rfc_dataEntryGeneral_t* currentDataEntry;
/* Received packet's length and pointer to the payload */
static uint8_t packetLength;
static uint8_t* packetDataPointer;
static volatile uint8_t dummy;
/* Sniff command for doing combined Carrier Sense and RX*/
static rfc_CMD_PROP_RX_SNIFF_t RF_cmdPropRxSniff;
/***** Prototypes *****/
static void rxTaskFunction(UArg arg0, UArg arg1);
static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
static void initializeSniffCmdFromRxCmd(rfc_CMD_PROP_RX_SNIFF_t* rxSniffCmd, rfc_CMD_PROP_RX_t* rxCmd);
static void configureSniffCmd(rfc_CMD_PROP_RX_SNIFF_t* rxSniffCmd, enum CarrierSenseMode mode, uint32_t datarate, uint8_t wakeupPerSecond);
static uint32_t calculateSymbolRate(uint8_t prescaler, uint32_t rateWord);
const char rxechoPrompt[] = "RX Echoing characters:\r\n";
extern UART_Handle uart;
extern UART_Params uartParams;
void rxTaskInit();
/***** Function definitions *****/
/* RX task initialization function. Runs once from main() */
void rxTaskInit()
{
Task_Params_init(&rxTaskParams);
rxTaskParams.stackSize = RX_TASK_STACK_SIZE;
rxTaskParams.priority = RX_TASK_PRIORITY;
rxTaskParams.stack = &rxTaskStack;
Task_construct(&rxTask, rxTaskFunction, &rxTaskParams, NULL);
}
/* RX task function. Executed in Task context by TI-RTOS when the scheduler starts. */
static void rxTaskFunction(UArg arg0, UArg arg1)
{
RF_Params rfParams;
RF_Params_init(&rfParams);
/* Route out LNA active pin to LED1 */
PINCC26XX_setMux(ledPinHandle, Board_PIN_LED0, PINCC26XX_MUX_RFC_GPO0);
/* Create queue and data entries */
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);
}
/* Copy all RX options from the SmartRF Studio exported RX command to the RX Sniff command */
initializeSniffCmdFromRxCmd(&RF_cmdPropRxSniff, &RF_cmdPropRx);
/* Configure RX part of RX_SNIFF command */
RF_cmdPropRxSniff.pQueue = &dataQueue;
RF_cmdPropRxSniff.pOutput = (uint8_t*)&rxStatistics;
RF_cmdPropRxSniff.maxPktLen = MAX_LENGTH;
/* Discard ignored packets and CRC errors from Rx queue */
RF_cmdPropRxSniff.rxConf.bAutoFlushIgnored = 1;
RF_cmdPropRxSniff.rxConf.bAutoFlushCrcErr = 1;
/* Calculate datarate from prescaler and rate word */
#if defined(DeviceFamily_CC26X0R2)
uint32_t datarate = calculateSymbolRate(RF_cmdPropRadioSetup.symbolRate.preScale,
RF_cmdPropRadioSetup.symbolRate.rateWord);
#else
uint32_t datarate = calculateSymbolRate(RF_cmdPropRadioDivSetup.symbolRate.preScale,
RF_cmdPropRadioDivSetup.symbolRate.rateWord);
#endif// DeviceFamily_CC26X0R2
/* Configure Sniff-mode part of the RX_SNIFF command */
configureSniffCmd(&RF_cmdPropRxSniff, WOR_MODE, datarate, WOR_WAKEUPS_PER_SECOND);
/* Request access to the radio */
#if defined(DeviceFamily_CC26X0R2)
rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioSetup, &rfParams);
#else
rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
#endif// DeviceFamily_CC26X0R2
/* Set frequency */
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, &callback, 0);
/* Save the current radio time */
RF_cmdPropRxSniff.startTime = RF_getCurrentTime();
UART_write(uart, rxechoPrompt, sizeof(rxechoPrompt));
/* Enter main loop */
while(1)
{
/* Set next wakeup time in the future */
RF_cmdPropRxSniff.startTime += WOR_WAKE_UP_INTERVAL_RAT_TICKS(WOR_WAKEUPS_PER_SECOND);
RF_yield(rfHandle);
/* Schedule RX */
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRxSniff, RF_PriorityNormal, &callback, RF_EventRxEntryDone);
/* Log RX_SNIFF status */
switch(RF_cmdPropRxSniff.status) {
case PROP_DONE_IDLE:
/* Idle based on RSSI */
worStatistics.doneIdle++;
break;
case PROP_DONE_IDLETIMEOUT:
/* Idle based on PQT */
worStatistics.doneIdleTimeout++;
break;
case PROP_DONE_RXTIMEOUT:
/* Got valid preamble on the air, but did not find sync word */
worStatistics.doneRxTimeout++;
break;
case PROP_DONE_OK:
/* Received packet */
worStatistics.doneOk++;
UART_write(uart, packetDataPointer, packetLength);
break;
default:
/* Unhandled status */
break;
};
}
}
/* Calculates datarate from prescaler and rate word */
static uint32_t calculateSymbolRate(uint8_t prescaler, uint32_t rateWord)
{
/* Calculate datarate according to TRM Section 23.7.5.2:
* f_baudrate = (R * f_ref)/(p * 2^20)
* - R = rateWord
* - f_ref = 24Mhz
* - p = prescaler */
uint64_t numerator = rateWord*24000000ULL;
uint64_t denominator = prescaler*1048576ULL;
uint32_t result = (uint32_t)(numerator/denominator);
return result;
}
/* Copies all RX options from the SmartRF Studio exported RX command to the RX Sniff command */
static void initializeSniffCmdFromRxCmd(rfc_CMD_PROP_RX_SNIFF_t* rxSniffCmd, rfc_CMD_PROP_RX_t* rxCmd)
{
/* Copy RX configuration from RX command */
memcpy(rxSniffCmd, rxCmd, sizeof(rfc_CMD_PROP_RX_t));
/* Change to RX_SNIFF command from RX command */
rxSniffCmd->commandNo = CMD_PROP_RX_SNIFF;
}
/* Configures Sniff-mode part of the RX_SNIFF command based on mode, datarate and wakeup interval */
static void configureSniffCmd(rfc_CMD_PROP_RX_SNIFF_t* rxSniffCmd, enum CarrierSenseMode mode, uint32_t datarate, uint8_t wakeupPerSecond)
{
/* 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 = 1000000UL/datarate;
uint32_t preambleSymbols = (1000000UL/wakeupPerSecond)/symbolLengthUs;
#if defined(DeviceFamily_CC26X0R2)
uint8_t syncWordSymbols = RF_cmdPropRadioSetup.formatConf.nSwBits;
#else
uint8_t syncWordSymbols = RF_cmdPropRadioDivSetup.formatConf.nSwBits;
#endif// DeviceFamily_CC26X0R2
/* Calculate sniff mode parameters */
#define US_TO_RAT_TICKS 4
#define CORR_PERIOD_SYM_MARGIN 16
#define RX_END_TIME_SYM_MARGIN 8
#define CS_END_TIME_MIN_TIME_SYM 30
#if ((WOR_RF_PHY_DATARATE == WOR_RF_PHY_DATARATE_50KBPS) || \
(WOR_RF_PHY_DATARATE == WOR_RF_PHY_DATARATE_100KBPS) || \
(WOR_RF_PHY_DATARATE == WOR_RF_PHY_DATARATE_200KBPS))
#define CS_END_TIME_MIN_TIME_STATIC_US 150
#elif ((WOR_RF_PHY_DATARATE == WOR_RF_PHY_DATARATE_300KBPS) || \
(WOR_RF_PHY_DATARATE == WOR_RF_PHY_DATARATE_400KBPS))
#define CS_END_TIME_MIN_TIME_STATIC_US 200
#elif (WOR_RF_PHY_DATARATE == WOR_RF_PHY_DATARATE_500KBPS)
#define CS_END_TIME_MIN_TIME_STATIC_US 250
#else
#error "WOR_RF_PHY_DATARATE is undefined or has an invalid option"
#endif
/* 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;
/* 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->endTime = (uint32_t)(rxEndTimeUs * US_TO_RAT_TICKS);
/* Set correct trigger types */
rxSniffCmd->endTrigger.triggerType = TRIG_REL_START;
rxSniffCmd->startTrigger.triggerType = TRIG_ABSTIME;
rxSniffCmd->startTrigger.pastTrig = 1;
}
/* Called for every received packet and command done */
void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{
/* If we've received a new packet and it's available to read out */
if (e & RF_EventRxEntryDone)
{
do
{
/* Toggle LED on RX */
PIN_setOutputValue(ledPinHandle, Board_PIN_LED1, !PIN_getOutputValue(Board_PIN_LED1));
/* Get current unhandled data entry */
currentDataEntry = RFQueue_getDataEntry();
/* Handle the packet data, located at ¤tDataEntry->data:
* - Length is the first byte with the current configuration
* - Data starts from the second byte */
packetLength = *(uint8_t*)(¤tDataEntry->data);
packetDataPointer = (uint8_t*)(¤tDataEntry->data + 1);
/* This code block is added to avoid a compiler warning.
* Normally, an application will reference these variables for
* useful data. */
dummy = packetLength + packetDataPointer[0];
} while(RFQueue_nextEntry() == DATA_ENTRY_FINISHED);
}
}
3. Add/revise the following codes in red into rfWakeOnRadioTx.c:
/***** Includes *****/
#include < stdlib.h >
/* XDCtools Header files */
#include < xdc/std.h >
#include < xdc/runtime/Assert.h >
/* BIOS Header files */
#include < ti/sysbios/BIOS.h >
#include < ti/sysbios/knl/Semaphore.h >
#include < ti/sysbios/knl/Task.h >
/* TI-RTOS Header files */
#include < ti/drivers/rf/RF.h >
#include < ti/drivers/PIN.h >
#include < ti/display/Display.h >
#include < ti/devices/DeviceFamily.h >
#include DeviceFamily_constructPath(driverlib/cpu.h)
#include < ti/drivers/UART.h >
/* Board Header files */
#include "Board.h"
/* RF settings */
#include "smartrf_settings/smartrf_settings.h"
/***** Defines *****/
/* Wake-on-Radio configuration */
#define WOR_WAKEUPS_PER_SECOND 2
/* TX number of random payload bytes */
#define PAYLOAD_LENGTH 30
/* WOR Example configuration defines */
#define WOR_PREAMBLE_TIME_RAT_TICKS(x) \
((uint32_t)(4000000*(1.0f/(x))))
/* TX task stack size and priority */
#define TX_TASK_STACK_SIZE 1024
#define TX_TASK_PRIORITY 2
/***** Prototypes *****/
static void txTaskFunction(UArg arg0, UArg arg1);
static void initializeTxAdvCmdFromTxCmd(rfc_CMD_PROP_TX_ADV_t* RF_cmdPropTxAdv, rfc_CMD_PROP_TX_t* RF_cmdPropTx);
/***** Variable declarations *****/
/* TX task objects and task stack */
static Task_Params txTaskParams;
Task_Struct txTask; /* not static so you can see in ROV */
static uint8_t txTaskStack[TX_TASK_STACK_SIZE];
/* TX packet payload (length +1 to fit length byte) and sequence number */
static uint8_t packet[PAYLOAD_LENGTH +1];
static uint16_t seqNumber;
/* RF driver objects and handles */
static RF_Object rfObject;
static RF_Handle rfHandle;
/* Pin driver objects and handles */
PIN_Handle ledPinHandle;
static PIN_Handle buttonPinHandle;
PIN_State ledPinState;
static PIN_State buttonPinState;
/* TX Semaphore */
static Semaphore_Struct txSemaphore;
static Semaphore_Handle txSemaphoreHandle;
/* Advanced TX command for sending long preamble */
static rfc_CMD_PROP_TX_ADV_t RF_cmdPropTxAdv;
/*
* Application LED pin configuration table:
* - All LEDs board LEDs are off.
*/
PIN_Config pinTable[] =
{
Board_PIN_LED0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
/*
* Application button pin configuration table:
* - Buttons interrupts are configured to trigger on falling edge.
*/
PIN_Config buttonPinTable[] = {
Board_PIN_BUTTON0 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
PIN_TERMINATE
};
char input;
const char echoPrompt[] = "Echoing characters:\r\n";
UART_Handle uart;
UART_Params uartParams;
/***** Function definitions *****/
/* Pin interrupt Callback function board buttons configured in the pinTable. */
void buttonCallbackFunction(PIN_Handle handle, PIN_Id pinId) {
/* Simple debounce logic, only toggle if the button is still pushed (low) */
CPUdelay((uint32_t)((48000000/3)*0.050f));
if (!PIN_getInputValue(pinId)) {
/* Post TX semaphore to TX task */
Semaphore_post(txSemaphoreHandle);
}
}
/* TX task initialization function. Runs once from main() */
void txTaskInit()
{
/* Initialize TX semaphore */
Semaphore_construct(&txSemaphore, 0, NULL);
txSemaphoreHandle = Semaphore_handle(&txSemaphore);
/* Initialize and create TX task */
Task_Params_init(&txTaskParams);
txTaskParams.stackSize = TX_TASK_STACK_SIZE;
txTaskParams.priority = TX_TASK_PRIORITY;
txTaskParams.stack = &txTaskStack;
Task_construct(&txTask, txTaskFunction, &txTaskParams, NULL);
}
/* TX task function. Executed in Task context by TI-RTOS when the scheduler starts. */
static void txTaskFunction(UArg arg0, UArg arg1)
{
UART_init();
/* Create a UART with data processing off. */
UART_Params_init(&uartParams);
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.readDataMode = UART_DATA_BINARY;
uartParams.readReturnMode = UART_RETURN_FULL;
uartParams.readEcho = UART_ECHO_OFF;
uartParams.baudRate = 115200;
uart = UART_open(Board_UART0, &uartParams);
if (uart == NULL) {
/* UART_open() failed */
while (1);
}
UART_write(uart, echoPrompt, sizeof(echoPrompt));
#if 0 /* Initialize the display and try to open both UART and LCD types of display. */
Display_Params params;
Display_Params_init(¶ms);
params.lineClearMode = DISPLAY_CLEAR_BOTH;
Display_Handle uartDisplayHandle = Display_open(Display_Type_UART, ¶ms);
Display_Handle lcdDisplayHandle = Display_open(Display_Type_LCD, ¶ms);
/* Print initial display content on both UART and any LCD present */
Display_printf(uartDisplayHandle, 0, 0, "Wake-on-Radio TX");
Display_printf(uartDisplayHandle, 0, 0, "Pkts sent: %u", seqNumber);
Display_printf(lcdDisplayHandle, 0, 0, "Wake-on-Radio TX");
Display_printf(lcdDisplayHandle, 1, 0, "Pkts sent: %u", seqNumber);
#endif /* Setup callback for button pins */
PIN_Status status = PIN_registerIntCb(buttonPinHandle, &buttonCallbackFunction);
Assert_isTrue((status == PIN_SUCCESS), NULL);
/* Initialize the radio */
RF_Params rfParams;
RF_Params_init(&rfParams);
/* Initialize TX_ADV command from TX command */
initializeTxAdvCmdFromTxCmd(&RF_cmdPropTxAdv, &RF_cmdPropTx);
/* Set application specific fields */
RF_cmdPropTxAdv.pktLen = PAYLOAD_LENGTH +1; /* +1 for length byte */
RF_cmdPropTxAdv.pPkt = packet;
RF_cmdPropTxAdv.preTrigger.triggerType = TRIG_REL_START;
RF_cmdPropTxAdv.preTime = WOR_PREAMBLE_TIME_RAT_TICKS(WOR_WAKEUPS_PER_SECOND);
/* Request access to the radio */
#if defined(DeviceFamily_CC26X0R2)
rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioSetup, &rfParams);
#else
rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
#endif// DeviceFamily_CC26X0R2
/* Set the frequency */
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
/* Enter main TX loop */
while(1)
{
RF_yield(rfHandle); /* Wait for a button press */
Semaphore_pend(txSemaphoreHandle, BIOS_WAIT_FOREVER);
#if 0 /* Create packet with incrementing sequence number and random payload */
packet[0] = PAYLOAD_LENGTH;
packet[1] = (uint8_t)(seqNumber >> 8);
packet[2] = (uint8_t)(seqNumber++);
uint8_t i;
for (i = 3; i < PAYLOAD_LENGTH +1; i++)
{
packet[i] = rand();
}
#else
uint8_t i = 1;
do
{
UART_read(uart, &input, 1);
UART_write(uart, &input, 1);
packet[i++] = input;
}
while (input != '\r');
UART_write(uart, &input, 6);
packet[0] = i - 1;
RF_cmdPropTxAdv.pktLen = packet[0] + 1;
#endif
/* Send packet */
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTxAdv, RF_PriorityNormal, NULL, 0);
#if 0
/* Update display */
Display_printf(uartDisplayHandle, 0, 0, "Pkts sent: %u", seqNumber);
Display_printf(lcdDisplayHandle, 1, 0, "Pkts sent: %u", seqNumber);
#endif
/* Toggle LED */
PIN_setOutputValue(ledPinHandle, Board_PIN_LED1, !PIN_getOutputValue(Board_PIN_LED1));
}
}
/* Copy the basic RX configuration from CMD_PROP_RX to CMD_PROP_RX_SNIFF command. */
static void initializeTxAdvCmdFromTxCmd(rfc_CMD_PROP_TX_ADV_t* RF_cmdPropTxAdv, rfc_CMD_PROP_TX_t* RF_cmdPropTx)
{
#define RADIO_OP_HEADER_SIZE 14
/* Copy general radio operation header from TX commmand to TX_ADV */
memcpy(RF_cmdPropTxAdv, RF_cmdPropTx, RADIO_OP_HEADER_SIZE);
/* Set command to CMD_PROP_TX_ADV */
RF_cmdPropTxAdv->commandNo = CMD_PROP_TX_ADV;
/* Copy over relevant parameters */
RF_cmdPropTxAdv->pktConf.bFsOff = RF_cmdPropTx->pktConf.bFsOff;
RF_cmdPropTxAdv->pktConf.bUseCrc = RF_cmdPropTx->pktConf.bUseCrc;
RF_cmdPropTxAdv->syncWord = RF_cmdPropTx->syncWord;
}
extern void rxTaskInit();
/*
* ======== main ========
*/
int main(void)
{
/* Call driver init functions. */
Board_initGeneral();
Display_init();
/* Open LED pins */
ledPinHandle = PIN_open(&ledPinState, pinTable);
Assert_isTrue(ledPinHandle != NULL, NULL);
/* Open Button pins */
buttonPinHandle = PIN_open(&buttonPinState, buttonPinTable);
Assert_isTrue(buttonPinHandle != NULL, NULL);
/* Initialize task */
rxTaskInit();
txTaskInit();
/* Start BIOS */
BIOS_start();
return (0);
}
4. Rebuild and download rfWakeOnRadioTx into two LAUNCHXL-CC1310.
5. Open two application UART COM ports simulated by two LAUNCHXL-CC1310
6. You can press BTN-1 on one of LAUNCHXL-CC1310 to input any string ended with "enter" to send the string to another LAUNCHXL-CC1310 to print the received string on UART.
No comments:
Post a Comment