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.

RF4CE, simple linux target application

From Texas Instruments Wiki
Jump to: navigation, search

--Calimero 11:28, 6 June 2012 (CDT)

Introduction

Purpose of this page is to explain how to implement a simple RF4CE target application on a linux host.

Two linux hosts are considered:

- a Ubuntu PC host,
- a Beagleboard host based on an angstrom distribution.

The RF4CE network will be created using a CC253x device.

For the Ubuntu PC host, a CC2531USB dongle will be used. The dongle will be flash with a RNP image therefore the dongle appears as a serial device (USB-CDC class device).

For the beagle board, 3 interfaces can be used: UART, I2C and SPI. For UART a CC2531USB dongle is used For I2C and SPI a smartRF board with a CC2533EM is used.

all possible interface are describe below.

Beagle Board.png

Information about beagleboard; beagleboard.org/


The source code of this simple application is available freely. it is actually based on a BSD licence. In all cases, user should check the header of each file the licence agreement.

Software Architecture Overview

RemoTI Network Processor Architecture

The architecture used is a Host + RNP architecture (RNP: RemoTI Network Processor).

The RF4CE network layer and profile are manage by the RNP, the host is driving the RNP using the remoTI API.

Here is an overview of the architecture:

RF4CE Host RNP Architecture.png

For full details, please read the following user guide and API:


The following documents can be found inside the remoTI SDK: 

  • RemoTI API
  • RemoTI Network Processor Interface Spec


Linux Software Architecture

Following diagram represents an overview of the linux software architecture

RF4CE RNP Linux Software overview.png


The linux software is split in two executables:

  • a NPI server , that will create a IP socket and connect it to the requested Bus
  • a NPI client, that will run the remoTI application.


The NPI client sends all commands to the socket. The NPI server will take care of translating them to the RNP.

The NPI client still use the remoTI interface to drive the RNP.

This architecture is very flexible, the NPI server is always available. This has for benefits to abstract the HW layer from the application. The application does not need to be compile/link with the HW bus anymore.

Also, the IP socket can be accessible from the same network: a NPI client on a different platform can access the NPI server.

RemoTI Network Processor interface

Three Interface can be used to connect to a RNP device: UART, SPI and I2C.

UART

There is two possible ways to use UART:

  • over the USB bus , by using the USB-CDC driver (and the CC2531USB dongle)
  • over a physical UART, by connecting directly to the UART port of the CC253x device.(all cc253x device have at least 1 physical UART port).

In this example, the CC2531USB dongle is used (for both the beagle board and the Ubuntu PC host):

ZID Dongle.JPG

 SPI and I2C

SPI and I2C cannot be use on our Ubuntu PC host since we do not have any I2C or SPI physical connection. SPI and I2C bus need to be physically connected between the beagle board and the RNP. A smartRf board is used with a CC253xEM board (SmartRF05 user guide). a CC2533EM or CC2530EM can be used for SPI, whereas only a CC2533 can be used for I2C (only CC2533 has a hardware I2C interface: cc2533 datasheet)

SmartRF05 Evaluation Board Trainee board for beagleboard 

CC253x are using a 3.3V logic, where the OMPA is using a 5V Logic. Therefore a level shifter need to be used. For this purpose, a trainer board is connected to the beagle board.

More information about this board can be find here; http://elinux.org/BeagleBoard_Trainer

Some GPIOs are also needed beside the SPI/I2C physical connection:

  • Slave Ready (SRDY, from RNP to host): This signal wake up the Host and signal it that new data (from the RNP) are pending.
  • Master Ready (MRDY, from Host to RNP): this signal wake up the RNP and signal it that new data (from the host) are pending.
  • Reset Signal: (RESET, host to RNP), connected to the Reset line of the RNP.

Following is the summary of the connections that need to be done between the SmartRf board and the trainer board.

Colored cells show which pins need to be connected. Other value are here for reference or for debug purpose.

SPI interface Connection
Smart RF

CC253x Config EM Board TRAINER BOARD

EM Connector

Debug Connector

User Itf Connector

