17.11.2012 Views

The Embedded I/O Company TDRV002-SW-82 Linux Device Driver

The Embedded I/O Company TDRV002-SW-82 Linux Device Driver

The Embedded I/O Company TDRV002-SW-82 Linux Device Driver

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>The</strong> <strong>Embedded</strong> I/O <strong>Company</strong><br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong><br />

<strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong><br />

Multi-Channel Serial Interface<br />

Version 1.4.x<br />

User Manual<br />

Issue 1.4.3<br />

April 2010<br />

TEWS TECHNOLOGIES GmbH<br />

Am Bahnhof 7 25469 Halstenbek, Germany<br />

Phone: +49 (0) 4101 4058 0 Fax: +49 (0) 4101 4058 19<br />

e-mail: info@tews.com www.tews.com


<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong><br />

<strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong><br />

Multi-Channel Serial Interface<br />

Supported Modules:<br />

TPMC371<br />

TPMC372<br />

TPMC375<br />

TPMC376<br />

TPMC460<br />

TPMC461<br />

TPMC462<br />

TPMC463<br />

TPMC465<br />

TPMC466<br />

TPMC467<br />

TCP460<br />

TCP461<br />

TCP462<br />

TCP463<br />

TCP465<br />

TCP466<br />

TCP467<br />

This document contains information, which is<br />

proprietary to TEWS TECHNOLOGIES GmbH. Any<br />

reproduction without written permission is forbidden.<br />

TEWS TECHNOLOGIES GmbH has made any<br />

effort to ensure that this manual is accurate and<br />

complete. However TEWS TECHNOLOGIES GmbH<br />

reserves the right to change the product described<br />

in this document at any time without notice.<br />

TEWS TECHNOLOGIES GmbH is not liable for any<br />

damage arising out of the application or use of the<br />

device described herein.<br />

�2005-2010 by TEWS TECHNOLOGIES GmbH<br />

Issue Description Date<br />

1.0.0 First Issue February 21, 2005<br />

1.1.0 Built-In-Self-Test (BIST) added March 11, 2005<br />

1.1.1 depmod for driver installation added October 13, 2005<br />

1.2.0 New module support and transceiver programming IOCTL added.<br />

ChangeLog.txt release history file added, file list modified.<br />

July 26, 2006<br />

1.2.1 New Address TEWS LLC November 7, 2006<br />

1.3.0 New IOCTL command <strong>TDRV002</strong>_IOCT_SPEED added January 10, 2007<br />

1.4.0 New IOCTL commands <strong>TDRV002</strong>_IOCQ_GET_SPEED,<br />

New IOCTL commands <strong>TDRV002</strong>_IOCQ_GET_INFO,<br />

example file added to file list<br />

1.4.1 “<strong>TDRV002</strong>” device naming note added<br />

Source file archive extraction command line added<br />

March 01, 2007<br />

June 20, 2007<br />

1.4.2 File list changed, include path moved September 26, 2007<br />

1.4.3 Address TEWS LLC removed, general Revision April,27, 2010<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 2 of 24


Table of Contents<br />

1 INTRODUCTION......................................................................................................... 4<br />

2 INSTALLATION.......................................................................................................... 6<br />

2.1 Build and install the device driver.................................................................................................7<br />

2.2 Uninstall the device driver .............................................................................................................7<br />

2.3 Install device driver into the running kernel ................................................................................7<br />

2.4 Remove device driver from the running kernel ...........................................................................8<br />

2.5 Change Major <strong>Device</strong> Number .......................................................................................................8<br />

3 DEVICE DRIVER PROGRAMMING ........................................................................... 9<br />

3.1 Simple Programming example ......................................................................................................9<br />

3.2 Using special baudrates...............................................................................................................10<br />

3.2.1 Special baudrates set via termios......................................................................................10<br />

3.3 ioctl() ..............................................................................................................................................11<br />

3.3.1 <strong>TDRV002</strong>_IOCQ_BIST ......................................................................................................13<br />

3.3.2 <strong>TDRV002</strong>_IOCT_CONF_TRANS ......................................................................................16<br />

3.3.3 <strong>TDRV002</strong>_IOCT_SPEED...................................................................................................18<br />

3.3.4 <strong>TDRV002</strong>_IOCQ_GET_SPEED ........................................................................................19<br />

3.3.5 <strong>TDRV002</strong>_IOCQ_GET_INFO ............................................................................................20<br />

4 <strong>TDRV002</strong>CONFIG – COMMAND LINE TOOL ......................................................... 22<br />

5 DIAGNOSTIC............................................................................................................ 23<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 3 of 24


1 Introduction<br />

<strong>The</strong> <strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> <strong>Linux</strong> device driver is a full-duplex serial driver which allows the operation of a<br />

supported serial PMC on <strong>Linux</strong> operating systems.<br />

