NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.
SimpleLink-EasyLink
Contents
- 1 Introduction
- 2 CC13xx EasyLink API
- 2.1 General Behavior
- 2.2 Frame Structure
- 2.3 API Functions
- 2.3.1 EasyLink_Status EasyLink_init(EasyLink_PhyType ui32ModType)
- 2.3.2 EasyLink_Status EasyLink_transmit(EasyLink_TxPacket *txPacket)
- 2.3.3 EasyLink_Status EasyLink_transmitAsync(EasyLink_TxPacket *txPacket, EasyLink_TxDoneCb cb)
- 2.3.4 EasyLink_Status EasyLink_receive(EasyLink_RxPacket *rxPacket)
- 2.3.5 EasyLink_Status EasyLink_receiveAsync(EasyLink_ReceiveCb cb, uint32_t absTime)
- 2.3.6 EasyLink_Status EasyLink_abort(void)
- 2.3.7 EasyLink_Status EasyLink_setFrequency(uint32_t ui16Freq)
- 2.3.8 uint32_t EasyLink_getFrequency(void)
- 2.3.9 EasyLink_Status EasyLink_setRfPwr(int8_t i8Power)
- 2.3.10 int8_t EasyLink_getRfPwr(void)
- 2.3.11 uint32_t EasyLink_getAbsTime(void)
- 2.3.12 EasyLink_Status EasyLink_getIeeeAddr(uint8_t *ieeeAddr)
- 2.3.13 EasyLink_Status EasyLink_enableRxAddrFilter(uint8_t* pui8AddrFilterTable, uint8_t ui8AddrSize, uint8_t ui8NumAddrs)
- 2.3.14 EasyLink_Status EasyLink_setCtrl(EasyLink_CtrlOption Ctrl, uint32_t ui32Value)
- 2.3.15 EasyLink_Status EasyLink_getCtrl(EasyLink_CtrlOption Ctrl, uint32_t* pui32Value)
- 2.4 Enumeration, Types and Macro's
- 2.4.1 EASYLINK_API_VERSION
- 2.4.2 EASYLINK_MAX_DATA_LENGTH
- 2.4.3 EASYLINK_MAX_ADDR_SIZE
- 2.4.4 EASYLINK_MAX_ADDR_FILTERS
- 2.4.5 EasyLink_RadioTime_To_ms(radioTime)
- 2.4.6 EasyLink_ms_To_RadioTime(ms)
- 2.4.7 EasyLink_Status
- 2.4.8 EasyLink_PhyType
- 2.4.9 EasyLink_TxPacket
- 2.4.10 EasyLink_RxPacket
- 2.4.11 EasyLink_ReceiveCb
- 2.4.12 EasyLink_TxDoneCb
- 2.4.13 EasyLink_CtrlOption
- 3 Examples
- 4 Using Custom Phy Settings
- 5 Enabling 14dBm Transmit Power
- 6 Known Issues
- 6.1 tirtos_simplelink_2_14_03_28
- 6.1.1 With default settings the AT Rx command will only receive a packet with more than 7 Bytes
- 6.1.2 The AT PER Rx will stall after the first packet
- 6.1.3 The Rx Example will stall after the first packet when RFEASYLINKRX_ASYNC is not defined
- 6.1.4 The AT PER Rx will exit on CRC error
- 6.1.5 The Rx Example drops the second packet in the burst
- 6.1.6 The Rx Example bursts 11 packets and not 10
- 6.1 tirtos_simplelink_2_14_03_28
Introduction[edit]
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:
- RF EasyLink Tx
- RF EasyLink Rx
- RF EasyLink Network Processor
- RF Wireless Sensor Network Concentrator
- RF Wireless Sensor Network Node
The required HW for running the examples is the CC1310DK: http://www.ti.com/tool/cc1310dk
CC13xx EasyLink API[edit]
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[edit]
Before using the EasyLink API:
- 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.
- The RX and TX can operate independently of each other.
The following is true for receive operation:
- RX is enabled by calling EasyLink_receive() or EasyLink_receiveAsync().
- Entering RX can be immediate or scheduled.
- EasyLink_receive() is blocking and EasyLink_receiveAsync() is nonblocking.
- the EasyLink API does not queue messages so calling another API function while in EasyLink_receiveAsync() will return EasyLink_Status_Busy_Error
- an Async operation can be cancelled with EasyLink_abort()
The following apply for transmit operation:
- TX is enabled by calling EasyLink_transmit() or EasyLink_transmitAsync().
- TX can be immediate or scheduled.
- EasyLink_transmit() is blocking and EasyLink_transmitAsync() is nonblocking
- EasyLink_transmit() for a scheduled command, or if TX can not start
- the EasyLink API does not queue messages so calling another API function while in EasyLink_transmitAsync() will return EasyLink_Status_Busy_Error
- an Async operation can be cancelled with EasyLink_abort()
Frame Structure[edit]
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[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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)[edit]
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[edit]
EASYLINK_API_VERSION[edit]
Defines the current version of the API.
EASYLINK_MAX_DATA_LENGTH[edit]
Defines the largest Tx/Rx payload that the interface can support.
EASYLINK_MAX_ADDR_SIZE[edit]
Defines the Tx/Rx Max Address Size.
EASYLINK_MAX_ADDR_FILTERS[edit]
Defines the Max number of Rx Address filters
EasyLink_RadioTime_To_ms(radioTime)[edit]
Macro to convert from Radio Time Ticks to ms
EasyLink_ms_To_RadioTime(ms)[edit]
Macro to convert from ms to Radio Time Ticks
EasyLink_Status[edit]
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[edit]
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[edit]
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[edit]
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[edit]
EasyLink Callback function type for Received packet, registered EasyLink_receiveAsync()
typedef void (*EasyLink_ReceiveCb)(EasyLink_RxPacket * rxPacket, EasyLink_Status status);
EasyLink_TxDoneCb[edit]
EasyLink Callback function type for Tx Done registered with EasyLink_transmitAsync()
typedef void (*EasyLink_TxDoneCb)(EasyLink_Status status);
EasyLink_CtrlOption[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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:
- Pxx: Parameters
- +xx: Control Commands
AT Parameters[edit]
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[edit]
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[edit]
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[edit]
The EasyLink AT interface supports the following test modes:
- Carrier Wave
- Modulated Signal
- PER Tx
- 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[edit]
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[edit]
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[edit]
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:
- PPL: PER Tx Packet Length
- PPB: PER Tx Burst size
- PPI: Interval in ms between bursts
PER Rx[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
tirtos_simplelink_2_14_03_28[edit]
With default settings the AT Rx command will only receive a packet with more than 7 Bytes[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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[edit]
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 */