MRDY P1.3 P1.4 GPIO135 P5.4 P18.4 P10.15 Jumper to remove
SRDY P1.2 P2.17 GPIO132 P6.17 P20.18 P10.7 Jumper to remove
RESET
P2.15 GPIO134 P6.15 P20.14 P10.35 Jumper to remove
MI P1.7 P1.20 SOMI P5.20 P18.12 P10.9
MO P1.6 P1.18 SIMO P5.18 P18.18 P10.11
CLK P1.5 P1.16 SCLK P5.16 P18.16 P10.13
SS P1.4 P1.14 NCS P5.14 P18.14 P10.29
VDD P2.7/P2.19 VCC P20.3
GND P1.1/P1.19 GND P20.20/P18.20

The RNP need to be loaded witth a firmware that Enable SPI on port1. Such a firmware can be obtain form the remoTI SDK.

short tutorial to generate the firmware for a CC2533F96EM board:

  1. Open the RNP workspace with IAR (rnp_cc2533.eww).
  2. load the project "CC2533F96_SPI_HEX"
  3. add the following define in the project option: SPI_CONFIG_ON_PORT1.
  4. Compile it

You know have a .hex file to load in the EM board.


I2C interface Connection
Smart RF

CC253x Config EM Board TRAINER BOARD

EM Connector

Debug Connector

User Itf Connector

MRDY P1.3 P1.4 GPIO135 P5.4 P18.4 P10.15 Jumper to remove
SRDY P1.2 P2.17 GPIO132 P6.17 P20.18 P10.7 Jumper to remove
RESET
P2.15 GPIO134 P6.15 P20.14 P10.35 Jumper to remove
SDA Pin 3 P2.12 SDA P6.12 P18.5 P10.33
SCL Pin 2 P2.14 SCL P6.14 P18.3 P10.3
VDD P2.7/P2.19 VCC (3.3V) P20.3
GND P1.1/P1.19 GND P20.20/P18.20

The RNP need to be loaded witth a firmware that Enable SPI on port1. Such a firmware can be obtain form the remoTI SDK.

short tutorial to generate the firmware for a CC2533F96EM board:

  1. Open the RNP workspace with IAR (rnp_cc2533.eww).
  2. load the project "CC2533F96_I2C_HEX"
  3. add the following define in the project option: I2C_CONFIG_ON_PORT1.
  4. Compile it

You know have a .hex file to load in the EM board.

Following is a picture of the two boards connected:

RF4CE smarfRF beagle connected.JPG

Linux Kernel Configuration

Physical interface needs to be enable in the linux host. Depending of the Host/Hardware you are using, this might be already the case, or not...

Following chapter describe quickly how to enable them. If you encounter some problem, please call you Hw salesmen/representative. Purpose of this chapter is not to show how to compile the linux kernel or generate the angstrom distribution for beagleboard.

UART On Ubuntu

By default, USB CDC-ACM driver is enable on Ubuntu and TI dongle is recognize witout any specific driver, you just have to plug the CC2531 USB dongle.

The dongle needs to be program with a RNP software, a precompile software can be found in the remoTI SDK (RemoTI).

Once the dongle is plugged, type the following command:

>dmesg

you should see something like this:


> [ 8882.923124] usb 2-1: new full speed USB device number 3 using uhci_hcd
> [ 8888.240836] cdc_acm 2-1:1.0: This device cannot do calls on its own. It is not a modem.
> [ 8888.240898] cdc_acm 2-1:1.0: ttyACM0: USB ACM device
> [ 8888.249738] usbcore: registered new interface driver cdc_acm
> [ 8888.249740] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters


Here we can see that the device assign to the Dongle is :

/dev/ttyACM0

UART On BeagleBoard

CDC-ACM driver should be present as a module in the root file system. Modules are in /lib/modules/3.0.25+ for example. If the kernel name mismatch the module folder path, rename it. If you have a XXX module.dep not found, recreate the dependencies with:

>depmod -a

To load the cdc-acm module if needed:

modprobe cdc-acm

To recompile the kernel with CDC-ACM driver, add the following in the defconfig file: CONFIG_USB_ACM=y

If you have opkg install and working on your beagleboard try : (this reqiered an connection to the internet)

