Please note as of Wednesday, August 15th, 2018 this wiki has been set to read only. If you are a TI Employee and require Edit ability please contact x0211426 from the company directory.

SimpleLink-EasyLink

From Texas Instruments Wiki
Jump to: navigation, search

Contents

Introduction

The CC13xx EasyLink API is a simple abstraction layer on top of the CC13xx RF Driver and is intended as a starting point for customers creating a proprietor Sub1G protocol. The EasyLink layer does not support any regional RF conformance such as Listen Before Talk required for the license free frequency band. Customers need to add support for the regional conformance that their product requires under the EasyLink API.

The API and examples are available in TIRTOS for SimpleLink MCU's version 2.14.03.28 and greater, which can be downloaded from: http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/tirtos/index.html

For instruction on using the TIRTOS examples refer to C:\ti\tirtos_simplelink_<version>\docs\tirtos_cc13xx_cc26xx_Getting_Started_Guide.pdf.

The EasyLink Example can be found in the resource explorer under SimpleLink Wireless MCU->CC1310F128->CC1310 Development Kit->Driver Examples->TI Driver Examples->RF Examples:

  1. RF EasyLink Tx
  2. RF EasyLink Rx
  3. RF EasyLink Network Processor
  4. RF Wireless Sensor Network Concentrator
  5. RF Wireless Sensor Network Node

The required HW for running the examples is the CC1310DK: http://www.ti.com/tool/cc1310dk


CC13xx EasyLink API

The EasyLink API is intended to abstract the RF Driver in order to give a simple API for customers to use as is or extend to suit their application

General Behavior

Before using the EasyLink API:

  1. The EasyLink Layer is initialized by calling EasyLink_init(). This initializes and opens the RF driver and configuring a modulation scheme passed to EasyLink_init.
  2. The RX and TX can operate independently of each other.

The following is true for receive operation:

  1. RX is enabled by calling EasyLink_receive() or EasyLink_receiveAsync().
  2. Entering RX can be immediate or scheduled.
  3. EasyLink_receive() is blocking and EasyLink_receiveAsync() is nonblocking.
  4. the EasyLink API does not queue messages so calling another API function while in EasyLink_receiveAsync() will return EasyLink_Status_Busy_Error
  5. an Async operation can be cancelled with EasyLink_abort()

The following apply for transmit operation:

  1. TX is enabled by calling EasyLink_transmit() or EasyLink_transmitAsync().
  2. TX can be immediate or scheduled.
  3. EasyLink_transmit() is blocking and EasyLink_transmitAsync() is nonblocking
  4. EasyLink_transmit() for a scheduled command, or if TX can not start
  5. the EasyLink API does not queue messages so calling another API function while in EasyLink_transmitAsync() will return EasyLink_Status_Busy_Error
  6. an Async operation can be cancelled with EasyLink_abort()

Frame Structure

The EasyLink implements a basic header for transmitting and receiving data. This header supports addressing for a star or point-to-point network with acknowledgements.

Packet structure:

1B Length 1-64b Dst Address Payload

API Functions

API function Description
EasyLink_init() Init's and opens the RF driver and configures the specified phy setting
EasyLink_transmit() Blocking Transmit
EasyLink_transmitAsync() Nonblocking Transmit
EasyLink_receive() Blocking Receive
EasyLink_receiveAsync() Nonblocking Receive
EasyLink_abort() Aborts a non blocking call
EasyLink_GetIeeeAddr() Gets the IEEE Address
EasyLink_EnableRxAddrFilter() Enables/Disables RX filtering on the Addr
EasyLink_SetFreq() Sets the frequency
EasyLink_GetFreq Gets the frequency
EasyLink_SetRfPwr() Sets the Tx Power
EasyLink_GetRfPwr() Gets the Tx Power
EasyLink_getAbsTime() Gets the absolute radio time
EasyLink_setCtrl() Sets advanced configuration options
EasyLink_getCtrl() Gets advanced configuration options

EasyLink_Status EasyLink_init(EasyLink_PhyType ui32ModType)

Initializes the radio with specified Phy settings