<strong>The</strong> <strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> device driver based on the standard <strong>Linux</strong> serial device driver and supports all<br />

standard terminal functions (TERMIOS).<br />

Supported features:<br />

� Extended baudrates up to 5.5296 Mbaud.<br />

� Each channel has a 64 Byte transmit and receive hardware FIFO<br />

� Programmable trigger level for transmit and receive FIFO.<br />

� Hardware (RTS/CTS) and software flow control (XON/XOFF) direct controlled by the serial<br />

controller. <strong>The</strong> advantage of this feature is that the transmission of characters will immediately<br />

stop as soon as a complete character is transmitted and not when the transmit FIFO is empty<br />

for handshake under software control. This will greatly improve flow control reliability.<br />

� Direct support of different physical interfaces (e.g. RS-232, RS-422).<br />

� Designed as <strong>Linux</strong> kernel module with dynamically loading.<br />

� Supports shared IRQ’s.<br />

� Build on new style PCI driver layout<br />

� Creates a TTY device tty<strong>TDRV002</strong> and dialout device cua<strong>TDRV002</strong> (Kernel 2.4.x) with<br />

dynamically allocated or fixed major device numbers.<br />

� DEVFS and UDEV support for automatic device node creation<br />

<strong>The</strong> <strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> device driver supports the modules listed below:<br />

TPMC371 8 Channel Serial Interface PMC Conduction Cooled<br />

TPMC372 4 Channel Serial Interface PMC Conduction Cooled<br />

TPMC375 8 Channel Serial Interface PMC Conduction Cooled<br />

TPMC376 4 Channel Serial Interface PMC Conduction Cooled<br />

TPMC460 16 Channel Serial Interface PMC<br />

TPMC461 8 Channel Serial Interface PMC<br />

TPMC462 4 Channel Serial Interface PMC<br />

TPMC463 4 Channel Serial Interface PMC<br />

TPMC465 8 Channel Serial Interface PMC<br />

TPMC466 4 Channel Serial Interface PMC<br />

TPMC467 4 Channel Serial Interface PMC<br />

TCP460 16 Channel Serial Interface CompactPCI<br />

TCP461 8 Channel Serial Interface CompactPCI<br />

TCP462 4 Channel Serial Interface CompactPCI<br />

TCP463 4 Channel Serial Interface CompactPCI<br />

TCP465 8 Channel Serial Interface CompactPCI<br />

TCP466 4 Channel Serial Interface CompactPCI<br />

TCP467 4 Channel Serial Interface CompactPCI<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 4 of 24


In this document all supported modules and devices will be called <strong>TDRV002</strong>. Specials for<br />

certain devices will be advised.<br />

To get more information about the features and use of the supported devices it is recommended to<br />

read the manuals listed below.<br />

TPMC37x, TPMC46x and TCP46x Hardware User manual<br />

TPMC37x, TPMC46x and TCP46x Engineering Manual<br />

Exar XR17D15x PCI UART User Manual<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 5 of 24


2 Installation<br />

<strong>The</strong> directory <strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> on the distribution media contains the following files:<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong>-1.4.3.pdf This manual in PDF format<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong>-SRC.tar.gz GZIP compressed archive with driver source code<br />

Release.txt Release information<br />

ChangeLog.txt Release history<br />

<strong>The</strong> GZIP compressed archive <strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong>-SRC.tar.gz contains the following files and<br />

directories:<br />

hal/ Hardware abstraction layer driver needed for all kernel versions<br />

hal/Makefile HAL driver makefile<br />

hal/tdrv002hal.c HAL driver source file<br />

hal/tdrv002haldef.h HAL driver private header file<br />

serial/ UART driver directory<br />

serial/2.4.x Kernel 2.4.x sources directory<br />

serial/2.4.x/Makefile Serial driver makefile<br />

serial/2.4.x/tdrv002serial.c Serial driver source file<br />

serial/2.4.x/tdrv002serialdef.h Serial driver private header file<br />

serial/2.6.x Kernel 2.6.x sources directory<br />

serial/2.6.x/Makefile Serial driver makefile<br />

serial/2.6.x/tdrv002serial.c Serial driver source file<br />

serial/2.6.x/tdrv002serialdef.h Serial driver private header file<br />

serial/makenode Shell script to create devices nodes without a device FS<br />

serial/makenodeFM24 Same as makenode with additional support for CUA devices<br />

include/tpmodule.c <strong>Driver</strong> independent library<br />

include/tpmodule.h <strong>Driver</strong> independent library header file<br />

include/config.h <strong>Driver</strong> independent library header file<br />

include/tpxxxhwdep.c HAL low level WINNT style hardware access functions source file<br />

include/tpxxxhwdep.h Access functions header file<br />

example/Makefile Example application makefile<br />