>opkg install kernel-module-cdc-acm 

the other solution is to download a pre-compile module and install it. you can find some here: [1]

install the module with the command

>opkg -i module_anme 

SPI On BeagleBoard

For the BeagleBoard, the SPI is not activated by default. You will need to edit the following file inside the kernel: <path to kernel source>/arch/arm/mach-omap2/board-omap3beagle.c then recompile the kernel.

You king find information on how to enable SPI bus inside the kernel here: BeagleBoard/SPI the SPI bus number 4 will be use.

I did the following modification:

In function omap3_beagle_init(), add the following call:

beagle_init_spi();

and then the following code in the same file:

static struct spi_board_info beagle_mcspi_board_info[] = {
	// spi 4.0
	{
		.modalias	= "spidev",
		.max_speed_hz	= 48000000, //48 Mbps
		.bus_num	= 4,
		.chip_select	= 0,
		.mode = SPI_MODE_1,
	},
};
 
static void __init beagle_init_spi(void)
{
	/* hook the spi ports to the spidev driver */
	spi_register_board_info( beagle_mcspi_board_info,
		ARRAY_SIZE( beagle_mcspi_board_info));
}

The device file will then appears here:

/dev/spidev4.0


I2C On BeagleBoard

By default I2C is activated. In our system, I2C bus number 2 will be used. If I2C does not appear in the device folder, check the fowllowing in file <path to kernel source>/arch/arm/mach-omap2/board-omap3beagle.c


In function omap3_beagle_init(), check the following call is present:
omap3_beagle_i2c_init();

Then check that the following code is present:

static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {};
 
static int __init omap3_beagle_i2c_init(void)
{
	omap_register_i2c_bus(1, 2600, beagle_i2c1_boardinfo,
			ARRAY_SIZE(beagle_i2c1_boardinfo));
	if(!strcmp(expansionboard_name, "zippy") || !strcmp(expansionboard_name, "zippy2"))
	{
		printk(KERN_INFO "Beagle expansionboard: registering i2c2 bus for zippy/zippy2\n");
		omap_register_i2c_bus(2, 400,  beagle_zippy_i2c2_boardinfo,
				ARRAY_SIZE(beagle_zippy_i2c2_boardinfo));
	} else
	{
		omap_register_i2c_bus(2, 400,  beagle_i2c2_boardinfo,
				ARRAY_SIZE(beagle_i2c2_boardinfo));
	}
	/* Bus 3 is attached to the DVI port where devices like the pico DLP
	 * projector don't work reliably with 400kHz */
	omap_register_i2c_bus(3, 100, NULL, 0);
	return 0;
}


The device should appear here;

/dev/i2c-2


Basic GPIO on BeagleBoard

Once you plug the trainer board, this will be detected and GPIO will be reserved. To check that, take a look at the startup log and search for the log:

Beagle expansionboard: exporting GPIOs 130-141,162 to userspace

GPIOs are then exported here: /sys/class/gpio/gpioXXX

Replace XXX by the gpio number.

For a short introduction to GPIO under beagleboard and how to access it, please go here: BeagleBoard/GPIO

<span style="color:red"Note that with the trainer board, the level shifter need to be configured in order to properly used the GPIO!! </span>

Please refer to the trainer schematics for a detailed understanding Trainer_Rev-B schematics

In short: GPIO 136 control the level shifter direction for GPIO 134 and 135 ('0':input, '1':output) GPIO 137 control the level shifter direction for GPIO 132 and 133 ('0':input, '1':output)

I created a short script to validate that GPIOs are working: Copy/Paste it in a file and make it executable:

#!/bin/bash
echo "test des GPIOs"
 
echo "Connect GPIO 135 and 132 together in the trinee board with a wire."
echo "Connect GPIO 134 and 133 together in the trinee board with a wire."
 
echo "   "
echo "   "
echo "out" > /sys/class/gpio/gpio137/direction
echo "1" > /sys/class/gpio/gpio137/value
 
echo "out" > /sys/class/gpio/gpio136/direction
echo "0" > /sys/class/gpio/gpio136/value
 