This function configures the radio phy settings. If the ui32ModType is EasyLink_Phy_Custom then the configuration is taken from smartf_settings.c/h. If a specific phy configuration is required (and not supported by any of the defined Phy types in EasyLink_PhyType then you can export the RF setting from the SmartRF Studio code export tool, see Using Custom Phy Settings for more detail on configuring the API to support customer phy settins.

param ui32ModType is a set to:

  • EasyLink_Phy_50kbps2gfsk (-110dBm sensitivity)
  • EasyLink_Phy_625bpsLrm (-124dBm sensitivity)
  • EasyLink_Phy_5kbpsSlLr (-119dBm sensitivity)
  • EasyLink_Phy_Custom

returns EasyLink_Status

EasyLink_Status EasyLink_transmit(EasyLink_TxPacket *txPacket)

Sends a Packet with blocking call.

This function is a blocking call to send a packet. If the Tx is successfully scheduled then the function will block until the Tx is complete.

param txPacket - The descriptor for the packet to be Tx'ed.

returns EasyLink_Status

EasyLink_Status EasyLink_transmitAsync(EasyLink_TxPacket *txPacket, EasyLink_TxDoneCb cb)

Sends a Packet with non blocking call.

This function is a non blocking call to send a packet. If the Tx is successfully scheduled then the callback will be call once the Tx is complete.

param txPacket - The descriptor for the packet to be Tx'ed. param cb - The tx done function pointer.

returns EasyLink_Status

EasyLink_Status EasyLink_receive(EasyLink_RxPacket *rxPacket)

brief Blocking call that waits for an Rx Packet.

This function is a blocking call to wait for an Rx packet.

param rxPacket - The descriptor for the packet to be Rx'ed.

returns EasyLink_Status

EasyLink_Status EasyLink_receiveAsync(EasyLink_ReceiveCb cb, uint32_t absTime)

Enables Asynchronous Packet Rx with non blocking call.

This function is a non blocking call to Rx a packet. The Rx is turned on and the Callback is called once a packet is received passing the

param cb - The rx function pointer. param absTime - Start time of Rx (0: now !0: absolute radio time to start Rx)

returns EasyLink_Status

EasyLink_Status EasyLink_abort(void)

Abort a previously call Async Tx/Rx.

This function is a blocking call to abort a previous Async Tx/Rx

returns EasyLink_Status

EasyLink_Status EasyLink_setFrequency(uint32_t ui16Freq)

Sets the Frequency

This function set the radio to the specified frequency. Note that this will be rounded to the nearest frequency supported by the Frequency Synthesizer.

param ui16Freq Frequency in units of kHz

returns EasyLink_Status

uint32_t EasyLink_getFrequency(void)

Gets the Frequency

This function gets Frequency in units of kHz. This function will return the value set in the Frequency Synthesizer, and may not be the same as set using easyLink_setFrequency API. Note that this value does not include any offsets for deviations due to factors such as temperature and hence this API should not be used to get an accurate measure of frequency.

returns Frequency in units of kHz

EasyLink_Status EasyLink_setRfPwr(int8_t i8Power)

Sets the TX Power

This function sets the Tx Power

param i8Power the tx power in dBm's to be set. integers of -10 and between 0-14 dBm are accepted. Values above 14 are rounded to 14 and below 0 are rounded to -10. setting the tx power to 14dBm requires changes to the ccfg, if this is not done then an error is returned, for more information see Enabling 14dBm Transmit Power

returns EasyLink_Status


int8_t EasyLink_getRfPwr(void)

Gets the TX Power

This function gets the Tx Power in dBm, values ranging from -10 to 14 dBm should be expect

returns power in dBm

uint32_t EasyLink_getAbsTime(void)

Gets the absolute radio time

This function returns the absolute radio time and can be used for monitoring or Tx/Rx events using the EasyLink_TxPacket_t and EasyLink_RxPacket_t absTime field.

returns absolute time

EasyLink_Status EasyLink_getIeeeAddr(uint8_t *ieeeAddr)

Gets the IEEE address

This function gets the IEEE address

param ieeeAddr pointer to an 8 element byte array to write the IEEE address to.

returns EasyLink_Status

EasyLink_Status EasyLink_enableRxAddrFilter(uint8_t* pui8AddrFilterTable, uint8_t ui8AddrSize, uint8_t ui8NumAddrs)

Enables the address filter

This function enables the address filter to filter out address that are not in the address table provided.

param pui8AddrFilterTable A uint8 pointer to a variable size 2d array containing the addresses to filter on. param ui8AddrSize The size of the address elements param ui8NumAddrs The number of address elements

returns EasyLink_Status

EasyLink_Status EasyLink_setCtrl(EasyLink_CtrlOption Ctrl, uint32_t ui32Value)

Sets advanced configuration options

This function allows setting some of the advanced configuration options

param Ctrl - The control option to be set param ui32Value - The value to set the control option to

returns EasyLink_Status

EasyLink_Status EasyLink_getCtrl(EasyLink_CtrlOption Ctrl, uint32_t* pui32Value)

Gets advanced configuration options

This function allows getting some of the advanced configuration options

param Ctrl - The control option to get param pui32Value - Pointer to return the control option value

returns EasyLink_Status

Enumeration, Types and Macro's

EASYLINK_API_VERSION

Defines the current version of the API.

EASYLINK_MAX_DATA_LENGTH

Defines the largest Tx/Rx payload that the interface can support.

EASYLINK_MAX_ADDR_SIZE

Defines the Tx/Rx Max Address Size.

EASYLINK_MAX_ADDR_FILTERS

Defines the Max number of Rx Address filters

EasyLink_RadioTime_To_ms(radioTime)

Macro to convert from Radio Time Ticks to ms

EasyLink_ms_To_RadioTime(ms)

Macro to convert from ms to Radio Time Ticks

EasyLink_Status

EasyLink Status and error code enumeration

Enum Description
EasyLink_Status_Success Success
EasyLink_Status_Config_Error Configuration error
EasyLink_Status_Param_Error Param error
EasyLink_Status_Mem_Error Memory Error
EasyLink_Status_Cmd_Error Memory Error
EasyLink_Status_Tx_Error Tx Error
EasyLink_Status_Rx_Error Rx Error
EasyLink_Status_Rx_Timeout Rx Error
EasyLink_Status_Rx_Buffer_Error Rx Buffer Error
EasyLink_Status_Busy_Error Busy Error
EasyLink_Status_Aborted Cmd stopped or aborted

EasyLink_PhyType

Phy Type enumeration passed to EasyLink_init

Enum Description
EasyLink_Phy_50kbps2gfsk Phy settings for 50kbps data rate, IEEE 802.15.4g GFSK.
EasyLink_Phy_625bpsLrm Phy settings for 625bps data rate, Long Range Mode.
EasyLink_Phy_5kbpsSlLr Phy settings for 5kbps data rate, SimpleLink Long Range Mode.
EasyLink_Phy_Custom Customer Phy specific settings exported from SmartRF Studio. For more information refer to Using_Custom_Phy_Settings

EasyLink_TxPacket

Structure for the TX Packet

Type Field Description
uint8_t[8] dstAddr Dst Address
uint32_t absTime Absolute time to Tx packet (0 for immediate)
uint8_t len Payload Length
uint8_t[ EASYLINK_MAX_DATA_LENGTH ] payload Payload Buffer

EasyLink_RxPacket

Structure for the RX'ed Packet

Type Field Description
uint8_t[8] dstAddr Dst Address of RX'ed packet
int8_t rssi rssi of RX'ed packet
uint32_t absTime Absolute time to turn on Rx (0 for immediate). When a packet is Received this will be over written with the Radio Time that packet was Received, this can be used in conjunction with the EasyLink_getAbsTime API which gets the current radio time.
uint32_t rxTimeout Relative time in ticks from Rx start to Rx TimeOut a value of 0 means no timeout
uint8_t len length of RX'ed packet
uint8_t[ EASYLINK_MAX_DATA_LENGTH ] payload payload of RX'ed packet

EasyLink_ReceiveCb

EasyLink Callback function type for Received packet, registered EasyLink_receiveAsync()

typedef void (*EasyLink_ReceiveCb)(EasyLink_RxPacket * rxPacket,
        EasyLink_Status status);

EasyLink_TxDoneCb

EasyLink Callback function type for Tx Done registered with EasyLink_transmitAsync()

typedef void (*EasyLink_TxDoneCb)(EasyLink_Status status);

EasyLink_CtrlOption

Advance configuration options enumeration

Enum Description
EasyLink_Ctrl_AddSize Set the number of bytes in Addr for both Addr Filter and Tx/Rx operations
EasyLink_Ctrl_Idle_TimeOut Set the time for Radio to return to idle after
EasyLink_Ctrl_Test_Tone Enable/Disable Test mode for Tone
EasyLink_Ctrl_Test_Signal Enable/Disable Test mode for Signal
EasyLink_Ctrl_MultiClient_Mode Set Multiclient mode for applications that will use multiple RF clients. Must be set before calling EasyLink_init.


Examples

The following examples have been provided to show how the API can be used in an application

  • rfEasyLinkNp AT Network Processor Example
  • rfEasyLinkTx Example
  • rfEasyLinkRx Example
  • Sensor Node Example
  • Sensor Collector Example

These examples can be imported, built and downloaded using the CCS or IAR IDE's. For more information on importing, building and downloading CC13xx TI RTOS examples refer to the TIRTOS documentation (available after installing): C:\ti\tirtos_simplelink_2_14_03_28\docs\tirtos_cc13xx_cc26xx_Getting_Started_Guide.pdf

The following sections describe the usage and design details of the EasyLink examples.

rfEasyLinkNp AT Network Processor Example

In the rfEasyLinkNp Example the EasyLink API has been exposed over an AT Command Interface such that it can be exercised by Host SW (running on an PC, MPU or MCU) or by using a serial terminal emulator.

Example Usage

Open a serial session (e.g. HyperTerminal,puTTY, etc.) to the appropriate COM port. Note: the COM port can be determine via Device Manager in Windows or via ls /dev/tty* in Linux.

The serial connection should have the following settings:

    Baud-rate:  115200
    Data bits:       8
    Stop bits:       1
    Parity:       None
    Flow Control: None

If the serial session is started before the target completes initialization, the reset indication and version number is displayed:

    RESET:vxx.xx.xx

The EM reset button can be pressed on the SmartRF06 to see the reset message.

By default the target echoes back any character that is typed in the serial session. This can be disabled with the AE parameter described later.

AT API

The AT Command Interface uses ASCII characters so that a terminal emulator can send the commands, but also uses framing so that SW can format and parse the AT commands.

The frame format is shown below

Start of Frame Command Type Command ID parameters End Of Frame
"AT" 'P'/'+' "i" "0001" <CR>

AT which stands for "ATtention" is used as the start of frame delimiter, and a Carriage Return '\r' is used as the end of frame delimiter.

An example command is:

    AT+I 0001<CR>

The EasyLink AT Command Interface uses 2 command types:


  1. Pxx: Parameters
  2. +xx: Control Commands

AT Parameters

Parameters offer set and get functionality.

The format of a parameter read command to get the TxPower parameter is:

ATPPW?<CR>

The response to a parameter read will be of the format shown below, depending on the parameter it will be hex or decimal:

-10<CR>

The format of an AT command to set the Frequency Parameter to 868MHz is:

ATPFR=868000000<CR>

The response to a parameter write will be of the format:

OK<CR>

The registers exposed for the EasyLink API are:

Param R/W Description Parameters (s)
ST R Read The last EasyLink status returned EasyLink status in 4B hex:
   Success = 0000
   Config_Error = 0001
   Param_Error = 0002
   Mem_Error = 0003
   Cmd_Error = 0004
   Tx_Error = 0005
   Rx_Error = 0006
   Rx_Timeout = 0007
   Rx_Buffer_Error = 0008
   Busy_Error = 0009
   Aborted = 000a
AE R/W UART Echo Enable 0 or 1 to enable/disable echo
FR R/W Read/Write frequency in kHz Frequency in 1B hex
PW R/W Read/Write tx power in dBm Power in decimal between -10 to 14dBm. Note ccfg changes are required for 14dBm outpur power
BM R/W Read/Write data mode for Tx/Rx data Mode in 1B hex
   0:ASCII 
   1:Binary
IE R Read IEEE address None
AS R Read address size in Bytes None
TS R/W Read/Write Tx address 1-8B Tx address in hex
RT R Read current radio time None
TY R/W Read/Write Time Type Time in 1B hex
   0:Absolute Time 
   1:Relative Time 
TT R/W Absolute or relative (based on Time Type) radio time to Tx a packet Absolute/relative time in units of 4MHz ticks in decimal OR 0 for immediate
TR R/W Absolute or relative (based on Time Type) radio time to Rx a packet
RO R/W Relative time for Rx timeout Relative time in units of 4MHz ticks in decimal OR 0 for never
LA R Destination address of last Rx'ed message None
LT R Read absolute radio time of last Rx'ed message None
LR R Read RSSI of last Rx'ed message None
F0 R/W Read/Write address filter 0 1-8B address in hex
F1 R/W Read/Write address filter 1 1-8B address in hex
F2 R/W Read/Write address filter 2 1-8B address in hex
TM R/W Read/Write test mode Test mode in 1B hex
   0:None/Cancel
   1:Tone/Carrier Wave        
   2:Modulated Signal         
   3:PER Tx                   
   4:PER Rx                   
PI R/W Read/Write PER Tx Bursts Interval 1B time between PER bursts in units of ms in Decimal
PB R/W Read/Write PER Tx Burst Size 1B Tx Burst Size in Hex
PP R/W Read/Write Number of PER Tx/Rx Packets 1B Tx/Rx Packets in Hex
PL R/W Read/Write PER Tx/Rx Packet Length 1B Tx/Rx Packet Length in Hex
GM00-03 R/W Read/Write GPIO Mode 0:1 GPIO Value input/outpu
GV00-03 R/W Read/Write GPIO Value 0:1 GPIO Value

It is important to note that most Register Commands call underlying EasyLink functions that require the Initialize Command "AT+I x" to be run.

AT Control Command

The format of Control Commands are:

    AT+I 00<CR>

The response will be like:

    OK<CR>


The Commands exposed for the EasyLink AT API are:

Command Description Parameter(s)
i/I Initialize the Radio Phy setting
   00: For 50kbps 2-GFSK
   01: For 625bps Long Range Mode
   02: For User defined from SmartRF_Settings.c/h
tx/TX Send a message to Tx Address (PARAM PTA) at Tx Time (Param PTT) or Immediate if 0 or expired x Data Bytes
rx/RX Turn on Radio to Receive Data at Rx Time set by Parameter `PRT` (orImmediate if 0), with timeout set by Parameter "PRO" None
rs/RS Reset the CC13xx None

Command Responses

Response for Register Write and Control Commands are formatted as:

Response Description
OK<CR> Command or Register write successful
Error 0001<CR> Command or register read/write failed due to bad formatting
Error 0002<CR> Command or register read/write failed due to bad length
Error 0003<CR> Command or register write failed due to a parameter Error
Error 0004<CR> Command or register write failed due to a Memory Error
Error 0005<CR> Command or register write failed due to Error From EasyLink API (EasyLink error is stored in Parameter "ST")

The response to the "rx"\"RX" (receive) Command is of the format:

- For ASCII Data Mode:

    RX: Hello World<CR>
    OK<CR>

- For Binary Data Mode:

    RX: 2fbb1aa8ec84045fb0c3e5236cb8cc5b3c<CR>
    OK<CR>

The response to the "rs"\"RX" (reset) Command is of format:

- For ASCII Data Mode:

    RESET:vxx.xx.xx<CR>

Where vxx.xx.xx is the version number of the EasyLink API


Test Modes

The EasyLink AT interface supports the following test modes:

  1. Carrier Wave
  2. Modulated Signal
  3. PER Tx
  4. PER Rx

Before running these commands you must first initialize the device using:

    AT+I x<CR>

where x indicates the Phy settings used.

Carrier Wave

This is enabled by Setting test mode to 1. To configure the Carrier Wave test mode use:

    ATPTM=1<CR>

To exit the Carrier Wave test mode:

    ATPTM=0<CR>

Modulated Signal

This is enabled by Setting test mode to 2. To configure the Modulated Signal test mode use:

    ATPTM=2<CR>

To exit the Modulated Signal test mode:

    ATPTM=0<CR>

PER Tx

This is enabled by setting test mode to 3, it will run for the number of packets configure in the `PP` Parameter, or indefinitely if the number of packets is set to 0. To configure PER Tx test mode to run for 100 packets:

    ATPPP=100<CR>
    ATPTM=3<CR>

While the test is running the below responses should be expected:

    TPER: 00
    TPER: 01
    TPER: 02
    ...

Once the test completes the below response should be expected.

    TPER: Done OK<CR>

Related Parameters to this test are:

  1. PPL: PER Tx Packet Length
  2. PPB: PER Tx Burst size
  3. PPI: Interval in ms between bursts

PER Rx

This is enabled by setting test mode to 4, it will run for the number of packets configure in the `PP` Parameter, or indefinitely number of packets is set to 0. To configure PER Rx test mode to run for 100 packets:

    ATPPP=100<CR>
    ATPTM=4<CR>

While the test is running the below responses should be expected:

    RPER: 00, 0001, 0000, -31
    RPER: 01, 0002, 0000, -31
    RPER: 02, 0003, 0000, -31
    ...

The columns are:

RPER Sequence Number Pass Count Fail Count RSSI

The sequence number is sent from the Tx PER, and is expected to increment by 1 in each packet. Pass Count increments every time a correct sequence number is received. Fail Count increments every time an incorrect sequence number is received.

Once the test completes the below response should be expected.

    <RPER>: Done OK


rfEasyLinkTx Example

The rfEasyLinkTx Example includes the EasyLink API and is used to configure the RF driver to transmit packets. This project should be run in conjunction with the rfEasyLinkRx project.

Example Usage

Run the example. Board_LED1 will toggle every 100ms indicating a packet has been transmitted, this will happen 10 times. The 11th Tx will then be aborted after 300ms toggling Board_LED2. This cycle will continue.

Before running this application you should first start the rfEasyLinkRx on a second board to see that the transmitted packets are received.

The following table explains the function of the LED's in this example:

LED Function
Board_LED1 Indicates that a Packet has been transmitted
Board_LED2 Indicates an abort which is expected after transmitting 10 packets
Board_LED3 Indicates an error

Application Design Details

This example shows how to use the EasyLink API to access the RF drive, set the frequency and Tx packets. The RFEASYLINKTX_ASYNC define is used to select the Blocking or Nonblocking (Async) Tx API.

The rfEasyLinkTx example will transmit a packet every 100ms for 10 packets, if RFEASYLINKTX_ASYNC is defined (as it is by default) then the 11th Tx will be scheduled to Tx in 1s, but will be aborted after 300ms, this is to shows an example of aborting a scheduled Tx. Board_LED2 will toggle when a Tx abort happens. LED3 indicates an error, this is not expected to happen. The Tx/abort cycle will repeat indefinitely.

A single task, "rfEasyLinkTxFnx", configures the RF driver through the EasyLink API and transmits messages.

rfEasyLinkRx Example

The rfEasyLinkRx Example includes the EasyLink API and uses it to configure the RF driver to Rx packets. This project should be run in conjunction with the rfEasyLinkTx project.

Example Usage

Run the example. Board_LED1 will toggle indicating a packet has been received, Board_LED2 will toggle indicating an abort, which is expected to happen if a packet is not received within 300ms of the Rx being scheduled. Board_LED3 indicates an error, this is not expected to happen under normal conditions, but may occur if there is some interference.

After running this application you should start the rfEasyLinkTx on a second board to transmit packets. Until the rfEasyLinkTx has been started the Rx will be continually aborted.

The following table explains the function of the LED's in this example:

LED Function
Board_LED1 Indicates that a Packet has been received
Board_LED2 Indicates an abort which is expected if a packet is not received within 300ms of calling the receive function
Board_LED3 Indicates an error

Application Design Details

This example shows how to use the EasyLink API to access the RF drive, set the frequency and receive packets. The board will blink Board_LED1 when a packet has been received. When a second board is running rfEasyLinkTx example then the expected behavior is that Board_LED1 will blink every 100ms 10 times, the rfEasyLinkTx example will then wait for 300ms before aborting and Transmitting the next packets and if RFEASYLINKRX_ASYNC is defined (as it is by default) then this will cause the rfEasyLinkRx example to timeout and exercise the EasyLink_abort API. When an Rx has been aborted Board_LED2 should toggle. The rfEasyLinkTx board will then Tx another burst of 10 packets and Board_LED1 should blink another 10 times and the cycle should repeat.

If RFEASYLINKRX_ADDR_FILTER is defined (as it is by default) then the RX Address filter will be enabled for address 0xaa. This will cause the rfEasyLinkRx to only accept packets with a destination address of 0xaa, which the rfEasyLinkTx example transmits. When using the rfEasyLinkTx example there will be no difference in behavior when defining/undefining RFEASYLINKRX_ADDR_FILTER as the rfEasyLinkTx example will use a destination address of 0xaa. However if transmitting from another source like SmartRF Studio and not using an address of 0xaa then defining RFEASYLINKRX_ADDR_FILTER will result in packets not being received.

A single task, "rfEasyLinkRxFnx", configures the RF driver through the EasyLink API and receives messages.

rfWsnConcentrator Wireless Sensor Network Concentrator Example

The WSN Concentrator example illustrates how to create a simple Wireless Sensor Network Concentrator device which listens for packets from other nodes. This example is meant to be used together with the WSN Node example to form a one- to-many network where the nodes send messages to the concentrator.

This examples showcases the use of several Tasks, Semaphores and Events to receive packets, send acknowledgements and display the received data on the LCD. For the radio layer, this example uses the EasyLink API which provides an easy-to-use API for the most frequently used radio operations.

Packet format

The WSN examples (Concentrator and Node) use the following packet format:

Start Byte Index Length Name Description
0 1 Length Total packet length counted from this byte to the last byte
1 1 Destination Destination address - RADIO_CONCENTRATOR_ADDRESS (0x00) for Concentrator, others for Node
2 1 Source Source Address - RADIO_CONCENTRATOR_ADDRESS (0x00) for Concentrator, others for Node
3 1 Type Packet Type - RADIO_PACKET_TYPE_ACK_PACKET(0), RADIO_PACKET_TYPE_ADC_SENSOR_PACKET(1)
4 N Data Packet data bytes - 2 bytes for ADC Value sent from Node to Concentrator, 0 byte for ACK packet sent from Concentrator to Node.


Example Usage

Run the example. On another board (or several boards) run the WSN Node example. The LCD will show the discovered node(s).

When the collector receives data from a new node, it is given a new row on the display and the received value is shown. If more than 7 nodes are detected, the device list rolls over, overriding the first.

Whenever an updated value is received from a node, it is updated on the LCD display:

Nodes    Value    RSSI
226      350      -69
124      201      -71


Application Design Details

This examples consists of two tasks, one application task and one radio protocol task.

The ConcentratorRadioTask handles the radio protocol. This sets up the EasyLink API and uses it to always wait for packets on a set frequency. When it receives a valid packet, it sends an ACK and then forwards it to the ConcentratorTask.

The ConentratorTask receives packets from the ConcentratorRadioTask and displays the data on the LCD.

The default frequency is 868.0 MHz, in order to change the frequency, please see "RadioProtocol.h". This can also be used to change the PHY settings to be either the default IEEE 802.15.4g 50kbit, Long Range Mode or custom settings. In the case of custom settings, the "smartrf_settings.c" file is used. This can be changed either by exporting from Smart RF Studio or directly in the file.


rfWsnNodeWireless Sensor Network Node Example

The WSN Node example illustrates how to create a Wireless Sensor Network Node device which sends packets to a concentrator. This example is meant to be used together with the WSN Concentrator example to form a one- to-many network where the nodes send messages to the concentrator.

This examples showcases the use of several Tasks, Semaphores and Events to get sensor updates and send packets with acknowledgement from the concentrator. For the radio layer, this example uses the EasyLink API which provides an easy-to-use API for the most frequently used radio operations.

For more information on the EasyLink API and usage refer to http://processors.wiki.ti.com/index.php/SimpleLink-EasyLink

Example Usage

Run the example. On another board run the WSN Concentrator example. This node should show up on the LCD of the Concentrator.

When the Node sends a packet, it also toggles LED 3. An SCE task is used to measure the Analog Light Sensor using the ADC.

Application Design Details

This examples consists of two tasks, one application task and one radio protocol task. It also consists of an Sensor Controller Engine, SCE, Task which samples the ADC.

The ADC task on the SCE checks the ADC value once per second. If this value has changed by a certain, maskable, amount since the last time it notified the CM3, then it wakes it up again. If the change is less than the masked value, then it does not wake up the CM3.

The NodeTask waits to be woken up by the SCE. When it wakes up it toggles LED3 and sends the new ADC value to the NodeRadioTask.

The NodeRadioTask handles the radio protocol. This sets up the EasyLink API and uses it to send new ADC values to the concentrator. After each sent packet it waits for an ACK packet back. If it does not get one, then it retries three times. If it did not receive an ACK by then, then it gives up.

The default frequency is 868.0 MHz, in order to change the frequency, please see "RadioProtocol.h". This can also be used to change the PHY settings to be either the default IEEE 802.15.4g 50kbit, Long Range Mode or custom settings. In the case of custom settings, the "smartrf_settings.c" file is used. This can be changed either by exporting from Smart RF Studio or directly in the file.

Using Custom Phy Settings

Currently the EasyLink API supports 2 Phy types and a custome Phy type:

  • 50kbps 2-GFSK: Initialized with EasyLink_init(EasyLink_Phy_50kbps2gfsk)
  • 625bps Long Range Mode: Initialized with EasyLink_init(EasyLink_Phy_625bpsLrm)
  • Custom: Initialized with EasyLink_init(EasyLink_Phy_Custom)

If a custom/user defined Phy setting is needed then this can be added as the EasyLink_Phy_Custom setting. The Phy settings can be generated using SmarfRF Studio: http://www.ti.com/tool/smartrftm-studio

Following the documentation to generate your phy settings and export the smartrf_settings.c/h. The files should then be copied into the smartrf_settings\ folder of your example, e.g.:

    \rfEasyLinkNp_CC1310DK_TI_CC1310F128\smartrf_settings\

The example should then initialize the EasyLink API with

    EasyLink_init(EasyLink_Phy_Custom)

And then be rebuilt.

This will cause the EasyLink API to use the RF_prop, RF_cmdPropRadioDivSetup and RF_cmdFs commands that have been defined and exported in SmartRF Studio, as well as the Synchword from the RF_cmdPropTx and RF_cmdPropRx commands.

Enabling 14dBm Transmit Power

With the default ccfg settings the transmit power is limited to 12dBm, if EasyLink_SetRfPwr() is called with a power > 12dBm then an EasyLink_Status of EasyLink_Status_Param_Error will be returned. In order to set the transmit power to 14dBm you will need to define CCFG_FORCE_VDDR_HH=1 in the application project options.


Known Issues

tirtos_simplelink_2_14_03_28

With default settings the AT Rx command will only receive a packet with more than 7 Bytes

By default the rfEasyLinkNp example will only Receive a packet with greater than 7 Bytes. This is due to a bug during the initialization where the Rx Address Size is wrongly defaulted to 8. The Default Tx Address size is 1 Byte, so to fulfill the Rx Address size and allow an packet to be received one must Tx 7 Bytes (1B Tx Address + 7 Bytes data).To fix this on the AT command interface set the Address size to 1 with:

ATPAS=1

Alternatively to fix this in the code add the below patch to easylink.c:

--- a/common/easylink/easylink.c
+++ b/common/easylink/easylink.c
@@ -463,11 +463,13 @@ EasyLink_Status EasyLink_init(EasyLink_PhyType ui32ModType)
     EasyLink_cmdPropRxAdv.maxPktLen = EASYLINK_MAX_DATA_LENGTH +
             EASYLINK_MAX_ADDR_SIZE;
     EasyLink_cmdPropRxAdv.pAddr = addrFilterTable;
-    EasyLink_cmdPropRxAdv.addrConf.addrSize = 8; //default addr size is 8
+    addrSize = 1;
+    EasyLink_cmdPropRxAdv.addrConf.addrSize = addrSize; //Set addr size to the
+                                                        //default

The AT PER Rx will stall after the first packet

The rfEasyLinkNp example PER Rx stalls after receiving the first packet. This is because the
rxPacket.absTime
is not set to 0 after the first packet is received. To fix this issue apply the following change to Per.c:
--- a/easylink_atnp/source/per.c
+++ b/easylink_atnp/source/per.c
@@ -139,10 +139,9 @@ uint32_t Per_testRx(uint32_t numPkts)

     uint32_t easyLinkStatus = EasyLink_Status_Success;
     uint8_t *seqNumber = rxPacket.payload;
    while( ((numPkts == 0) || (*seqNumber < (numPkts-1))) &&
            (easyLinkStatus == EasyLink_Status_Success))
-
+        rxPacket.absTime = 0;
         if ((easyLinkStatus = EasyLink_receive(&rxPacket)) == EasyLink_Status_Success)
         {
             if(perRxStats.rcvdPkts == 0)

The Rx Example will stall after the first packet when RFEASYLINKRX_ASYNC is not defined

The rfEasyLinkRx example will stalls after receiving the first packet when RFEASYLINKRX_ASYNC is not defined. This is because the
rxPacket.absTime
is not set to 0 after the first packet is received. To fix this issue apply the following change to rfEasyLinkRx.c:
--- a/easylink_rx/source/rfEasyLinkRx.c
+++ b/easylink_rx/source/rfEasyLinkRx.c
@@ -156,6 +156,7 @@ static void rfEasyLinkRxFnx(UArg arg0, UArg arg1)
             Semaphore_pend(rxDoneSem, BIOS_WAIT_FOREVER);
         }
#else
+        rxPacket.absTime = 0;
         EasyLink_Status result = EasyLink_receive(&rxPacket);

         if (result == EasyLink_Status_Success)

The AT PER Rx will exit on CRC error

The rfEasyLinkNp example PER Rx exits after receiving an error. To fix this issue apply the following change to Per.c:

--- a/easylink_atnp/source/per.c
+++ b/easylink_atnp/source/per.c
@@ -139,8 +139,7 @@ uint32_t Per_testRx(uint32_t numPkts)

     uint32_t easyLinkStatus = EasyLink_Status_Success;
     uint8_t *seqNumber = rxPacket.payload;
-    while( ((numPkts == 0) || (*seqNumber < (numPkts-1))) &&
-           (easyLinkStatus == EasyLink_Status_Success))
+    while( (numPkts == 0) || (*seqNumber < (numPkts-1)) )
     {
         rxPacket.absTime = 0;
         if ((easyLinkStatus = EasyLink_receive(&rxPacket)) == EasyLink_Status_Success)
@@ -157,14 +156,20 @@ uint32_t Per_testRx(uint32_t numPkts)
             perRxStats.rssiSum += rxPacket.rssi;
             perRxStats.expectedSeqNum++;
             perRxStats.rcvdPkts++;
-
-            //Increase and print the SeqNumber
-            AtTerm_sendStringUi8Value("RPER: ", (uint8_t) *seqNumber, 16);
-            AtTerm_sendStringUi16Value(", ", (uint32_t) perRxStats.rcvdPkts, 16);
-            AtTerm_sendStringUi16Value(", ", (uint32_t) perRxStats.lostPkts, 16);
-            AtTerm_sendStringI8Value(", ", (uint32_t) rxPacket.rssi, 10);
-            AtTerm_sendString("\r");
         }
+        else //!EasyLink_Status_Success
+        {
+            //Increase lost packet and print
+            perRxStats.expectedSeqNum++;
+            perRxStats.lostPkts++;
+        }
+
+        //Print results
+        AtTerm_sendStringUi8Value("RPER: ", (uint8_t) *seqNumber, 16);
+        AtTerm_sendStringUi16Value(", ", (uint32_t) perRxStats.rcvdPkts, 16);
+        AtTerm_sendStringUi16Value(", ", (uint32_t) perRxStats.lostPkts, 16);
+        AtTerm_sendStringI8Value(", ", (uint32_t) rxPacket.rssi, 10);
+        AtTerm_sendString("\r");
     }

     if( (easyLinkStatus == EasyLink_Status_Success) && (perRxStats.lostPkts == 0) )