example/tdrv002example.c Send and receive example application<br />

example/tdrv002setspeed.c Speed configuration example application<br />

example/tdrv002bist.c Example for using Built-In-Self-Test<br />

example/tdrv002config.c Command-Line Tool for transceiver programming<br />

example/tdrv002readinfo.c Example displays hardware information of a channel<br />

tdrv002.h <strong>Driver</strong> header file<br />

tdrv002user.h User application header file<br />

In order to perform an installation, extract all files of the archive <strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong>-SRC.tar.gz to the<br />

desired target directory. (Note: to extract the archive file use # tar –xvzf <strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong>-SRC.tar.gz)<br />

� Login as root and change to the target directory<br />

� Copy tdrv002user.h to /usr/include<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 6 of 24


2.1 Build and install the device driver<br />

� Login as root<br />

� Change to the hal/ target directory<br />

� To create and install the HAL driver in the module directory /lib/modules//misc enter:<br />

# make install<br />

� Change to the serial/ target directory<br />

� To create and install the SERIAL driver in the module directory /lib/modules//misc<br />

enter:<br />

# make install<br />

For <strong>Linux</strong> kernel 2.6.x, there may be compiler warnings claiming some undefined<br />

tdrv002_hal_* symbols. <strong>The</strong>se warnings are caused by the HAL driver, which is<br />

unknown during compilation of this SERIAL driver. <strong>The</strong> warnings can be ignored.<br />

� To update the device driver’s module dependencies, enter:<br />

# depmod -aq<br />

2.2 Uninstall the device driver<br />

� Login as root<br />

� Change to the target directory<br />

� To remove the driver from the module directory /lib/modules//misc enter:<br />

# make uninstall<br />

2.3 Install device driver into the running kernel<br />

� To load the device driver into the running kernel, login as root and execute the following<br />

commands:<br />

# modprobe tdrv002serialdrv<br />

� After the first build or if you are using dynamic major device allocation it’s necessary to create<br />

new device nodes on the file system. Please execute the script file makenode, which resides in<br />

serial/ directory, to do this. If your kernel has enabled the device file system (devfs, udev, ...)<br />

then skip running the makenode script. Instead of creating device nodes from the script the<br />

driver itself takes creating and destroying of device nodes in its responsibility.<br />

# sh makenode<br />

On success the device driver will create a minor device for each compatible channel found. <strong>The</strong> first<br />

channel of the first PMC module can be accessed with device node /dev/ttyS<strong>TDRV002</strong>_0, the second<br />

channel with device node /dev/ttyS<strong>TDRV002</strong>_1 and so on. <strong>The</strong> assignment of device nodes to<br />

physical PMC modules depends on the search order of the PCI bus driver.<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 7 of 24


2.4 Remove device driver from the running kernel<br />

� To remove the device driver from the running kernel login as root and execute the following<br />

command:<br />

# modprobe –r tdrv002serialdrv<br />

If your kernel has enabled a device file system (devfs, udev, ...), all /dev/ttyS<strong>TDRV002</strong>_* nodes will be<br />

automatically removed from your file system after this.<br />

Be sure that the driver isn’t opened by any application program. If opened you will get the<br />

response “tdrv002serialdrv: <strong>Device</strong> or resource busy” and the driver will still remain in the<br />

system until you close all opened files and execute modprobe –r again.<br />

2.5 Change Major <strong>Device</strong> Number<br />

This paragraph is only for <strong>Linux</strong> kernels without a device file system (devfs, udev, ...) installed.<br />

<strong>The</strong> released <strong>TDRV002</strong> driver use dynamic allocation of major device numbers. If this isn’t suitable for<br />

the application it’s possible to define a major number separately for the TTY and CUA driver.<br />

To change the major number edit the file serial//tdrv002serial.c, change the following<br />

symbols to appropriate values and enter make install to create a new driver.<br />

<strong>TDRV002</strong>_TTY_MAJOR Defines the value for the terminal device.<br />

Valid numbers are in range between 0 and<br />

255. A value of 0 means dynamic number<br />

allocation.<br />

<strong>TDRV002</strong>_CUA_MAJOR Defines the value for the dialout device.<br />

Valid numbers are in range between 0 and<br />

255. A value of 0 means dynamic number<br />

allocation.<br />

Example:<br />

#define <strong>TDRV002</strong>_TTY_MAJOR 122<br />

#define <strong>TDRV002</strong>_CUA_MAJOR 123<br />

Be sure that the desired major number isn’t used by other drivers. Please check /proc/devices<br />

to see which numbers are free.<br />

Keep in mind that’s necessary to create new device nodes if the major number for the <strong>TDRV002</strong><br />

driver has changed and the makenode script isn’t used.<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 8 of 24


3 <strong>Device</strong> <strong>Driver</strong> Programming<br />

<strong>The</strong> <strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> driver loosely bases on the standard <strong>Linux</strong> terminal driver. Due to this way of<br />

implementation the driver interface and functionality is compatible to the standard <strong>Linux</strong> terminal<br />

driver.<br />

Please refer to the TERMIOS man page and driver programming related man pages for more<br />

information about serial driver programming.<br />

3.1 Simple Programming example<br />

This example program opens the first serial channel of a <strong>TDRV002</strong> compatible device for read/write.<br />

After the device is open it writes a “Hello World” string to the device and receives up 80 bytes from the<br />

serial channel.<br />

int main()<br />

{<br />

int fd;<br />

int count;<br />

char buffer[81];<br />

}<br />

/* open the desired PMC device channel*/<br />

fd = open( “/dev/ttyS<strong>TDRV002</strong>_0”, O_RDWR | O_NOCTTY);<br />

if (fd < 0) exit(-1);<br />

/* write data to the certain channel */<br />

count = write(fd, “Hello World\n”, 12);<br />

printf(“%d bytes written\n”, count);<br />

/* read up to 80 bytes from the device */<br />

count = read(fd, buffer, 80)<br />

if (count < 0) {<br />

printf(“read error\n”);<br />

}<br />

else {<br />

buffer[count] = 0;<br />

printf(“%d bytes read \n”, count, buffer);<br />

}<br />

close(fd);<br />

<strong>The</strong> source files tdrv002example.c and tdrv002setspeed.c contains additional programming<br />

examples.<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 9 of 24


3.2 Using special baudrates<br />

<strong>The</strong>re are two possibilities setting up special baudrates. <strong>The</strong> first is used to setup some predefined<br />

baudrates, this is the standard way by using the termios structure. <strong>The</strong> second way allows the<br />

selection of all baud rates the module can support. This way uses the ioctl function<br />

<strong>TDRV002</strong>_IOCT_SPEED. (Please refer to the description of the ioctl function).<br />

3.2.1 Special baudrates set via termios<br />

Some of the supported modules allow very high non standard baud rates. To use these baudrates with<br />

the standard <strong>Linux</strong> IOCTL functions regard the following section.<br />

<strong>The</strong> file “tdrv002user.h” defines some special baudrates.<br />

Define Value Description<br />

<strong>TDRV002</strong>_BUSER B1000000 Default value for baudrate definition<br />

<strong>TDRV002</strong>_B13<strong>82</strong>400 <strong>TDRV002</strong>_BUSER Select 13<strong>82</strong>400 Baud<br />

<strong>TDRV002</strong>_B2764800 (<strong>TDRV002</strong>_BUSER+1) Select 2764800 Baud<br />

<strong>TDRV002</strong>_B5529600 (<strong>TDRV002</strong>_BUSER+2) Select 5529600 Baud<br />

By overriding some standard baudrates, you can easily use it with a termios structure. To setup speed<br />

e.g. to 5529600 BAUD use the following code:<br />

newtermios.c_cflag = (oldtermios.c_cflag & ~CBAUD) | <strong>TDRV002</strong>_B5529600;<br />

tcsetattr(, TCSANOW, &newtermios);<br />

You can also use the following, it does the same:<br />

newtermios.c_cflag = (oldtermios.c_cflag & ~CBAUD) | B1500000;<br />

tcsetattr(, TCSANOW, &newtermios);<br />

But it is recommended to use the first solution for a better readability.<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 10 of 24


3.3 ioctl()<br />

NAME<br />

ioctl() device control functions<br />

SYNOPSIS<br />

#include <br />

#include <br />

#include <br />

int ioctl(int filedes, int request [, void *argp])<br />

DESCRIPTION<br />

<strong>The</strong> ioctl function sends a control code directly to a device, specified by filedes, causing the<br />

corresponding device to perform the requested operation. <strong>The</strong> argument request specifies the control<br />

code for the operation. <strong>The</strong> optional argument argp depends on the selected request and is described<br />

for each request in detail later in this chapter.<br />

<strong>The</strong> following ioctl codes are defined in tdrv002user.h:<br />

Value Meaning<br />

<strong>TDRV002</strong>_IOCQ_BIST Start Built-In-Self-Test<br />

<strong>TDRV002</strong>_IOCT_CONF_TRANS Configure transceiver (physical interface)<br />

<strong>TDRV002</strong>_IOCT_SPEED Setup user defined baudrates<br />

<strong>TDRV002</strong>_IOCQ_GET_SPEED Returns the current configured baudrate<br />

<strong>TDRV002</strong>_IOCQ_GET_INFO Reads out hardware information of a channel<br />

See below for more detailed information on each control code.<br />

To use these <strong>TDRV002</strong> specific control codes the header file tdrv002user.h must be included in<br />

the application.<br />

RETURNS<br />

On success, zero is returned. In case of an error, a value of –1 is returned. <strong>The</strong> global variable errno<br />

contains the detailed error code.<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 11 of 24


ERRORS<br />

EINVAL Invalid argument. This error code is returned if the requested ioctl function is<br />

unknown. Please check the argument request.<br />

Other function dependant error codes will be described for each ioctl code separately. Note, the<br />

<strong>TDRV002</strong> driver always returns standard <strong>Linux</strong> error codes.<br />

SEE ALSO<br />

ioctl man pages<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 12 of 24


3.3.1 <strong>TDRV002</strong>_IOCQ_BIST<br />

NAME<br />

<strong>TDRV002</strong>_IOCQ_BIST – Start Built-In-Self-Test<br />

DESCRIPTION<br />

<strong>The</strong> <strong>TDRV002</strong> driver (version 1.1.0 and higher) supports a special IOCTL function for testing module<br />

hardware and for system diagnostic. <strong>The</strong> optional argument can be omitted for this ioctl function.<br />

<strong>The</strong> functionality is called Built-In-Self-Test or BIST. With BIST you can test each channel of all your<br />

modules separately. <strong>The</strong>re are three different test classes. First is a line test, second an interrupt test<br />

and the last a data integrity test. All tests run with local channel loopback enabled, so you don’t need<br />

an external cable connection. <strong>The</strong> Fig. 3-1 describes the loop back configuration of a XR17D158 8<br />

channel UART, so all line arrays are index with [7:0]. For the two and four channel UARTs XR17D152<br />

and XR17D154 line arrays should be indexed with [1:0] or [3:0].<br />

Fig. 3-1<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 13 of 24


<strong>The</strong> line test contains a test of all modem lines, as you can see RTS and CTS, DTR and DSR, OP1<br />

and RI and finally OP2 and CD. Only the static states for both electrical levels are tested on each<br />

sender – receiver line pair.<br />

For testing interrupts the BIST transmits a test buffer with known data and size. All data should be<br />

received on same channel during internal loopback. If not, there is an interrupt error. <strong>The</strong> buffer size is<br />

1024 BYTE. <strong>The</strong> baudrate has to be set through the standard terminal IOCTL functions.<br />

<strong>The</strong> last test verifies received data to assert data integrity.<br />

EXAMPLE<br />

#include <br />

int result, tty1;<br />

/* Start Built-In Selftest, */<br />

result = ioctl(tty1, <strong>TDRV002</strong>_IOCQ_BIST, NULL);<br />

if (result) {<br />

printf("Error during Built-In Selftest !\n", result, result);<br />

}<br />

if (result < 0) {<br />

printf("ERRNO %d - %s\n", errno, strerror(errno));<br />

}<br />

else if (result > 0) {<br />

if (result & <strong>TDRV002</strong>_ERTSCTS)<br />

printf("RTS/CTS line broken!\n");<br />

if (result & <strong>TDRV002</strong>_EDTRDSR)<br />

printf("DTR/DSR line broken!\n");<br />

if (result & <strong>TDRV002</strong>_ERI)<br />

printf("OP1/RI line broken!\n");<br />

if (result & <strong>TDRV002</strong>_ECD)<br />

printf("OP2/DCD line broken!\n");<br />

if (result & <strong>TDRV002</strong>_EDATA)<br />

printf("Data integrity test failed!\n");<br />

}<br />

else {<br />

printf("INFO: Port %s successfully tested.\n", DevName);<br />

}<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 14 of 24


RETURNS<br />

If return value is > 0 one of three tests failed. Use the following flags to get a detailed error description.<br />

ERRORS<br />

<strong>TDRV002</strong>_ERTSCTS If set RTS/CTS line broken.<br />

<strong>TDRV002</strong>_EDTRDSR If set DTR/DSR line broken.<br />

<strong>TDRV002</strong>_ERI If set OP1/RI line broken.<br />

<strong>TDRV002</strong>_ECD If set OP2/CD line broken.<br />

<strong>TDRV002</strong>_EDATA Data integrity test failed. No correct transmission<br />

possible.<br />

ETIME A timeout occurred during wait, interrupts do not<br />

work correctly.<br />

EAGAIN Your task should never been blocked. Change it to<br />

use the Built-In-Self-Test.<br />

ERESTARTSYS Interrupted by external signal.<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 15 of 24


3.3.2 <strong>TDRV002</strong>_IOCT_CONF_TRANS<br />

NAME<br />

<strong>TDRV002</strong>_IOCT_CONF_TRANS – Configure transceiver<br />

DESCRIPTION<br />

This ioctl function configures the transceiver circuit of all <strong>TDRV002</strong> modules with a programmable<br />

physical interface.<br />

<strong>The</strong> configuration is passed by value by the parameter arg to the driver.<br />

<strong>The</strong> flags below are available and should be ORed to build a configuration value:<br />

<strong>TDRV002</strong>_CFG_RS485_RS232 Set to enable RS485 interface, clear to enable<br />

RS232 interface.<br />

<strong>TDRV002</strong>_CFG_HDPLX Set to enable half-duplex interface, clear to enable<br />

full-duplex interface.<br />

<strong>TDRV002</strong>_CFG_RENA Set to enable “auto RS485 receiver enable”<br />

feature, clear to disable it.<br />

<strong>TDRV002</strong>_CFG_RTERM Set to enable receiver termination, clear to disable<br />

it.<br />

<strong>TDRV002</strong>_CFG_TTERM Set to enable transmitter termination, clear to<br />

disable it.<br />

<strong>TDRV002</strong>_CFG_SLEWLIMIT Set to enable slew limit mode, clear to disable it.<br />

<strong>TDRV002</strong>_CFG_SHDN Set to shutdown the hole transceiver circuit, clear<br />

to enable the transceiver.<br />

<strong>TDRV002</strong>_CFG_AUTO_RS485 Set to enable “UART Auto RS485 Mode”, clear to<br />

disable it. (See UART XR17D15x Hardware User<br />

Manual)<br />

Beside the certain flags the tdrv002user.h header file offers a set of standard configurations that could<br />

be used alternatively. <strong>The</strong> following predefined macros could be used:<br />

<strong>TDRV002</strong>_INTF_OFF Shutdown mode / disable interface<br />

<strong>TDRV002</strong>_INTF_RS232 RS232<br />

<strong>TDRV002</strong>_INTF_RS422 RS422 (Multidrop / Full Duplex)<br />

<strong>TDRV002</strong>_INTF_RS485FDM RS485 Full Duplex (Master)<br />

<strong>TDRV002</strong>_INTF_RS485FDS RS485 Full Duplex (Slave)<br />

<strong>TDRV002</strong>_INTF_RS485HD RS485 Half Duplex<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 16 of 24


EXAMPLE<br />

#include <br />

unsigned long config;<br />

int result;<br />

int tty1, tty2; /* device handles of modules with programmable<br />

transceivers */<br />

/* Setup channel as RS485 Full Duplex (Master)*/<br />

config = <strong>TDRV002</strong>_CFG_RS485_RS232 |<br />

<strong>TDRV002</strong>_CFG_RTERM |<br />

<strong>TDRV002</strong>_CFG_TTERM;<br />

result = ioctl(tty1, <strong>TDRV002</strong>_IOCT_CONF_TRANS, config);<br />

if (result < 0) {<br />

/* handle errors */<br />

}<br />

/* Setup channel as RS485 Full Duplex (Master) (alternative way) */<br />

config = <strong>TDRV002</strong>_INTF_RS485FDM;<br />

result = ioctl(tty1, <strong>TDRV002</strong>_IOCT_CONF_TRANS, config);<br />

if (result < 0) {<br />

/* handle errors */<br />

}<br />

/* Shutdown the physical interface of certain channel */<br />

config = <strong>TDRV002</strong>_INTF_OFF;<br />

result = ioctl(tty2, <strong>TDRV002</strong>_IOCT_CONF_TRANS, config);<br />

if (result < 0) {<br />

/* handle errors */<br />

}<br />

ERRORS<br />

ENODEV <strong>The</strong> selected device has no programmable physical<br />

interface. See Hardware User Manual for detailed<br />

information about programmable transceivers.<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 17 of 24


3.3.3 <strong>TDRV002</strong>_IOCT_SPEED<br />

NAME<br />

<strong>TDRV002</strong>_IOCT_SPEED – Setup user defined baudrates<br />

DESCRIPTION<br />

This ioctl function sets up a user defined baudrate. This allows using the <strong>TDRV002</strong> device with every<br />

adjustable baudrate.<br />

<strong>The</strong> new baudrate is passed by value by the parameter arg to the driver. <strong>The</strong> baudrate limits are<br />

device and configuration dependent therefore refer to the suitable manual.<br />

<strong>The</strong> function tries to set the baudrate in “X16-mode”, if the nearest configurable baudrate has a<br />

difference grater than 3% to the chosen one, the driver will setup the baudrate in “X8-mode”.<br />

If a user defined baudrate is defined, standard tools will return invalid information about the<br />

selected baudrate.<br />

EXAMPLE<br />

#include <br />

int result, tty1;<br />

/* Setup 14400 Baud */<br />

result = ioctl(tty1, <strong>TDRV002</strong>_IOCT_SPEED, 14400);<br />

if (result < 0) {<br />

/* handle errors */<br />

}<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 18 of 24


3.3.4 <strong>TDRV002</strong>_IOCQ_GET_SPEED<br />

NAME<br />

<strong>TDRV002</strong>_IOCQ_GET_SPEED – Read the current configured baudrate<br />

DESCRIPTION<br />

This ioctl function returns the currently configured baudrate of the specified channel. This allows<br />

checking if a baudrate can be configured correctly or if it is substituted by the nearest configurable<br />

baudrate.<br />

<strong>The</strong> current baudrate is returned in the integer argument the parameter arg points on.<br />

EXAMPLE<br />

#include <br />

int result, tty1, baudrate;<br />

result = ioctl(tty1, <strong>TDRV002</strong>_IOCQ_GET_SPEED, &baudrate);<br />

if (result < 0) {<br />

/* handle errors */<br />

}<br />

else {<br />

printf(“Current Baudrate: %d\n”, baudrate);<br />

}<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 19 of 24


3.3.5 <strong>TDRV002</strong>_IOCQ_GET_INFO<br />

NAME<br />

<strong>TDRV002</strong>_IOCQ_GET_INFO – Reads information about the position and type of a channel<br />

DESCRIPTION<br />

This ioctl function reads the module position, module ID and the local channel number of a specified<br />

channel. This information may allow an easier module identification and configuration checking in the<br />

system.<br />

A pointer to the information buffer (<strong>TDRV002</strong>_GET_INFO_STRUCT) is passed by the parameter arg<br />

to the driver<br />

typedef struct<br />

{<br />

int pciBusNo;<br />

int pciParentBusNo;<br />

int pci<strong>Device</strong>No;<br />

int localChannelNo;<br />

int deviceId;<br />

int subSystemId;<br />

char typeStr[20];<br />

} <strong>TDRV002</strong>_GET_INFO_STRUCT;<br />

pciBusNo<br />

Returns the PCI bus number the UART is mounted. Some <strong>TDRV002</strong> supported modules have their<br />

own PCI bridge in this case the value is the number of the local PCI bus on the module.<br />

pciParentBusNo<br />

Returns the PCI bus number of the parent PCI bus. This value may be interesting if a module type<br />

with an own PCI bridge is used. If there is no parent PCI bus, the value will be -1.<br />

pci<strong>Device</strong>No<br />

Returns the PCI device number the UART controller. This specifies a fix place on the PCI bus and<br />

may be used to identify a special module. <strong>The</strong> value returns the PCI device number of the UART<br />

not that one of the <strong>TDRV002</strong> supported module.<br />

localChannelNo<br />

Returns the local channel number of the specified device. <strong>The</strong> first channel on a module starts with<br />

0, the second is 1 and so on.<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 20 of 24


deviceId<br />

Returns the PCI device ID, this identifies the model type.<br />

subSystemId<br />

Returns the PCI Sybsystem ID, this identifies the model variant.<br />

typeStr[]<br />

Returns a string with the product name, e.g. TPMC461-12 or TCP462-10<br />

EXAMPLE<br />

#include <br />

int result, tty1;<br />

<strong>TDRV002</strong>_GET_INFO_STRUCT infoBuf;<br />

/* Display channel position and Moduletype */<br />

result = ioctl(tty1, <strong>TDRV002</strong>_IOCQ_GET_INFO, &infoBuf);<br />

if (result < 0) {<br />

printf(“<strong>Device</strong>: %d/%d/%d: %s\n”,<br />

infoBuf.pciBusNo,<br />

infoBuf.pci<strong>Device</strong>No,<br />

infoBuf.localChannelNo,<br />

infoBuf.typeStr);<br />

}<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 21 of 24


4 tdrv002config – Command Line Tool<br />

To setup the physical interface of a certain channel you can use example/tdrv002config for<br />

programming of the transceiver circuit.<br />

format : tdrv002config <br />

example: tdrv002config 0 crs485 crterm<br />

configures /dev/ttyS<strong>TDRV002</strong>_0 to RS422 full duplex master<br />

List of all options:<br />

crs485<br />

chdplx<br />

crena<br />

crterm<br />

ctterm<br />

cslewlimit<br />

cshdn<br />

cautors485<br />

For detailed configuration options information see <strong>TDRV002</strong>_IOCT_CONF_TRANS ioctl function<br />

description.<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 22 of 24


5 Diagnostic<br />

If the <strong>TDRV002</strong> driver does not work properly it is helpful to get some status information from the<br />

driver respective kernel.<br />

<strong>The</strong> <strong>Linux</strong> /proc file system provides information about kernel, resources, driver, devices and so on.<br />

<strong>The</strong> following screen dumps displays information of a correct running <strong>TDRV002</strong> driver (see also the<br />

proc man pages).<br />

# cat /proc/tty/driver/tdrv002serial<br />

TEWS TECHNOLOGIES - <strong>TDRV002</strong> Generic UART driver (Kernel 2.4.x): <br />

revision: <br />

0: uart:XR17D15X port:D08E8000 irq:10 tx:0 rx:0<br />

1: uart:XR17D15X port:D08E<strong>82</strong>00 irq:10 tx:0 rx:0<br />

2: uart:XR17D15X port:D08E8400 irq:10 tx:0 rx:0<br />

3: uart:XR17D15X port:D08E8600 irq:10 tx:0 rx:0<br />

4: uart:XR17D15X port:D08E8800 irq:10 tx:0 rx:0<br />

5: uart:XR17D15X port:D08E8A00 irq:10 tx:0 rx:0<br />

6: uart:XR17D15X port:D08E8C00 irq:10 tx:0 rx:0<br />

7: uart:XR17D15X port:D08E8E00 irq:10 tx:0 rx:0<br />

8: uart:XR17D15X port:D08EA000 irq:11 tx:0 rx:0<br />

9: uart:XR17D15X port:D08EA200 irq:11 tx:0 rx:0<br />

10: uart:XR17D15X port:D08EA400 irq:11 tx:0 rx:0<br />

11: uart:XR17D15X port:D08EA600 irq:11 tx:0 rx:0<br />

…<br />

# cat /proc/tty/drivers<br />

tdrv002serial /dev/cua/cua<strong>TDRV002</strong>_ 253 0-127 serial:callout<br />

tdrv002serial /dev/tts/ttyS<strong>TDRV002</strong>_ 254 0-127 serial<br />

serial /dev/cua/%d 5 64-127 serial:callout<br />

serial /dev/tts/%d 4 64-127 serial<br />

pty_slave /dev/pts/%d 143 0-255 pty:slave<br />

pty_master /dev/ptm 135 0-255 pty:master<br />

pty_slave /dev/pts/%d 142 0-255 pty:slave<br />

pty_master /dev/ptm 134 0-255 pty:master<br />

pty_slave /dev/pts/%d 141 0-255 pty:slave<br />

pty_master /dev/ptm 133 0-255 pty:master<br />

pty_slave /dev/pts/%d 140 0-255 pty:slave<br />

pty_master /dev/ptm 132 0-255 pty:master<br />

pty_slave /dev/pts/%d 139 0-255 pty:slave<br />

pty_master /dev/ptm 131 0-255 pty:master<br />

pty_slave /dev/pts/%d 138 0-255 pty:slave<br />

pty_master /dev/ptm 130 0-255 pty:master<br />

pty_slave /dev/pts/%d 137 0-255 pty:slave<br />

pty_master /dev/ptm 129 0-255 pty:master<br />

pty_slave /dev/pts/%d 136 0-255 pty:slave<br />

pty_master /dev/ptm 128 0-255 pty:master<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 23 of 24


pty_slave /dev/pty/s%d 3 0-255 pty:slave<br />

pty_master /dev/pty/m%d 2 0-255 pty:master<br />

/dev/vc/0 /dev/vc/0 4 0 system:vtmaster<br />

/dev/ptmx /dev/ptmx 5 2 system<br />

/dev/console /dev/console 5 1 system:console<br />

/dev/tty /dev/tty 5 0 system:/dev/tty<br />

unknown /dev/vc/%d 4 1-63 console<br />

# cat /proc/interrupts<br />

CPU0<br />

0: 60160 XT-PIC timer<br />

1: 6 XT-PIC keyboard<br />

2: 0 XT-PIC cascade<br />

8: 1 XT-PIC rtc<br />

10: 0 XT-PIC ehci-hcd, tdrv002serial<br />

11: 2635 XT-PIC usb-uhci, usb-uhci, eth0, tdrv002serial<br />

12: 49 XT-PIC PS/2 Mouse<br />

14: 7783 XT-PIC ide0<br />

NMI: 0<br />

ERR: 0<br />

# lspci –v<br />

…<br />

00:0f.0 Serial controller: TEWS Datentechnik GmBH: Unknown device 01cd (rev<br />

02) (prog-if 02 [16550])<br />

Subsystem: TEWS Datentechnik GmBH: Unknown device 000a<br />

Flags: fast devsel, IRQ 10<br />

Memory at cfffc000 (32-bit, non-prefetchable) [size=4K]<br />

00:11.0 Serial controller: TEWS Datentechnik GmBH: Unknown device 01cf (rev<br />

01) (prog-if 02 [16550])<br />

Subsystem: TEWS Datentechnik GmBH: Unknown device 000a<br />

Flags: fast devsel, IRQ 11<br />

Memory at cfffd000 (32-bit, non-prefetchable) [size=2K]<br />

…<br />

<strong>TDRV002</strong>-<strong>SW</strong>-<strong>82</strong> - <strong>Linux</strong> <strong>Device</strong> <strong>Driver</strong> Page 24 of 24

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!