echo "in" > /sys/class/gpio/gpio134/direction
echo "in" > /sys/class/gpio/gpio135/direction
 
echo "GPIO 132 Value, output set to 1"
echo "out" > /sys/class/gpio/gpio132/direction
echo "1" > /sys/class/gpio/gpio132/value
cat /sys/class/gpio/gpio132/value
echo "GPIO 135 set as input , should have same value a GPIO 132"
cat /sys/class/gpio/gpio135/value
echo "   "
 
echo "GPIO 133 Value, output set to 1"
echo "out" > /sys/class/gpio/gpio133/direction
echo "1" > /sys/class/gpio/gpio133/value
cat /sys/class/gpio/gpio132/value
echo "GPIO 134 set as input , should have same value a GPIO 133"
cat /sys/class/gpio/gpio134/value
 
 
 
echo "   "
echo "   "
echo "GPIO 132 Value, output set to 0"
echo "out" > /sys/class/gpio/gpio132/direction
echo "0" > /sys/class/gpio/gpio132/value
cat /sys/class/gpio/gpio132/value
echo "GPIO 135 set as input , should have same value a GPIO 132"
cat /sys/class/gpio/gpio135/value
 
echo "   "
echo "GPIO 133 Value, output set to 0"
echo "out" > /sys/class/gpio/gpio133/direction
echo "0" > /sys/class/gpio/gpio133/value
cat /sys/class/gpio/gpio132/value
echo "GPIO 134 set as input , should have same value a GPIO 133"
cat /sys/class/gpio/gpio134/value
 
echo "   "

Linux Sample Application

Software Architecture

Following os a description of the application architecture:

RF4CE Linux Application Architecture.png RF4CE Linux NPI socket server Architecture.png

Features

This simple application create a RF4CE network.

By default it allows pairing with any RF4CE controller node using ZRC profile or ZID profile.

Once paired, all data send by the controller node will be display in the terminal.

Compilation on an Ubuntu PC host

Compile both client and server with the following command:


>cd <you path to the linux app>/RemoTI-Linux/Projects/tools/LinuxHost
>make clean
>make

applications will be in the ./out folder:


>./out/NPI_lnx_x86_client
>./out/NPI_lnx_x86_server
>./out/NPI_lnx_armBeagleBoard_client
>./out/NPI_lnx_armBeagleBoard_server
>./out/NPI_lnx_armBeagleBone_client
>./out/NPI_lnx_armBeagleBone_server

Compilation tools are already installed by default on a Ubuntu PC host, if you only want to compile for PC then add argument arch-all-x86. The create_output is added to create the output folder. This segment is executed when make is run without arguments, but not when running only specific parts. See makefile for details.


>cd <you path to the linux app>/RemoTI-Linux/Projects/tools/LinuxHost
>make clean
>make create_output
>make arch-all-x86

Compilation for a BeagleBoard host

No compilation tools are installed on the beagle board and since the beagle board is using a OMAP preocessor based on ARM core, the compilation chain of the Ubuntu PC host cannot be used. To facilitate the development, the compilation chain has been installed on a Ubuntu PC host, instead of the beagleboard.

The Code sourcery tool chain has been used for this purpose.

It can be found here: CodeSourcery Lite

An existing TI wiki page already exist on this subject: Installing CodeSourcery Toolchain


Once the compilation tool chain is install, run the following commands to compile both client and server application application:


>cd <you path to the linux app>/RemoTI-Linux/Projects/tools/LinuxHost
>make clean
>make create_output
>make arch-all-armBeagleBoard

Application will be in the ./debug folder:


>./debug/NPI_lnx_armBeagleBoard_client
>./debug/NPI_lnx_armBeagleBoard_server

On earlier versions of RemoTI-Linux, before BeagleBone was introduced, please replace armBeagleBoard with just arm in the above commands.


Those files will need to be copied on the BeagleBoard.

Compilation for Linux EZ on BeagleBone

Please download the Linux EZ installer from, and follow the steps, given here. This may also have come with your BeagleBone kit. In the latter case please follow the steps in the user guide of your Beagle Bone. The toolchain we are looking for is called arm-arago-linux-gnueabi-gcc. To check if you have the toolchain installed, and added to the path so it is found, run >which arm-arago-linux-gnueabi-gcc.