The Rx Example drops the second packet in the burst

The rfEasyLinkRx example will drop the second packet in the burst after an abort. This is because the abort cause the txDoneCb to be called, and the txDoneSem to be released. This then means that the
 Semaphore_pend(txDoneSem, (300000 / Clock_tickPeriod)) 
unblocks immediately before the packet is sent and the RF command is over written with the next Tx packet. To fix this issue you must consume the txDoneSem after the abort:
--- a/easylink_rx/source/rfEasyLinkRx.c
+++ b/easylink_rx/source/rfEasyLinkRx.c
@@ -169,12 +169,18 @@
         EasyLink_transmitAsync(&txPacket, txDoneCb);
         /* Wait 300ms for Tx to complete */
         if(Semaphore_pend(txDoneSem, (300000 / Clock_tickPeriod)) == FALSE)
         {
             /* TX timed out, abort */
             EasyLink_abort();
+
+            /*
+             * Abort will cause the txDoneCb to be called, and the txDoneSem to
+             * Be released. So we must consume the txDoneSem
+             * */
+            Semaphore_pend(txDoneSem,  BIOS_WAIT_FOREVER);
         }
 #else
         EasyLink_Status result = EasyLink_transmit(&txPacket);

The Rx Example bursts 11 packets and not 10

The rfEasyLinkRx Example transmits 11 packets in the burts, when combined with "The Rx Example drops the second packet in the burst" issue you will see 10 packets sent.

--- a/easylink_rx/source/rfEasyLinkRx.c
+++ b/easylink_rx/source/rfEasyLinkRx.c
@@ -149,13 +149,13 @@
         }
 
         txPacket.len = RFEASYLINKTXPAYLOAD_LENGTH;
         txPacket.dstAddr[0] = 0xaa;
 
         /* Add a Tx delay for > 500ms, so that the abort kicks in and brakes the burst */
-        if(txBurstSize++ > RFEASYLINKTX_BURST_SIZE)
+        if(txBurstSize++ >= RFEASYLINKTX_BURST_SIZE)
         {
           /* Set Tx absolute time to current time + 1s */
           txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(1000);
           txBurstSize = 0;
         }
         /* Else set the next packet in burst to Tx in 100ms */