Once the compilation tool chain is install, run the following commands to compile both client and server application application:


>cd <you path to the linux app>/RemoTI-Linux/Projects/tools/LinuxHost
>make clean
>make create_output
>make arch-all-armBeagleBone

Application will be in the ./debug folder:


>./debug/NPI_lnx_armBeagleBone_client
>./debug/NPI_lnx_armBeagleBone_server


Those files will need to be copied on the BeagleBoard.

Building libraries for use with other applications

You can easily build libraries for use with other application. As an example; you want to create an application more advanced than the simple console application. The following will explain how to build and use the libraries. You can always include the necessary source, but sometimes it is more manageable to just use a library amongst other applications. You may have many applications which require access to the RemoTI RNP.

After you have compiled NPI_Client for Ubuntu, use the following to create the client library in your desired folder:


>ar rs <yourDstPath>/<rtisClientLibUbuntu.a <yourSrcPath>/RemoTI-Linux/Projects/tools/LinuxHost/debug/rtis_lnx_ipc_client.o

After you have compiled NPI_Client for BeagleBoard, use the following to create the client library in your desired folder:


>ar rs <yourDstPath>/<rtisClientLibBB.a <yourSrcPath>/RemoTI-Linux/Projects/tools/LinuxHost/debug/rtis_lnx_ipc_client.o

Note that the object file name is the same independent of what compiler you have used. The names of the libraries (.a) are chosen to reflect what the library is compiled for. You can choose whatever name you want, as long as you keep track of what platform it is compiled for. This means that the same steps as given for BeagleBoard is valid for BeagleBone.

Once the libraries have been built we are ready to include it in our project. The header file you need is


 #include "rtis_lnx.h"

You will find this in the "/rtilib/" folder. This header file depends on these header files as well


 #include "npi_lnx.h"
#include "rti_lnx.h"
#include "rti_lnx_constants.h"

If you have the official RemoTI installer the last two header files are only included if you didn't include


 #include "rti.h"
#include "rti_constants.h"

So, please make sure these are also available to your application. Next is the changes required in your makefile. For the example it is assumed that you place all the headers in a "../rtilib/" folder relative to your makefile.

For Ubuntu


"...
LIBS= -lpthread ../rtilib/rtisClientLib_ubuntu.a
CC := gcc
...
INCLUDES= -I../rtilib \
..."

For BeagleBoard


"...
LIBS= -lpthread ../rtilib/rtisClientLibBB.a
CC = arm-none-linux-gnueabi-gcc
...
INCLUDES= -I../rtilib \
..."


As long as an NPI_Server is running, either locally or somewhere on your network, you now have full access to the RemoTI RNP through function calls from your application.

Usage

The Server application is configured through a config file: RemoTI_RNP.cfg This config file need to be updated to set up the HW interface you want to use. by default, UART is used (/dev/ttyACM0). You can create copies of the configuration file that are modified to your choosing and pass them as arguments to the server. This makes starting up different physical interfaces very quick and easy.

First you need to start the server:

./debug/NPI_lnx_x86_server RemoTI_RNP.cfg


Then the Client. the client takes as parameter the IP address of the socket, for example for a local socket (both Client and server on the same machine):

./debug/NPI_lnx_x86_client 127.0.0.1:2533


Starting the Server

When the Server Start, it will display the following:

.../RemoTI-Linux/Projects/tools/LinuxHost$ ./debug/NPI_lnx_x86_server RemoTI_RNP.cfg
deviceKey = 0
devPath = '/dev/ttyACM0'
Port: 2533
IP addresses for localhost:
  IPv4: 0.0.0.0
  IPv6: ::
waiting for connection on 3...

Each time a Client connect, a log will appear on the terminal. All data exchange through the socket will be logged also.

Starting the Client

Once the application is running, the first thing that it will do is connect to the given socket, initialize the RNP device and display the following menu:

 .../RemoTI-Linux/Projects/tools/LinuxHost$ ./debug/NPI_lnx_x86_client 127.0.0.1:2533
Port: 2533
IP addresses for 127.0.0.1:
 IPv4: 127.0.0.1
Trying to connect...
Connected.
-------------------- START Node Configuration-------------------
- Target Configuration
- ZID and ZRC profile activated
-------------------- END Node Configuration-------------------
-------------------- START SOFTWARE VERSION READING-------------------
- Software Version = 0xd0
-------------------- END SOFTWARE VERSION READING-------------------
-------------------- START Init Req-------------------
- Calling RTI_InitReq...
- ...Waiting for RTI_InitCnf...
-------------------- END Init Req-------------------
- SUCCESS: RTI_InitCnf called with status 0
Press key 'p' the <enter> to allow pairing

Pairing

To perform the pairing, press 'p' then enter.

The RNP will enter the pairing procedure. You have 30s to press the pairing key of your remote control.

For a TI basic remote, this is the zoom key and for a TI advance remote, this is the bottom red button

RF4CE BasicRemote pairing button.png : RF4CE AdvanceRemote pairing button.png

You should see the following on your screen:

Press key 'p' the <enter> to allow pairing
p
Calling RTI_AllowPairReq
RTI_AllowpairCnf called with status 0
Paired!! Waiting for data from RC, press the <q> key followd by <enter> at any time to quit

Not that the pairing entry is saved inside the RNP. Even if you reset the RNP (or remote the USB dongle), next time you use it the pairing will still be activated.

Receiving Data

Press any key on the remote control, each incoming packet will be display.


example of ZRC packet:

*************************************************
RTI_ReceiveDataInd @
Source Idx: 1, profileId 1 , vendorId: 58111 , rxLQI 176
Raw Data: 1 34
*************************************************
*************************************************
RTI_ReceiveDataInd @
Source Idx: 1, profileId 1 , vendorId: 58111 , rxLQI 176
Raw Data: 2 34
*************************************************
*************************************************
RTI_ReceiveDataInd @
Source Idx: 1, profileId 1 , vendorId: 58111 , rxLQI 174
Raw Data: 3 34
*************************************************

Example of ZID packet;

*************************************************
RTI_ReceiveDataInd @
Source Idx: 1, profileId 2 , vendorId: 50175 , rxLQI 148
Raw Data: 2 10 1 2 0 0 0 0 0 0 0 0
*************************************************
*************************************************
RTI_ReceiveDataInd @
Source Idx: 1, profileId 2 , vendorId: 50175 , rxLQI 148
Raw Data: 2 10 1 2 0 0 31 0 0 0 0 0
*************************************************
*************************************************
RTI_ReceiveDataInd @
Source Idx: 1, profileId 2 , vendorId: 50175 , rxLQI 148
Raw Data: 2 10 1 2 0 0 31 0 0 0 0 0
*************************************************

API to Control the Server

There is a simple API to perform certain actions on the Server.

#define
NPI_LNX_CMD_ID_CTRL_TIME_PRINT_REQ
0x01
#define
NPI_LNX_CMD_ID_CTRL_BIG_DEBUG_PRINT_REQ
0x02
#define
NPI_LNX_CMD_ID_VERSION_REQ
0x03
#define
NPI_LNX_CMD_ID_GET_PARAM_REQ
0x04
#define
NPI_LNX_CMD_ID_RESET_DEVICE
0x05
#define
NPI_LNX_CMD_ID_DISCONNECT_DEVICE
0x06
#define
NPI_LNX_CMD_ID_CONNECT_DEVICE
0x07

Source Code

The source code is availble on Git HUB:

https://github.com/TI-LPRF-Software/RemoTI-Linux

To retrieve the code use this command:
$ git clone git://github.com/TI-LPRF-Software/RemoTI-Linux.git


Reference

The remoTI SDK is available here: RemoTI once the SDK installed, in the document folder you will find the following useful API and user guide:

  • RemoTI API
  • RemoTI Network Processor Interface Spec
  • RemoTI Network Processor Developer's Guide
  • CC2533DK RF4CE Advanced Quick Start Guide v 1 0


On TI website, the following interesting app note and website are available: