From Technologic Systems Manuals
Jump to: navigation, search
TS-7700
ts-7700.gif
Product Page
Product Images
Specifications
Documentation
Schematic
Mechanical Drawing
FTP Path
Processor
Marvell PXA166 or PXA168
800MHz or 1066MHz ARMv5TE Mohawk (ARM9 compatible)
CPU Series Website
PXA16X Software Guide

Contents

1 Overview

The TS-7700 is a Computer on Module based on the TS-4710 with in the same small form factor as the TS-7500.

2 Getting Started

A Linux PC is recommended for development, and will be assumed for this documentation. For users in Windows or OSX we recommend virtualizing a Linux PC. Most of our boards run Debian and if you have no other distribution preference this is what we recommend.

Virtualization

Suggested Linux Distributions

It may be possible to develop using a Windows or OSX system, but this is not supported. Development will include accessing drives formatted for Linux and often Linux based tools.

2.1 Development Kit and Accessories

The KIT-7700 includes the items that are commonly necessary for development with the TS-7700.

KIT-7700 Contents
Item Description
MSD-4GB-USB-4710 A Sandisk MicroSD card with a Vivitar SD reader. We recommend Sandisk SD cards as that is what we use for testing. Whenever we receive batches of SD cards from our suppliers, we will pull a few cards for testing to ensure they behave within our expectations. The Vivitar reader is also recommended because it was tested to work with the most SD cards, and it does not have a potentially damaging voltage drop that many consumer SD readers have.
TS-752 The TS-752 demonstrates the flexibility of a Technologic Systems SoM by connecting FPGA driven IO pins to relays, buffered digital inputs, buffered digital outputs, and RS-485 drivers. It also provides an RS-232 driver for the serial console. A TS-ENC750 with a TS-7500 or TS-7550 can provide a complete solution for many embedded applications.
PS-5VDC-REG-8PG The PS-5VDC-REG-8PG is a 5V 2.5A power supply by Condor. Optionally type I or C adapters are available and will ship with the product if ordered to a country where this specific adapter is required. If you require one of these adapters it is recommended to put this in the comments for your order.
CB7-05 The CB7-05 is a 5 foot null modem cable. This is commonly used to connect to your workstation.
CB-USB-AMBM This is a USB A male to USB B male which is commonly used to connect the board to your PC as a USB device. This is also used for connecting the TS-9449 to your workstation for a USB to serial console.

The other options include:

Item Description
CN-PC104-40PIN-F The CN-PC104-40PIN-F is the mating connector for the 44 pin male header on the SBC. The 4 omitted pins are the JTAG pins which are only used for factory programming. The pins on this header are a very common 0.100" pitch.
WIFI-N-USB-2 WIFI-N-USB-2 description
TS-ENC750 The TS-ENC750 provides both the TS-752 and a metal enclosure.
TS-ENC750-DIN The TS-ENC750-DIN is the TS-ENC750 with a DIN rail mount.
TS-752 The TS-752 demonstrates the flexibility of a Technologic Systems SoM by connecting FPGA driven IO pins to relays, buffered digital inputs, buffered digital outputs, and RS-485 drivers. It also provides an RS-232 driver for the serial console. A TS-ENC750 with a TS-7500 or TS-7550 can provide a complete solution for many embedded applications.

2.2 Booting up the board

WARNING: Be sure to take appropriate Electrostatic Discharge (ESD) precautions. Disconnect the power source before moving, cabling, or performing any set up procedures. Inappropriate handling may cause damage to the board.

Using one of the "off the shelf" baseboards, be sure to refer to that baseboard's manual here. Different baseboards use different power connectors, voltage ranges, and may have different power requirements.

The macrocontroller only requires a 5V rail from the baseboard which may be regulated from other voltage ranges. Refer to the #TS-Socket Connector section for the POWER pins. While operating the board will typically idle at around 350mA@5V with the PXA166 or 450mA with the PXA168, but this can vary slightly based on your application. For example, every USB device can consume up to 500mA@5V. The ethernet interface can draw around 50mA while the interface is up. Every DIO pin can source up to 12mA from the FPGA. A Sandisk SD card can draw 65mA@3.3V during a write, and larger cards can consume more. A typical power supply for just the macrocontroller will allow around 1A, but a larger power supply may be needed depending on your peripherals.

Once you have applied power to the baseboard, look for console output. The next section of the manual provides information on getting the console connected. The first output is from the bootrom:

>> TS-BOOTROM - built Jan 21 2013 16:17:55
>> Copyright (c) 2012, Technologic Systems
.
.
Uncompressing Linux... done, booting the kernel.
Booted in 0.66 s
Type 'tshelp' for help
# 

The "Booting From" message will indicate your boot media. The 2 dots after indicate steps of the booting procedure. The first dot means the MBR was copied into memory and executed. The next dot indicates that the MBR executed and the kernel/initramfs were copied into memory and executed.

2.3 Get a Console

2.3.1 Option 1: Telnet

If your system is configured with zeroconf support (Avahi, Bonjour, etc) you can simply connect to the TS-4710 with:

telnet ts4710-<last 6 characters of the MAC address>.local
# You will need to use your TS-4710 MAC address, but 
# for example if you mac is 00:d0:69:01:02:03
telnet ts4710-010203.local

When the board first powers up it has two network interfaces. The first interface eth0 is configured to use IPv4LL, and eth0:0 is configured to use DHCP. The board broadcasts using multicast DNS advertising the _telnet._tcp service. You can use this to query all of the available TS-4710s on the network.

From Linux you can use the avahi commands to query for all telnet devices with:

avahi-browse _telnet._tcp

Which would return:

+   eth0 IPv4 TS-4710 console [4f47a5]                      Telnet Remote Terminal local
+   eth0 IPv4 TS-4710 console [4f471a]                      Telnet Remote Terminal local

This will show you the mac address you can use to resolve the board. In this case you can connect to either ts4710-4f47a5 or ts4710-4f47a5.


From Windows you can use Bonjour Print Services to get the dns-sd command. OSX also comes preinstalled with the same command. Once this is installed you can run:

dns-sd -B _telnet._tcp

Which will return:

Browsing for _telnet._tcp
Timestamp     A/R Flags if Domain                    Service Type              Instance Name
10:27:57.078  Add     3  2 local.                    _telnet._tcp.             TS-4710 console [4f47a5]
10:27:57.423  Add     3  2 local.                    _telnet._tcp.             TS-4710 console [4f47a5]

This will show you the mac address you can use to resolve the board. In this case you can connect to either ts4710-4f47a5.local or ts4710-4f47a5.local.

2.3.2 Option 2: Serial Console

With the development kit you should have the TS-752 which brings out the debug console ttyS0 from the ARM processor as RS232. Custom baseboards should emulate the TS-752 for bringing out console. See the schematics available on the TS-752 page. The console from the UART will use 115200 baud, 8n1 (8 data bits 1 stop bit), and no flow control.


Console from Linux

There are many serial terminal applications for Linux, but 3 common implementations would be picocom, screen, and minicom. These examples assume that your COM device is /dev/ttyUSB0 (common for USB adapters), but replace them with the COM device on your workstation.

Linux has a few applications capable of connecting to the board over serial. You can use any of these clients that may be installed or available in your workstation's package manager:

Picocom is a very small and simple client.

picocom -b 115200 /dev/ttyUSB0

Screen is a terminal multiplexer which happens to have serial support.

screen /dev/ttyUSB0 115200

Or a very commonly used client is minicom which is quite powerful:

minicom -s
  • Navigate to 'serial port setup'
  • Type "a" and change location of serial device to '/dev/ttyUSB0' then hit "enter"
  • If needed, modify the settings to match this and hit "esc" when done:
     E - Bps/Par/Bits          : 115200 8N1
     F - Hardware Flow Control : No
     G - Software Flow Control : No
  • Navigate to 'Save setup as dfl', hit "enter", and then "esc"


Console from Windows

Putty is a small simple client available for download here. Open up Device Manager to determine your console port. See the putty configuration image for more details.

Device Manager Putty Configuration

2.4 Initramfs

When the board first boots up you should have a console such as:

>> TS-BOOTROM - built Mar 14 2013 15:01:50
>> Copyright (c) 2012, Technologic Systems
.
.
Uncompressing Linux... done, booting the kernel.
Booted in 0.90s
Initramfs Web Interface: http://ts47XX-112233.local

This is a minimalistic initial ram filesystem that includes our specific utilities for the board, and is then used to bootstrap the Linux root. The initramfs is built into the kernel image so it cannot be modified without rebuilding the kernel, but it does read several bits from nonvolatile memory for common configuration options we call soft jumpers. Note: Soft jumper settings are not stored on the SD media, so re-flashing your SD card will not reset the soft jumpers. This action can only be taken from within the OS.

WARNING: Setting soft jumper 1 will boot the system straight to Debian, leaving the serial port as the only default access method. Ensure that alternate access methods (telnet, SSH, etc.) are set up and working in Debian if the serial port is not a viable access method before this jumper is set. If a lockout situation does occur, please contact us at support@embeddedarm.com
Soft Jumpers
Jumper Function
1 Boot automatically to Debian [1]
2 Reserved
3 Reserved
4 Reserved
5 Reserved
6 Reserved
7 Skip most of the init. [2]
8 Skip full DRAM test on startup [3]
  1. Initramfs boot is default. Be sure to configure Debian before setting this jumper if serial port access is not possible, see "Warning" above.
  2. This option skips a significant amount of setup and will boot to a single SD card as fast as possible with no initialization. This mode will still execute /mnt/root/ts/init if it exists, or boot to Debian if jp1 is set. Note that this will not initialize any networking in the initramfs, leaving the serial port as the only access method. If booting to Debian, see "Warning" above.
  3. The DRAM test can be used to verify the RAM, but adds approximately 20 seconds to the boot time. This should normally only be enabled when diagnosing problems.

There are 2 ways to manipulate soft jumpers on the board. The web interface at "http://ts<model>-<last 6 chars of the MAC>.local" has a list of checkboxes that will immediately change the values. You can also use tshwctl:

# Boot automatically to Debian:
tshwctl --setjp=1
 
# Or revert to the initramfs:
tshwctl --removejp=1

The Debian boot can also be inhibited by creating a file in /ts/fastboot in the Debian root. While this file exists the board will stop booting at the initramfs. If you do not have a serial console, make sure you first configure Debian's network settings first before booting directly to Debian. Once JP1 is enabled, the initramfs does not run ifplugd/udhcpc to configure the network.

Most development should be done in Debian, however many applications are capable of running from the initramfs. Utilities from Debian can be accessed under /mnt/root as read only, but for Debian services, or using apt-get a full boot into Debian should be performed. The initramfs itself cannot be easily modified, and it is not recommended to do so. The initramfs however has several hooks for applications to manipulate it's behavior.

/mnt/root/ts/init

For headless applications you can create a bash script with any initialization you require in /ts/init. This does not use the same $PATH as Debian, so you should enter the full path to any applications you intend to run from this environment. The init file does not exist by default and must be created.:

#!/bin/sh
 
/path/to/your/application &

Remember to set it executable!
chmod a+x /ts/init

/mnt/root/ts/initramfs-xinit

Graphical applications run in the initramfs should use /ts/initramfs-xinit. Users booting to Debian should use /usr/bin/default-x-session. The xinit file is used to start up a window manager and any applications. The default initramfs-xinit starts a webbrowser viewing localhost:

#!/bin/sh
# Causes .Xauthority and other temp files to be written to /root/ rather than default /
export HOME=/root/
# Disables icewm toolbars
export ICEWM_PRIVCFG=/mnt/root/root/.icewm/
 
# minimalistic window manager
icewm-lite &
 
# this loop verifies the window manager has successfully started
while ! xprop -root | grep -q _NET_SUPPORTING_WM_CHECK
do
    sleep 0.1
done
 
# This launches the fullscreen browser.    If the xinit script ever closes, x11 will close.  This is why the last
# command is the target application which is started with "exec" so it will replace the xinit process id.
exec /usr/bin/fullscreen-webkit http://localhost

/mnt/root/ts/config

This config file can be used to alter many details of the initramfs boot procedure.

## This file is included by the early init system to set various bootup settings.
## if $jp7 is enabled none of these settings will be used.

## Used to control whether the FPGA is reloaded through software.
## 1 to enable reloading (default)
## 0 to disable reloading
#CFG_FPGARELOAD="0"

## By default dns-sd is started which advertises the ts<model>-<last 6 of mac> 
## telnet and http services using zeroconf.
## 1 to enable dns-sd (default)
## 0 to disable dns-sd
#CFG_DNSSD_EN="0"

## This is used to discover hosts and advertise this host over multicast DNS.
## 1 to enable mdns (default)
## 0 to disable mdns
#CFG_MDNS_EN="0"

## ifplugd is started in the initramfs to start udhcpc, and receive an ipv4ll
## address.
## 1 to enable ifplugd (default)
## 0 to disable ifplugd
#CFG_IFPLUGD_EN="0"

## By default telnet is started on port 2323.
## 1 to enable telnet (default)
## 0 to disable telnet
##CFG_TELNET_EN="0"

## The busybox webserver is used to display a diagnostic web interface that can
## be used for development tasks such as rewriting the SD or uploading new
## software
## 1 to enable (default)
## 0 to disable
##CFG_HTTPD_EN="0"

## This eanbles a reset switch on DIO 29 (TS-7700), or DIO 9 on all of the 
## boards.  Pull low to reset the board immediately.
## 1 to enable the reset sw (default)
## 0 to disable
#CFG_RESETSW_EN="0"

## The console is forwarded through xuartctl which makes the cpu console available
## over telnet or serial console.
## 1 to enable network console (default)
## 0 to disable network console
#CFG_NETCONS_EN="0"

## By default Alsa will put the SGTL5000 chip into standby after 5 seconds of 
## inactivity.  This is desirable in that it results in lower power consumption,
## but it can result in an audible popping noise.  This setting prevents 
## standby so the pop is never heard.  
## 1 to disable standby
## 0 to enable standby (default)
#CFG_SGTLNOSTBY="1"

## xuartctl is used to access the FPGA uarts.  By default it is configured to
## be IRQ driven which is optimized for best latency, but at the cost of 
## additional CPU time.  You can reduce this by specifying a polling rate.
## The xuartctl process also binds to all network interfaces which can provide a 
## simple network API to access serial ports remotely.  You can restrict this to
## the local network with the bind option.
## Configure XUART polling 100hz
## Default is IRQ driven
CFG_XUARGS="--irq=100hz"
## Configure xuartctl to bind on localhost
## Default binds on all interfaces
#CFG_XUARGS="--bind 127.0.0.1 --irq=100hz"
## For a full list of arguments, see the xuartctl documentation here:
## http://wiki.embeddedarm.com/wiki/Xuartctl#Usage

## By default the system will probe for up to 10s on USB for a mass storage device
## and mount the first partition.  If there is an executable /tsinit script in the
## root this will be executed.  This is intended for production or updates.
## 2 to enable USB init always (adds 10s or $CFG_USBTIME to startup)
## 1 to enable USB init when jp1=0 (default)
## 0 to disable USB init always
#CFG_USBINIT="2"

## The USB init script by default blocks for 10s to detect a thumb drive that 
## contains the tsinit script.  Most flash media based drives can be detected 
## in 3s or less.  Some spinning media drives can take 10s, or potentially longer.
## This options is the number of seconds to wait before giving up on the 
## mass storage device.
#CFG_USBTIME="3"

### TS-8700
## Using the TS-8700 baseboard the board will by default initialze all of the 
## ethernet ports as individual vlan ports, eg eth0.1, eth0.2, eth0,3, and eth0.4
## The alterantive option sets Port A to eth0.1, and Ports B-D to eth0.2, or
## you can configure all ethernet ports as a single eth0 port.
## See http://wiki.embeddedarm.com/wiki/TS-8700 for more information
## 2 disables any vlan and passes through all interfaces to eth0
## 1 enables "WLAN" mode setting "A" as eth0.1, and all others as eth0.2
## 0 enables "VLAN" mode for 4 individual ports (default)
#CFG_4ETH="1"

### TS-4712 / TS-4720
## These boards include an onboard switch with 2 external ports.  By default
## the switch will detect if it is on a known baseboard that supports the second
## ethernet switch port, and set up VLAN rules to define eth0.1 and eth0.2.  The
## other option is to configure the switch to pass through the packets to eth0
## regarless of port.
## 2 Disable VLAN and pass through to eth0
## 1 Enable VLAN on all baseboards
## 0 Enable VLAN on supported baseboards (Default)
#CFG_2ETH="1"

3 Debian Configuration

For development it is recommended to go to Debian on the SD card where there is plenty of space for development work. Debian provides many more packages and a much more familiar environment for users already versed in Debian. Once here you can use apt-get to install/remove packages, configure the network, and perform other common tasks. Out of the box the Debian distribution does not have a custom username/password set. You can use "root" as the username with no password to get access to the system. Keep in mind services such as ssh require a password set before they allow connection.

3.1 Configuring the Network

Note: While we, the Technologic Systems engineers, do our best to write clear and concise instructions, we must assume certain basic skills and knowledge are present. If you are not already familiar with Linux TCP/IP networking, the instructions herein may be very confusing and might even cause consternation for both you and our Engineering support team. It is best to become well familiar with general Linux networking concepts before continuing further. Especially in scenarios where automatic configuration is being disabled in lieu of default Debian settings (which, as default, do not auto-configure). Please consider reading the full Debian documentation on network configuration: https://wiki.debian.org/NetworkConfiguration#Setting_up_an_Ethernet_Interface

From almost any Linux system you can use "ip" or the ifconfig/route commands to initially set up the network. To configure the network interface manually you can use the same set of commands in the initramfs or Debian.

# Bring up the CPU network interface
ifconfig eth0 up
 
# Or if you're on a baseboard with a second ethernet port, you can use that as:
ifconfig eth1 up
 
# Set an ip address (assumes 255.255.255.0 subnet mask)
ifconfig eth0 192.168.0.50
 
# Set a specific subnet
ifconfig eth0 192.168.0.50 netmask 255.255.0.0
 
# Configure your route.  This is the server that provides your internet connection.
route add default gw 192.168.0.1
 
# Edit /etc/resolv.conf for your DNS server
echo "nameserver 192.168.0.1" > /etc/resolv.conf

Most commonly networks will offer DHCP which can be set up with one command:

Configure DHCP in Debian:

# To setup the default CPU ethernet port
dhclient eth0
# Or if you're on a baseboard with a second ethernet port, you can use that as:
dhclient eth1
# You can configure all ethernet ports for a dhcp response with
dhclient

Configure DHCP in the initrd:

udhcpc -i eth0
# Or if you're on a baseboard with a second ethernet port, you can use that as:
udhcpc -i eth1

To make your network settings take effect on startup in Debian, edit /etc/network/interfaces:

 # Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or 
 # /usr/share/doc/ifupdown/examples for more information.          
                                                                   
 # We always want the loopback interface.                          
 #                                                                 
 auto lo                                                           
 iface lo inet loopback                                            
                                                                   
 auto eth0                                                         
 iface eth0 inet static                                            
   address 192.168.0.50                                            
   netmask 255.255.255.0                                           
   gateway 192.168.0.1                                             
 auto eth1                                                         
 iface eth1 inet dhcp
Note: During Debian's startup it will assign the interfaces eth0 and eth1 to the detected mac addresses in /etc/udev/rules.d/70-persistent-net.rules. If the system is imaged while this file exists it will assign the new interfaces as eth1 and eth2. This file is generated automatically on startup, and should be removed before your first software image is created. The initrd network configuration does not use this file.

In this example eth0 is a static configuration and eth1 receives its configuration from the DHCP server. For more information on network configuration in Debian see their documentation here.

3.1.1 WIFI Client

This board optionally supports 802.11 through the WIFI-N-USB-2 module using the ath9k_htc driver.

Scan for a network

ifconfig wlan0 up
 
# Scan for available networks
iwlist wlan0 scan

In this case I'm connecting to "default" which is an open network:

          Cell 03 - Address: c0:ff:ee:c0:ff:ee
                    Mode:Managed
                    ESSID:"default"
                    Channel:2
                    Encryption key:off
                    Bit Rates:9 Mb/s

To connect to this open network:

iwconfig wlan0 essid "default"

You can use the iwconfig command to determine if you have authenticated to an access point. Before connecting it will show something similar to this:

# iwconfig wlan0
wlan0     IEEE 802.11bgn  ESSID:"default"  
          Mode:Managed  Frequency:2.417 GHz  Access Point: c0:ff:ee:c0:ff:ee   
          Bit Rate=1 Mb/s   Tx-Power=20 dBm   
          Retry  long limit:7   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off
          Link Quality=70/70  Signal level=-34 dBm  
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

If you are connecting using WEP, you will need to define a network key:

iwconfig wlan0 essid "default" key "yourpassword"

If you are connecting to WPA you will need to use wpa_passphrase and wpa_supplicant:

wpa_passphrase the_essid the_password > /etc/wpa_supplicant.conf

Now that you have the configuration file, you will need to start the wpa_supplicant daemon:

wpa_supplicant -Dwext -iwlan0 -c/etc/wpa_supplicant.conf -B

Now you are connected to the network, but this would be close to the equivalent of connecting a network cable. To connect to the internet or talk to your internal network you will need to configure the interface. See the #Configuring the Network for more information, but commonly you can just run:

dhclient wlan0
Note: Some older images did not include the "crda" and "iw" packages required to make a wireless connection. If you cannot get an ip address you may want to connect over ethernet and install these packages with "apt-get install crda iw -y".

3.1.2 Host a WIFI Access Point

The software image includes a build of compat-drivers from 3.8 so a large amount of wireless devices are supported. Some devices support AP/Master mode which can be used to host an access point. The WIFI-N-USB-2 module we provide also supports this mode.

First install hostapd to manage the access point:

apt-get update && apt-get install hostapd -y

Edit /etc/hostapd/hostapd.conf to include:

interface=wlan0
driver=nl80211
ssid=YourAPName
channel=1
Note: Refer to the kernel's hostapd documentation for more wireless configuration options.

To start the access point launch hostapd:

hostapd /etc/hostapd/hostapd.conf &

This will create a valid wireless access point, however many devices will not be able to connect without either a static connection, or a DHCP server. Refer to Debian's documentation for more details on DHCP configuration.

3.2 Installing New Software

Debian provides the apt-get system which lets you manage pre-built applications. Before you do this you need to update Debian's list of package versions and locations. This assumes you have a valid network connection to the internet.

Debian Squeeze has been moved to archive so you will need to update /etc/apt/sources.list to contain only these two lines:

 deb http://archive.debian.org/debian squeeze main
 deb-src http://archive.debian.org/debian squeeze main
apt-get update

For example, lets say you wanted to install openjdk for Java support. You can use the apt-cache command to search the local cache of Debian's packages.

 <user>@<hostname>:~# apt-cache search openjdk                                                                                  
 icedtea-6-jre-cacao - Alternative JVM for OpenJDK, using Cacao                                                           
 icedtea6-plugin - web browser plugin based on OpenJDK and IcedTea to execute Java applets                                 
 openjdk-6-dbg - Java runtime based on OpenJDK (debugging symbols)                                                        
 openjdk-6-demo - Java runtime based on OpenJDK (demos and examples)                                                      
 openjdk-6-doc - OpenJDK Development Kit (JDK) documentation                                                              
 openjdk-6-jdk - OpenJDK Development Kit (JDK)                                                                            
 openjdk-6-jre-headless - OpenJDK Java runtime, using Hotspot Zero (headless)                                             
 openjdk-6-jre-lib - OpenJDK Java runtime (architecture independent libraries)                                            
 openjdk-6-jre-zero - Alternative JVM for OpenJDK, using Zero/Shark                                                       
 openjdk-6-jre - OpenJDK Java runtime, using Hotspot Zero                                                                 
 openjdk-6-source - OpenJDK Development Kit (JDK) source files                                                            
 openoffice.org - office productivity suite                                                                               
 freemind - Java Program for creating and viewing Mindmaps                                                                
 default-jdk-doc - Standard Java or Java compatible Development Kit (documentation)                                       
 default-jdk - Standard Java or Java compatible Development Kit                                                           
 default-jre-headless - Standard Java or Java compatible Runtime (headless)                                               
 default-jre - Standard Java or Java compatible Runtime                                                                   

In this case you will likely want openjdk-6-jre to provide a runtime environment, and possibly openjdk-6-jdk to provide a development environment. You can often find the names of packages from Debian's wiki or from just searching on google as well.

Once you have the package name you can use apt-get to install the package and any dependencies. This assumes you have a network connection to the internet.

apt-get install openjdk-6-jre
# You can also chain packages to be installed
apt-get install openjdk-6-jre nano vim mplayer

For more information on using apt-get refer to Debian's documentation here.

3.3 Setting up SSH

On our boards we include the Debian package for openssh-server, but we remove the automatically generated keys for security reasons. To regenerate these keys:

dpkg-reconfigure openssh-server

Make sure your board is configured properly on the network, and set a password for your remote user. SSH will not allow remote connections without a password or a shared key.

passwd root

You should now be able to connect from a remote Linux or OSX system using "ssh" or from Windows using a client such as putty.

Note: If your intended application does not have a DNS source on the target network, it can save login time to add "UseDNS no" in /etc/ssh/sshd_config.

3.4 Starting Automatically

From Debian the most straightforward way to add your application to startup is to create a startup script. This is an example simple startup script that will toggle the red led on during startup, and off during shutdown. In this case I'll name the file customstartup, but you can replace this with your application name as well.

Edit the file /etc/init.d/customstartup to contain this:

 #! /bin/sh
 # /etc/init.d/customstartup
 
 case "$1" in
   start)
     /path/to/your/application
     ## If you are launching a daemon or other long running processes
     ## this should be started with
     # nohup /usr/local/bin/yourdaemon &
     ;;
   stop)
     # if you have anything that needs to run on shutdown
     /path/to/your/shutdown/scripts
     ;;
   *)
     echo "Usage: customstartup start|stop" >&2
     exit 3
     ;;
 esac
 
 exit 0
Note: The $PATH variable is not set up by default in init scripts so this will either need to be done manually or the full path to your application must be included.

To make this run during startup and shutdown:

update-rc.d customstartup defaults

To manually start and stop the script:

/etc/init.d/customstartup start
/etc/init.d/customstartup stop

While this is useful for headless applications, if you are using X11 you should modify "/usr/bin/default-x-session":

#!/bin/sh
 
export HOME=/root/
export ICEWM_PRIVCFG=/mnt/root/root/.icewm/
 
icewm-lite &
 
while ! xprop -root | grep -q _NET_SUPPORTING_WM_CHECK
do
    sleep 0.1
done
 
exec /usr/bin/fullscreen-webkit http://127.0.0.1

Replace fullscreen-webkit with your own graphical application.

3.5 Creating a Custom Startup Splash

Our splash screens are generated by writing the raw pixel format directly to the screen. For our touchscreens this is RGB565. To generate this first create a PNG of your logo. You can use ffmpeg either on the board installed from the apt repositories, or from another desktop system. When designing your splash screen keep in mind that it will compress much better in this format when there are solid colors. Our default splash has our logo in the center with a solid black background at 800x480 which is about 3kb. If the file is too large you may have to reformat the disk to expand the size of the initrd.

# Replace image.png with your filename
ffmpeg -vcodec png -i image.png -vcodec rawvideo -f rawvideo -pix_fmt rgb565 splash-800x480
 
gzip splash-800x480

In the initrd you will find a splash-<resolution>.gz which is loaded automatically on startup. The actual resolution of the PNG should match the size of your display as well. The resolution is varied based on which display you are using:

Baseboard Resolution
TS-TPC-8390 800x480
TS-TPC-8400 640x480
TS-TPC-8900 800x600

4 Backup / Restore

If you are using a Windows workstation there is no support for writing directly to block devices. However, as long as one of your booting methods still can boot a kernel and the initrd you can rewrite everything by using a usb drive. This is also a good way to blast many stock boards when moving your product into production. You can find more information about this method with an example script here.

Note: Note that the MBR installed by default on this board contains a 446 byte bootloader program that loads the initial power-on kernel and initrd from the first and second partitions. Replacing it with an MBR found on a PC would not work as a PC MBR contains an x86 code bootup program.

4.1 MicroSD Card

WARNING: While tools exist for writing image from Windows or other operating systems, we do not support their use. If they are not careful to make sure the OS has not mounted the FS, or existing drivers have ceased any access to the card, they may end up with corruption that is not immediately apparent upon using the card. This may present as sublte corruption, or a card that does not boot at all. We do not encourage use of any other process other than what is described in this section.
MicroSD.png Click to download the latest 4GB SD card image.

Using onboard web interface

The initramfs contains a #Web interface that can be used to backup/restore the software image. From the main page, you can download a complete backup containing the MBR, Kernel, initramfs, and Debian filesystem by clicking "backup.dd". You can click "Choose File" and browse to a previous backup.dd, or the link above to rewrite the SD card.

Using another Linux workstation

If you do not have an SD card that can boot to the initramfs, you can download the sd card image and rewrite this from a Linux workstation. A USB MicroSD adapter can be used to access the card. First, you must find out which /dev/ device corresponds with your USB reader/writer.

Step 1 Option 1 (lsblk)


Newer distributions include a utility called "lsblk" which allows simple identification of the intended card:

lsblk
 NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
 sda      8:0    0   400G  0 disk 
 ├─sda1   8:1    0   398G  0 part /
 ├─sda2   8:2    0     1K  0 part 
 └─sda5   8:5    0     2G  0 part [SWAP]
 sr0     11:0    1  1024M  0 rom  
 sdc      8:32   1   3.9G  0 disk 
 ├─sdc1   8:33   1   7.9M  0 part 
 ├─sdc2   8:34   1     2M  0 part 
 ├─sdc3   8:35   1     2M  0 part 
 └─sdc4   8:36   1   2.8G  0 part  

In this case my SD card is 4GB, so sdc is the target device.

Step 1 Option 2 (dmesg)


After plugging in the device, you can use dmesg to list

 scsi 9:0:0:0: Direct-Access     Generic  Storage Device   0.00 PQ: 0 ANSI: 2
 sd 9:0:0:0: Attached scsi generic sg2 type 0
 sd 9:0:0:0: [sdb] 7744512 512-byte logical blocks: (3.96 GB/3.69 GiB)

In this case, sdc is shown as a 3.96GB card.

Step 2


Once you have the target /dev/ device you can use "dd" to backup/restore the card. To restore the board to stock, or rewrite to the latest SD image:

wget ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/ts-4710-linux/binaries/ts-images/4gbsd-471x-latest.dd.bz2
bzip2 -d 4gbsd-471x-latest.dd.bz2
 
# Specify your block device instead of /dev/sdc
# Note that this does not include a partition, so use /dev/sdc instead of
# using /dev/sdc1
dd if=4gbsd-471x-latest.dd conv=fsync bs=4M of=/dev/sdc

To take a backup of your entire SD card, you can switch the input file and the output file:

dd if=/dev/sdc conv=fsync bs=4M of=backup.dd

5 Software Development

Most of our examples are going to be in C, but Debian will include support for many more programming languages. Including (but not limited to) C++, PERL, PHP, SH, Java, BASIC, TCL, and Python. Most of the functionality from our software examples can be done from using system calls to run our userspace utilities. For higher performance, you will need to either use C/C++ or find functionally equivalent ways to perform the same actions as our examples. Our userspace applications are all designed to go through a TCP interface. By looking at the source for these applications, you can learn our protocol for communicating with the hardware interfaces in any language.

The most common method of development is directly on the SBC. Since debian has space available on the SD card, we include the build-essentials package which comes with everything you need to do C/C++ development on the board.


Editors

Vim is a very common editor to use in Linux. While it isn't the most intuitive at a first glance, you can run 'vimtutor' to get a ~30 minute instruction on how to use this editor. Once you get past the initial learning curve it can make you very productive. You can find the vim documentation here.

Emacs is another very common editor. Similar to vim, it is difficult to learn but rewarding in productivity. You can find documentation on emacs here.

Nano while not as commonly used for development is the easiest. It doesn't have as many features to assist in code development, but is much simpler to begin using right away. If you've used 'edit' on Windows/DOS, this will be very familiar. You can find nano documentation here.

Compilers

We only recommend the gnu compiler collection. There are many other commercial compilers which can also be used, but will not be supported by us. You can install gcc on most boards in Debian by simply running 'apt-get update && apt-get install build-essential'. This will include everything needed for standard development in c/c++.

You can find the gcc documentation here. You can find a simple hello world tutorial for c++ with gcc here.

Build tools

When developing your application typing out the compiler commands with all of your arguments would take forever. The most common way to handle these build systems is using a make file. This lets you define your project sources, libraries, linking, and desired targets. You can read more about makefiles here.

If you are building an application intended to be more portable than on this one system, you can also look into the automake tools which are intended to help make that easier. You can find an introduction to the autotools here.

Cmake is another alternative which generates a makefile. This is generally simpler than using automake, but is not as mature as the automake tools. You can find a tutorial here.

Debuggers

Linux has a few tools which are very helpful for debugging code. The first of which is gdb (part of the gnu compiler collection). This lets you run your code with breakpoints, get backgraces, step forward or backward, and pick apart memory while your application executes. You can find documentation on gdb here.

Strace will allow you to watch how your application interacts with the running kernel which can be useful for diagnostics. You can find the manual page here.

Ltrace will do the same thing with any generic library. You can find the manual page here.

5.1 Accessing Hardware Registers

The standard assumption in Linux is that kernel drivers are required in order to control hardware. However, it is also possible to talk to hardware devices from user space. In doing so, one does not have to be aware of the Linux kernel development process. This is the recommended way of accessing hardware on a TS-SOCKET system. The special /dev/mem device implements a way to access the physical memory from the protected user space, allowing reading and writing to any specific memory register. Applications may be allowed temporary access through memory space windows granted by the mmap() system call applied to the /dev/mem device node.

The following C code is provided as an example of how to set up user space access to the SYSCON registers at base address 0x80004000:

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
static volatile unsigned short *syscon;
static unsigned short peek16(unsigned int adr) {
	return syscon[adr / 2];
}
static void poke16(unsigned int adr, unsigned short val) {
	syscon[adr / 2] = val;
}
 
int main(void) {
        int devmem = open("/dev/mem", O_RDWR|O_SYNC);
 
	assert(devmem != -1);
	syscon = (unsigned short *) mmap(0, 4096,
	  PROT_READ | PROT_WRITE, MAP_SHARED, devmem, 0x80004000);
 
        poke16(0x6, 0x3); // disable watchdog
        poke16(0x12, peek16(0x12) | 0x1800); // turn on both LEDs
 
        return 0;
}

Important Notes about the preceding example:

  • The peek16 and poke16 wrapper functions make the code more readable due to how pointer arithmetic/array indexing works in C, since the same offsets from the register map appear in the code.
  • Make sure to open using O_SYNC, otherwise you may get a cachable MMU mapping which, unless you know what you're doing, probably is not what you want when dealing with hardware registers.
  • mmap() must be called only on pagesize (4096 byte) boundaries and size must at least have pagesize granularity.
  • Only the root user can open '/dev/mem'. For testing, this just means the tester needs to be root, which is normal in embedded Linux. For deployment in the field under Debian, this can be an issue because the init process does not have root privileges. To get around this, make sure the binary is owned by root and has the setuid bit set. The command 'chmod +s mydriver' will set the setuid flag.
  • The pointers into memory space should have the same bit width as the registers they are accessing. In the example above, the TS-4710 FPGA registers are 16 bits wide, so an unsigned short pointer is used. With very few exceptions, FPGA registers on TS-SOCKET macrocontrollers will be 16 bits wide and CPU registers will be 32 bits wide. Unsigned int, unsigned short, and unsigned char pointers should be used for 32, 16, and 8 bit registers, respectively.
  • When compiling ARM code that emits 16 bit or 8 bit hardware register accesses, it is important to add the compiler switch -mcpu=arm9. Otherwise the wrong opcodes may be emitted by the compiler and unexpected behavior will occur.
  • Pointers into memory space must be declared as volatile.

5.2 Cross Compiling

While you can develop entirely on the board itself, if you prefer to develop from another x86 compatible Linux system we have a cross compiler available. For this board you will want to use this toolchain. To compile your application, you only need to use the version of GCC in the cross toolchain instead of the version supplied with your distribution. The resulting binary will be for ARM.

[user@localhost]$ /opt/arm-2008q3/bin/arm-none-linux-gnueabi-gcc hello.c -o hello
[user@localhost]$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.14, not stripped

This is one of the simplest examples. If you want to work with a project, you will typically create a makefile. You can read more about makefiles here. Another common requirement is linking to third party libraries provided by Debian on the board. There is no exact set of steps you can take for every project, but the process will be very much the same. Find the headers, and the libraries. Sometimes you have to also copy over their binaries. In this example, I will link to sqlite from Debian (which will also work in the Ubuntu image).

Install the sqlite library and header on the board:

apt-get update && apt-get install -y libsqlite3-0 libsqlite-dev

This will fetch the binaries from the internet and install them. You can list the installed files with dpkg:

dpkg -L libsqlite3-0 libsqlite3-dev

The interesting files from this output will be the .so files, and the .h files. In this case you will need to copy these files to your project directory.

I have a sample example with libsqlite3 below. This is not intended to provide any functionality, but just call functions provided by sqlite.

#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
 
int main(int argc, char **argv)
{
	sqlite3 *db;
	char *zErrMsg = 0;
	int rc;
	printf("opening test.db\n");
	rc = sqlite3_open("test.db", &db);
	if(rc){
		fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
		sqlite3_close(db);
		exit(1);
	}
	if(rc!=SQLITE_OK){
		fprintf(stderr, "SQL error: %s\n", zErrMsg);
	}
	printf("closing test.db\n");
	sqlite3_close(db);
	return 0;
}

To build this with the external libraries I have the makefile below. This will have to be adjusted for your toolchain path. In this example I placed the headers in external/include and the library in external/lib.

CC=/opt/arm-2008q3/bin/arm-none-linux-gnueabi-gcc
CFLAGS=-c -Wall
 
all: sqlitetest
 
sqlitetest: sqlitetest.o
        $(CC) sqlitetest.o external/lib/libsqlite3.so.0 -o sqlitetest
sqlitetest.o: sqlitetest.c
        $(CC) $(CFLAGS) sqlitetest.c -Iexternal/include/
 
clean:  
        rm -rf *o sqlitetest.o sqlitetest

You can then copy this directly to the board and execute it. There are many ways to transfer the compiled binaries to the board. Using a network filesystem such as sshfs or NFS will be the simplest to use if you are frequently updating data, but will require more setup. See your linux distribution's manual for more details. The simplest network method is using ssh/sftp. You can use winscp if from windows, or scp from linux. Make sure you set a password from debian for root. Otherwise the ssh server will deny connections. From winscp, enter the ip address of the SBC, the root username, and the password you have set. This will provide you with an explorer window you can drag files into.

For scp in linux, run:

#replace with your app name and your SBC IP address
scp sqlitetest root@192.168.0.50:/root/

After transferring the file to the board, execute it:

ts:~# ./sqlitetest 
opening test.db
closing test.db

5.3 Compile the Kernel

For adding new support to the kernel, or recompiling with more specific options you will need to have an X86 compatible linux host available that can handle the cross compiling. Compiling the kernel on the board is not supported or recommended. Before building the kernel you will need to install a few support libraries on your workstation:

Prerequisites

RHEL/Fedora/CentOS:

yum install ncurses-devel ncurses
yum groupinstall "Development Tools" "Development Libraries"

Ubuntu/Debian:

sudo apt-get install build-essential libncurses5-dev libncursesw5-dev git
## If you are on a 64-bit system then 32-bit libraries will be required for the toolchain
# sudo apt-get install ia32-libs
# On newer distributions with Multiarch support:
#sudo dpkg --add-architecture i386
#sudo apt-get update
#sudo apt-get install libc6-dev:i386 zlib1g-dev:i386

For other distributions, please refer to their documentation to find equivalent tools.

Set up the Sources and Toolchain

# Download the cross compile toolchain (EABI)from Technologic Systems:
wget ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/ts-4700-linux/cross-toolchains/arm-2008q3.tar.gz
 
# Extract the toolchain
tar xvf arm-2008q3.tar.gz
 
# Move arm-2008q3 to a permanent location, eg /opt/toolchains/
mkdir /opt/toolchains/
mv arm-2008q3 /opt/toolchains/
 
# Download the Kernel sources
git clone https://github.com/embeddedarm/linux-2.6.34-ts471x.git
 
cd linux-2.6.34-ts471x
 
# Set the CROSS_COMPILE variable to the absolute path to the toolchain.
export CROSS_COMPILE=/opt/toolchains/arm-2008q3/bin/arm-none-linux-gnueabi-
export ARCH=arm
 
# This sets up the default configuration that we ship with for the TS-471x
make ts471x_defconfig

Once you have the configuration ready you can make your changes to the kernel. Commonly a reason for recompiling is to add support that was not built into the standard image's kernel. You can get a menu to browse available options by running:

make menuconfig

You can use the "/" key to search for specific terms through the kernel.

Build the kernel

Once you have it configured you can begin building the kernel. This usually takes about 5-10 minutes.

make

The new kernel will be at "arch/arm/boot/Image".

Install the Kernel and Modules

Install the target SD card in your workstation, and mount the Debian partition. For example, if your workstation's SD card is /dev/sdb:

# Update this to point to your SD card block device
export DEV=/dev/sdb
sudo mkdir /mnt/sd/
sudo dd if=arch/arm/boot/zImage of="$DEV"1 conv=fsync
sudo mount "$DEV"2 /mnt/sd/
INSTALL_MOD_PATH=/mnt/sd/ sudo -E make modules_install
INSTALL_HDR_PATH=/mnt/sd/ sudo -E make headers_install
sudo umount /mnt/sd/
sync

Build compat-drivers (optional)

Optionally if you use the WIFI-N-USB2 module or another recent USB wireless device you can build "compat-drivers" which provides more recent compatibility on this kernel.

# Assuming you are still in the 2.6.34 kernel directory
cd ../
export ARCH=arm
export CROSS_COMPILE=/opt/toolchains/arm-2008q3/bin/arm-none-linux-gnueabi-
 
# Update this to point to your SD card block device
export DEV=/dev/sdb
export KLIB=/mnt/sd
# Update these paths to point to the linux tree
export KLIB_BUILD=../linux-2.6.34-ts471x/
 
wget http://www.kernel.org/pub/linux/kernel/projects/backports/stable/v3.8.3/compat-drivers-3.8.3-2-snpu.tar.bz2 && \
tar xf compat-drivers-3.8.3-2-snpu.tar.bz2 && \
cd compat-drivers-3.8.3-2-snpu/ && \
make && \
sudo mount "$DEV"2 /mnt/sd/ && \
INSTALL_MOD_PATH=/mnt/sd/ sudo -E make install-modules && \
sudo umount /mnt/sd/ && \
sync

5.4 Using the Oracle JRE

Oracle provides a headless JRE binary for the ARMv5 processor series which is compatible with this processor. In many cases the OpenJDK JRE is sufficient for an application, but Oracle's JRE provides better performance. To install this JRE, first accept the license and download this from Oracle here.

Your version number may be slightly different, but the process should remain the same:

tar -xf ejre-7u45-fcs-b15-linux-arm-sflt-headless-26_sep_2013.tar.gz
mv ejre1.7.0_45/ /usr/share/oracle-jre/
ln -s /usr/share/oracle-jre/bin/java /usr/bin/java

You can verify this is installed by checking the version:

root@ts:~# java -version
java version "1.7.0_45"
Java(TM) SE Embedded Runtime Environment (build 1.7.0_45-b15, headless)
Java HotSpot(TM) Embedded Client VM (build 24.45-b08, mixed mode)

6 Features

6.1 Software images

6.2 CPU

The TS-4710 supports two processors from Marvell's Armada 100 series. The common features will be described in other sections, but for more details see the CPU user guide.

PXA16X Feature Comparison
Feature PXA166 (88AP166) PXA168 (88AP168)
Frequency 800MHz 1066MHz
Video Playback Acceleration (gstreamer) Supported up to D1 Supported up to 720p
Maximum Framebuffer Fesolution Up to WUXGA Up to WUXGA
PCI-Express support N/A 1x PCI-E 2.0

6.3 MicroSD Card Interface

This macrocontroller uses our SD controller implementation which supports MicroSD, MicroSDHC, and MicroSDXC cards. This controller has been tested with Sandisk Extreme SD cards which allow read speeds up to 20.5MB/s, and write speeds up to 21.5MB/s.

The support for the SD controller is provided by sdctl which serves up a /dev/nbd0 for the entire block device. The kernel also includes a module that will break this up into partitions. Our default software image contains 2 partitions:

Device Contents
/dev/nbd0 SD Card block device
/dev/nbd0p1 Kernel and initramfs
/dev/nbd0p2 Full Linux Root

6.4 DoubleStore

This series supports DoubleStore which can be used to significantly increase the reliability of SD cards. This allows one SD image to be written to two cards allowing redundancy among both SD cards. See our white paper for more information on the concept. Development can take place with a single MicroSD card, but for using DoubleStore 2 MicroSD cards are used.

The default SD image is 3GB which is designed to fit in a dual-card Doublestore configuration. When dual card doublestore is used it stores the same image on both cards and also includes metadata and checksums for the entire image.

You can use the dblstorctl utility to work with DoubleStore on your Linux workstation. The simplest way to get doublestore set up is to first take a backup of your SD image, and then use dblstorctl on a workstation to convert it:

export INPUTIMAGE="yourimagebackup.dd"
eval $(stat -c "imgsize=%s" $INPUTIMAGE)
dblstorctl --primary ${INPUTIMAGE}.dblstor --fallback /dev/null --init --writeimg "$INPUTIMAGE" --size=${imgsize}B

This will output yourimagebackup.dd.dblstor which can be written directly to both SD cards:

dd if=yourimagebackup.dd bs=4M conv=fsync of=/dev/sdb # replace sdb with your SD card device

The board will boot the same using the DoubleStore MicroSD cards, but sdctl includes additional information:

# sdctl --stats
nbdpid=338
nbd_readreqs=1508
nbd_read_blks=95490
nbd_writereqs=0
nbd_write_blks=0
nbd_seek_past_eof_errs=0
sdcard_resets=4
read_seeks=1261
write_seeks=0
size=0x641800
humanized_size=3.35GB
fb_offset=-6559744
primary_tainted=0
primary_failed=0
fallback_tainted=0
fallback_failed=0
resilver_pct_done=0
lifetime_write_blks=59038888
humanized_lifetime_write_blks=30.22GB
errors=0
unrecoverable_errors=0
conflicts=0
fallback_configuration="separate disk"

fallback_configuration should read "seperate disk" when booting doublestore correctly. For diagnostics, the tainted and failed settings are the most relevant:

primary_tainted=0
primary_failed=0
fallback_tainted=0
fallback_failed=0

When a card is tainted, the LED near the card will begin to blink. This indicates Doublestore has seen the card perform an unexpected behavior that DoubleStore was able to correct.

6.5 Interrupts

We include a userspace IRQ patch in our kernels. This allows you to receive interrupts from your applications where you would normally have to write a kernel driver. This works by creating a file for each interrupt in '/proc/irq/<irqnum>/irq'. The new irq file allows you to block on a read on the file until an interrupt fires.

The original patch is documented here.

The Linux kernel supports up to 16 IRQs from the FPGA. When the CPU receives an IRQ from the FPGA, it uses the IRQ register in the #Syscon to find out which IRQ on the MUX is triggering. Currently only three IRQs are used. Off-board IRQs 5, 6, and 7 correspond to FPGA IRQs 0, 1, and 2, respectively. FPGA IRQs 3 to 15 are reserved for future uses. If the DIO pins are not being used as IRQs, they can be masked out by writing 0 to the corresponding bit in the IRQ mask register.

IRQ # Name
64 XUART IRQ
65 CAN1 IRQ
66 Reserved
70 EVGPIO


This example below will work with any of our TS-Socket boards running Linux. This opens the IRQ number specified in the first argument and prints when it detects an IRQ.

#include <stdio.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
 
int main(int argc, char **argv)
{
	char proc_irq[32];
	int ret, irqfd = 0;
	int buf; // Holds irq junk data
	fd_set fds;
 
	if(argc < 2) {
		printf("Usage: %s <irq number>\n", argv[0]);
		return 1;
	}
 
	snprintf(proc_irq, sizeof(proc_irq), "/proc/irq/%d/irq", atoi(argv[1]));
	irqfd = open(proc_irq, O_RDONLY| O_NONBLOCK, S_IREAD);
 
	if(irqfd == -1) {
		printf("Could not open IRQ %s\n", argv[1]);
		return 1;
	}
 
	while(1) {
		FD_SET(irqfd, &fds); //add the fd to the set
		// See if the IRQ has any data available to read
		ret = select(irqfd + 1, &fds, NULL, NULL, NULL);
 
		if(FD_ISSET(irqfd, &fds))
		{
			FD_CLR(irqfd, &fds);  //Remove the filedes from set
			printf("IRQ detected\n");
 
			// Clear the junk data in the IRQ file
			read(irqfd, &buf, sizeof(buf));
		}
 
		//Sleep, or do any other processing here
		usleep(10000);
	}
 
	return 0;
}

6.6 External Reset

The external reset pin (DIO 9) will reset the CPU by default when it is low. You can disable this functionality to use this as a DIO by running:

tshwctl --resetswitchoff

This can be disabled with the CFG_RESETSW_EN=0 option in the #Initramfs.

6.7 RTC

The RTC is accessed using tshwctl. This is automatically retrieved on startup, but must be set manually.

# Save the running system clock to the RTC
tshwctl --setrtc
 
# Set the system clock from the RTC
tshwctl --getrtc

6.8 NVRAM

The RTC has an included 128-byte battery-backed NVRAM which can be accessed using tshwctl. Its contents will remain with the main power off, so long as the RTC battery is installed and withing a valid voltage range.

tshwctl --nvram

This will return a format such as:

 nvram0=0xf7f8a73e
 nvram1=0x2fef5ae0
 nvram2=0x48ca4278
 ...
 nvram31=0x70544510

This breaks up the NVRAM into 32x 32-bit registers which can be accessed in bash. As this uses the name=value output, you can use "eval" for simple parsing:

eval `tshwctl --nvram`
echo $nvram2

From the above value, this would return 0x48ca4278. To set values, you can use environment variables:

nvram0=0x42 tshwctl --nvram

If you read back nvram0, this should now confirm the value is 0x42.

6.9 Temperature Sensor

This macrocontroller includes temperature sensors located on the CPU and RTC. Both of these can be read using tshwctl:

tshwctl --rtctemp
tshwctl --cputemp

Both of these will return the temperature in millicelsius.

6.10 LEDs

On all of our baseboards we include 2 indicator LEDs which are under software control. You can manipulate these using "hwctl --greenledon --redledon" or "tshwctl --greenledoff --redledoff". The LEDs have 4 behaviors from default software. The LEDs are also controllable via the Syscon register at offset 0x12.

Green Behavior Red behavior Meaning
Solid On Off System is booted and running
Solid On On for approximately 15s, then off Once the system has booted the kernel and executed the startup script, it will check for a USB device and then determine if it is a mass storage device. This is used for updates/blasting through USB. Once it determines this is not a mass storage device the red LED will turn back off.
On for 10s, off for 100ms, and repeating Turns on after Green turns off for 300ms, and then turns off for 10s The watchdog is continuously resetting the board. This happens when the system cannot find a valid boot device, or the watchdog is otherwise not being fed. This is normally fed by tshwctl once a valid boot media has started. See the #Watchdog section for more details.
Off Off The FPGA is not able to start. Typically either the board is not being supplied with enough voltage, or the FPGA has been otherwise damaged. If a stable 5V is being provided and the supply is capable of providing at least 1A to the macrocontroller, an RMA is suggested.
Blinking about 5ms on, about 10ms off. Blinking about 5ms on, about 10ms off. The board is receiving too little power, or something is drawing too much current from the macrocontroller's power rails.

6.11 Web Interface

This macrocontroller includes a web interface that can be used to simplify common tasks when working with our embedded systems.

Uploading files


On the main page you can select a file and upload. These have various functions depending on the file extensions:

Filename/Extension Description
*.vme.bz2 Upload FPGA to be soft reloaded automatically on startup. This will be copied to "/ts/" path in the linux root filesystem.
ko.tar.bz2 While most kernel modules will be loaded automatically when needed, if you include a ko.tar.bz2 this will insmod each file in the archive automatically on startup. This will be copied to the "/ts/" path in the linux root filesystem.
init If this file exists and the JP1 is not set, the board will boot to the initramfs and execute this script. This can be used to have an application automatically run on startup without proceeding with the Linux root filesystem's traditionally lengthy startup. This can have an application running within seconds after poweron. The $PATH variable is set up to be abel to resolve most applications in the linux root filesystem, and the libraries of the full distribution are available. As this does not run through the normal startup, any running services or network configuration will need to be started manually.
Image, zImage, kernel*.dd This will automatically replace the first partition containing the Kernel.
root*.dd This will completely replace the second partition with the uploaded dd file.
mbr.dd|mbr*.dd Replace the MBR on the current boot image.
*.dd Any file not caught by one of the previous "*.dd" filenames will entirely replace the SD image.
*.sh Any file named *.sh will automatically be copied to /tmp, set as executable and run.
root*.tar This will remove all data from the linux root filesystem and replace it with the contents of the uploaded root*.tar file.
src*.tar This will extract the contents to the "/ts/" directory in the Linux rootfilesystem and if present, execute the "Makefile". This could be used to build a project, and automatically install it.
*.c *.cpp Any uploaded c/cpp file will automatically be compiled and executed. The applications "stdout" will be printed out to the web page.
* Any other files not captured by a previous pattern will be copied to the "/ts/" path in the Linux root filesystem.

Any uploaded file can be compressed with bzip2 or gzip before uploading. The file will be decompressed and then processed as normal as described in the above table.

Downloading Files


On the main page there is a download link for 4 files. Any downloaded file will be renamed to contain the date in the format "date -Iminutes".

Filename Description
backup.dd This is a backup containing the MBR, Kernel/initramfs, and Linux root filesystem.
root.dd This is a backup of a complete dd of the Linux root filesystem.
root.tar The root.tar contains a complete tar of the contents in the root filesystem.
kernel.dd This file contains a copy of the kernel and initramfs.

Duplicating an SD card


This page can be used to either duplicate an SD card, or convert a software image to a single or dual Doublestore card configuration. When this page is loaded it copies the kernel/initramfs to ram. You will need to have the root.tar downloaded before continuing.

Once you have loaded this page and you have a copy of the root.tar, you can either remove the current SD card, or leave it in if you intend to convert it to DoubleStore. On step 2, you can select "Standard" to write a new sd card without doublestore, or you can create a single or dual card configuration. Click "Format card" after selecting either option.

After being formatted you can upload the root*.tar file to reformat the rest of the card. Once this is completed, you can reboot to test out the card, or restart the procedure to create another card.

Find other TS41X boards


By default this board broadcasts itself using multicast DNS which can be used to detect all other similar boards on the network. This will print out the last 6 of the MAC address which can be used to uniquely identify each board.

6.12 Ethernet Port

The Marvell processor implements a 10/100 ethernet controller with support built into the Linux kernel. You can use standard Linux utilities such as ifconfig/ip to control this interface. See the #Configuring the Network section for more details. For the specifics of this interface see the CPU manual.

6.13 DIO

DIO Number Location Alternate Function
30 44-pin Header pin 5 Mode 2/XUART0 TX
27 44-pin Header pin 6 XUART0 RX
29 44-pin Header pin 9 #External Reset
28 44-pin Header pin 11
26 44-pin Header pin 12
0 44-pin Header pin 13
25 44-pin Header pin 14
1 44-pin Header pin 19 XUART1 TX
2 44-pin Header pin 20 XUART1 RX
3 44-pin Header pin 21 XUART2 TX
4 44-pin Header pin 22 XUART2 RX
5 44-pin Header pin 23 CAN_TXD/XUART3 TX
6 44-pin Header pin 24 CAN_RXD/XUART3 RX
7 44-pin Header pin 25 XUART4 TX
8 44-pin Header pin 26 XUART4 RX
9 44-pin Header pin 27 XUART1 TXEN
22 44-pin Header pin 28 XUART2 TXEN
10 44-pin Header pin 29 XUART5 TXEN
11 44-pin Header pin 30 XUART6 TXEN
12 44-pin Header pin 31 XUART5 TX
13 44-pin Header pin 32 XUART5 RX
14 44-pin Header pin 33 XUART6 TX
21 44-pin Header pin 34 XUART6 RX
15 44-pin Header pin 35 XUART7 TX (TS-752 Relay 0)
16 44-pin Header pin 36 XUART7 RX
17 44-pin Header pin 37 TS-752 Relay 1
18 44-pin Header pin 38
19 44-pin Header pin 39 TS-752 Relay 2
24 44-pin Header pin 40
31 26-pin Header pin 1
43 26-pin Header pin 2
32 26-pin Header pin 3
44 26-pin Header pin 4
33 26-pin Header pin 5
45 26-pin Header pin 6
34 26-pin Header pin 7
46 26-pin Header pin 8
35 26-pin Header pin 9
47 26-pin Header pin 10
36 26-pin Header pin 11
48 26-pin Header pin 12
37 26-pin Header pin 13
49 26-pin Header pin 14
38 26-pin Header pin 15
50 26-pin Header pin 16
39 26-pin Header pin 17
51 26-pin Header pin 18
40 26-pin Header pin 19
52 26-pin Header pin 20
41 26-pin Header pin 21
53 26-pin Header pin 22
54 26-pin Header pin 54
42 26-pin Header pin 25

6.13.1 EVGPIO

This board features the EVGPIO core (Event Driven GPIO) which allows a low bandwidth mechanism to monitor all FPGA DIO on a shared interrupt. All DIO are accessed atomically through two registers. The data register is used to read dio state changes, set output values, and data direction. The mask register is used to set which DIO will trigger the IRQ and provide state changes to the data register. We provide "evgpioctl" which can be used to access these DIO:

# evgpioctl --help
Usage: evgpioctl [OPTIONS] ...
EVGPIO utility

  -i, --getin  <dio>    Returns the input value of a DIO
  -s, --setout <dio>    Sets a DIO output value high
  -l, --clrout <dio>    Sets a DIO output value low
  -o, --ddrout <dio>    Set DIO to an output
  -d, --ddrin <dio>     Set DIO to an input
  -m, --setmask <dio>   Mask out a DIO so it does not provide input
                        event changes and trigger the shared IRQ
  -c, --clrmask <dio>   Clear the mask from a DIO so it provides input
                        event changes and trigger the shared IRQ
  -w, --watch           Prints csv output when any unmasked DIO changes
                        <dio>,<1=high,0=low>

This provides a simple interface that can be used in scripts, or wrapped for higher level software access.

# Set DIO 31 to a high output
evgpioctl --ddrout 31 --setout 31
 
# Set DIO 31 to a low output
evgpioctl --setout 31
 
# Read the value of DIO 30
evgpioctl --ddrin 30 --getin 30
 
# The input return values are parsable and can be used easily in scripts:
eval $(evgpioctl --getin 30)
echo $dio30

The sources for this utility are available here:

You can also manipulate the EVGPIO data and mask registers directly in your application. Setting a pin direction, output value, and reading input changes are accessed through the EVPGIO data register.

EVGPIO Data Register
Bits Description
15:9 Reserved (Write 0)
8 Valid Read Data [1]
7 Value
6 Data/Data Direction [2]
5:0 DIO number
  1. When writing, write 0. During a read this indicates if this read includes new valid changes. After an interrupt this register should be read until it returns 0.
  2. When bit6 = 0, data direction of DIO is set to value (bit7 1 = output, 0 = input). When bit6 = 1, the data output of DIO is set to value

The second register is the IRQ mask. This is used to set which DIO will update the data register and trigger an IRQ on change.

EVGPIO Mask Register
Bits Description
15:8 Reserved (Write 0)
7 Mask Set (0 = irq enabled, 1 = irq disabled)
6 Reserved (Write 0)
5:0 DIO number

6.14 USB

6.14.1 USB OTG

This board features USB OTG which is wired to support a second USB host port (that's the top one). The Marvell OTG driver has a known issue where it does not properly support hotplugged USB devices. If a device is plugged in during boot it will work, but if it is plugged in after kernel initialization the following command must be used in order to set the port in to host mode.:

echo 1 > /proc/driver/otg

6.14.2 USB Host

The USB host port is a standard USB 2.0 at 480Mbps. The Linux kernel provides most of the USB support, and some devices may require a kernel recompile. Common devices such as keyboards, mice, wifi, and ethernet should mostly work out of the box.

The libusb project can also be used to communicate directly with USB peripherals from userspace.

6.15 TWI

I2C data is on HD2 pin 18, and I2C clock is on HD2 pin 17. This functionality is used to read and set the RTC on the TS-7700 in tshwctl.c (ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/ts-4710-linux/sources/tshwctl.c).

6.16 SPI

The TS-7700 SPI functionality must presently be achieved through bit-banged GPIO. There is an SPI core included with the Opencore that can be used to implement a more TS-4710-style SPI interface.

6.17 FPGA

The TS-7700 FPGA is connected to the CPU by a static memory controller, and as a result the FPGA can provide registers in the CPU memory space.

While most common functionality is accessed through layers of software that are already written, some features may require talking directly to the FPGA. Access to the FPGA is done through either the 8-bit or 16-bit memory regions. Code should access 16-bit or 8-bit depending on the access designed for the specific hardware core. For example, the CAN core is 8 bit, the 8 bit MUXBUS space is 8 bit. To access hardware cores in the FPGA, add the offset in the table below to the base address.

Bit Width Base Address
16 0x80000000
8 0x81000000
Offset Usage Bit Width
0x0000 16KB blockram access (for XUART buffer) 16
0x4000 Syscon registers 16
0x4400 ADC registers (for off-board ADC) 16
0x4800 SPI interface (not implemented) 16
0x4C00 CAN controller 8
0x4D00 2nd CAN controller 8
0x5000 Touchscreen registers 16
0x5400 XUART IO registers 16
0x8000 32KB MUXBUS space 16/8

6.18 FPGA Bitstreams

There are some reconfigured TS-7700 FPGA bitstreams are located in the bitstreams section of the pxa16x family ftp directory. These are provided for convenience, please take note of the target model in the filename, only files designated TS-7700 will work on the TS-7700. If a desired configuration is not present there, you can create your desired configuration using the opencore instructions below, or contact our sales team (sales@embeddedarm.com) to discuss commissioning the creation of a customized FPGA for your purposes.

6.18.1 FPGA Programming

Note: We do not provide support for the opencores under our free support, however we do offer custom FPGA programming services. If interested please contact us.

We provide an open version of the Verilog project that contains the functionality of the default FPGA bitstream. The FPGA bitstream is built using Lattice Diamond which is free and runs under Windows or Linux (Redhat). This allows you to modify the verilog and create a jedec file with your custom logic. The jedec is converted to a vme file which is loaded from the SD card and used to reprogram the SRAM of the FPGA on every startup. This requires approximately a second during startup to reprogram, but allows you to recover by removing the bitstream file from the SD card in the case of a faulty bitstream.

The opencore FPGA sources are available here. Custom logic can be built by implementing a wishbone compatible core, or by extending the cores we already have connected.

The ts7700_top.v file is used to connect all of the wishbone cores, and map any DIO. The syscon.v is used for most common system configuration registers. As a simple example these next steps will modify the custom load register located at 0x2a in the syscon.v.

Open up the Lattice diamond tools and open the .ldf file to open the project. On the bottom left there are 3 tabs to control the left panel (Files, Process, and Hierarchy). Go to Files, and double click syscon.v. Around line 40 is:

localparam [3:0] revision = 4'h2;
localparam [15:0] custom = 16'h0000;

You can edit the custom value to:

localparam [15:0] custom = 16'h0001;

The custom register is not used by any default software and is a safe register to use for a custom version number. The default bitstream will always use 0.

Save the file and go to the "Process" tab. Double click "Place & Route Trace" to begin synthesizing the bitstream. This will take approximately 5-10 minutes. Once this is finished open the "Reports" tab from the top open file list. Under "Analysis Reports" click on "Place & Route Trace". This is used to verify timing of your build. Under "Preference Summary" make sure none of the clock domains list errors. If timing is not met this will cause seemingly random issues with the bitstream which will usually present first as SD corruption.

Once the timing has been verified, double click "JECEC File" on the "Process" tab to build the jed file. Once this is finished there will be a "ts7700_opencore.jed" in the project folder. In order for the board to use this it must be converted to a vme file. This is generated using "jed2vme":

jed2vme ts7700_opencore.jed | bzip2 > ts7700-fpga.vme.bz2
WARNING: Generating a VME using other Lattice's tools can generate a flash bitstream which will render your board unbootable.

Once this is built it should be placed on the second partition of the SD card as "/ts/ts<model>-fpga.vme.bz2" This should match your macrocontroller's model such as "/ts/ts7700-fpga.vme.bz2".

Once it is loaded on the SD card the board can be booted normally. The green and red LEDs will shut off during programming, and then turn back on after the bitstream has been reloaded. Commands should not be run during reload since issuing a bus cycle during programming can interfere with timing and cause the reload to fail. Once it has reloaded you can use devmem to verify the register has changed:

devmem 0x8000402a 16

On the default bitstream this should return "0x0000", or "0x0001" if modified as suggested above.

6.19 Syscon

The registers listed below are all 16 bit registers and must be accessed with 16 bit reads and writes. This register block appears at base address 0x80004000. For example, to identify the TS-4710:

devmem 0x80004000 16

This will return 0x7700 to read back the model ID.

Many of the syscon options can be manipulated using tshwctl.

 Usage: tshwctl [OPTION] ...
 Technologic Systems TS-471x / TS-77XX FPGA manipulation.
 
 General options:
   -g, --getmac            Display ethernet MAC address
   -s, --setmac=MAC        Set ethernet MAC address
   -R, --reboot            Reboot the board
   -t, --getrtc            Get system time from RTC time/date
   -S, --setrtc            Set RTC time/date from system time
   -F, --rtcinfo           Print RTC temperature, poweron/off time, etc
   -v, --nvram             Get/Set RTC NVRAM
   -i, --info              Display board FPGA info
   -e, --greenledon        Turn green LED on
   -b, --greenledoff       Turn green LED off
   -c, --redledon          Turn red LED on
   -d, --redledoff         Turn red LED off
   -D, --setdio=<pin>      Sets DDR and asserts a specified pin
   -O, --clrdio=<pin>      Sets DDR and deasserts a specified pin
   -G, --getdio=<pin>      Sets DDR and gets DIO pin input value
   -x, --random            Get 16-bit hardware random number
   -W, --watchdog          Daemonize and set up /dev/watchdog
   -n, --setrng            Seed the kernel random number generator
   -X, --resetswitchon     Enable reset switch
   -Y, --resetswitchoff    Disable reset switch
   -l, --loadfpga=FILE     Load FPGA bitstream from FILE
   -q, --cputemp           Display the CPU die temperature
   -U, --removejp=JP       Remove soft jumper numbered JP (1-8)
   -J, --setjp=JP          Set soft jumper numbered JP (1-8)
   -k, --txenon=XUART(s)   Enables the TX Enable for an XUART
   -K, --txenoff=XUART(s)  Disables a specified TX Enable
   -N, --canon=PORT(s)     Enables a CAN port
   -f, --canoff=PORT(s)    Disables a CAN port
   -h, --help              This help
   -j, --bbclkon           Enables a 12.5MHz clock on DIO 3
   -H, --bbclkoff          Disables the 12.5MHz clock
   -E, --bbclk2on          Enables a 25MHz clock on DIO 34
   -I, --bbclk2off         Disables the 25MHz clock
Offset Bits Usage
0x00 15:0 Model ID: Reads 0x7700
0x02 15 Reset switch enable (Use DIO 29 input)
14 Reserved (write 0)
13 Enable UART4 TXEN (override DIO 14)
12 Enable UART0 TXEN (override DIO 12)
11 Enable 12.5MHz base board clock (override DIO 3)
10 Enable SPI (override DIO 17-20)
9 Reserved
8 Enable CAN (override DIO 5,6)
7:6 Scratch Register
5 Mode2
4 Mode1
3:0 FPGA revision
0x04 15:0 Reserved
0x06 15:0 Watchdog feed register
0x08 15:0 Free running 1MHz counter LSB
0x0a 15:0 Free running 1MHz counter MSB
0x0c 15:0 Hardware RNG LSB
0x0e 15:0 Hardware RNG MSB
0x10 15:0 EVGPIO Data
0x12 15:13 Reserved
12 Red LED (1 = on)
11 Green LED (1 = on)
10:0 Reserved
0x14 15:0 EVGPIO Mask
0x16 15 Enable UART2 TXEN (override DIO 10)
14 Enable UART1 TXEN (override DIO 9)
13 Enable UART5 TXEN (override DIO 7)
12 Enable UART3 TXEN (override DIO 13)
11:0 Reserved
0x18 15:0 Reserved
0x1a 15:0 Reserved
0x1c 15:0 Reserved
0x1e 15:0 Reserved
0x20 15 Reserved
14:0 DIO DIO 14:0 input data
0x22 15:11 Reserved
10:6 DIO DIO 26:22 input data
5:0 DIO DIO 20:15 input data
0x24 15:0 DIO DIO 42:27 input data
0x26 15:12 Reserved
11:0 DIO DIO 59:48 input data
0x28 15:4 Reserved
3:0 FPGA TAG memory access [1]
0x2a 15:0 Custom load ID register [2]
0x2c 15:7 Reserved
6 EVGPIO
5 Offboard IRQ 7
4 Offboard IRQ 6
3 Offboard IRQ 5
2 CAN2 IRQ
1 CAN IRQ
0 XUART IRQ
0x2e 15:6 Reserved
5 Offboard IRQ 7 mask (1 disabled, 0 on) [3]
4 Offboard IRQ 6 mask (1 disabled, 0 on) [3]
3 Offboard IRQ 5 mask (1 disabled, 0 on)[3]
2 CAN2 IRQ mask (1 disabled, 0 on)[3]
1 CAN IRQ mask (1 disabled, 0 on)[3]
0 XUART IRQ mask (1 disabled, 0 on)[3]
  1. TAG memory stores persistent data on the FPGA such a the MAC address, CPU settings, and the born on date. Software using this data should instead use tshwctl rather than accessing this register manually.
  2. Reads back 0 on default load. Used to identify customized bitstreams
  3. 3.0 3.1 3.2 3.3 3.4 3.5 The IRQ masks are handled automatically by the kernel after an IRQ is requested. Under most circumstances these registers should not be manipulated.

6.20 Watchdog

By default there is a /dev/watchdog with the tshwctl daemon running at the highest possible priority to feed the watchdog. This is a pipe that is created in userspace, so for many applications this may provide enough functionality for the watchdog by verifying that userspace is still executing applications. If you would like to have the watchdog functionality more tightly integrated with your application you can specify various feed options.

At the lower level there are 3 valid watchdog feed values that are written to the watchdog register in the #Syscon:

Value Result
0 feed watchdog for another .338s
1 feed watchdog for another 2.706s
2 feed watchdog for another 10.824s
3 disable watchdog

The watchdog is armed by default for 10s for the operating system to take over, after which the startup scripts autofeed the watchdog with:

echo a2 > /dev/watchdog

The /dev/watchdog fifo accepts 3 types of commands:

Value Function
f<3 digits> One time feed for a specified amount of time which uses the 3 digit number / 10. For example, "f456" would feed for 45.6 seconds.
"0", "1", "2", "3" One time feed with the value in the above table.
a<num 0-3> This value autofeeds with the value in the above table.

Most applications should use the f<3 digits> option to more tightly integrate this to their application. For example:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
 
void do_some_work(int data) {
	/* The contract for sleep(int n) is that it will sleep for at least n
	 * seconds, but not less.  If other kernel threads or processes require
	 * more time sleep can take longer, but when your process has a high
	 * priority this is usually measured in millseconds */
	sleep(5);
}
 
int read_some_io() {
	/* If this function (or do_some_work) misbehave and stall thee watchdog 
         * will not be fed in the main loop and cause a reboot.  You can test 
         * this by uncommenting the next line to force an infinite loop */
	// while (1) {}
	return 42;
}
 
int main(int argc, char **argv)
{
	int wdfd;
	/* In languages other than C/C++ this is still essentially the same, but
	 * make sure you are opening the watchdog file synchronously so the writes
	 * happen immediately.  Many languages will buffer writes together to make 
	 * them more efficient, but the watchdog needs the writes to be timed 
	 * precisely */
	wdfd = open("/dev/watchdog", O_SYNC|O_RDWR);
 
	while (1) {
		int data;
		/* This loop is expected to take about 5-6 seconds, but to allow some
		 * headroom for other applications, I will feed the watchdog for 10s. */
		write(wdfd, "f100", 4);
 
		data = read_some_io();
		do_some_work(data);
	}
}

6.21 XUARTS

The XUARTs are ttl serial ports implemented in the FPGA. These communicate with the userspace driver xuartctl. Each XUART core in the FPGA can handle up to 8 XUARTs, though the default TS-4710 FPGA contains 6. The XUART serial ports have a single shared 4kByte receive FIFO which makes real time interrupt latency response less of a concern and in actual implementation, the serial ports are simply polled at 100Hz and don't even use an IRQ. Even with all 8 ports running at 230400 baud, it is not possible to overflow the receive FIFO in 1/100th of a second. The "xuartctl --server" daemon is started by default in the init scripts which sets up listening TCP/IP ports for all XUART channels on ports 7350-7357. An application may simply connect to these ports via localhost (or via the network) and use the serial ports as if they were network services.

The typical method for accessing xuarts is using the pts layer. For example:

eval $(xuartctl --server --port 3 --mode=8n1 --speed 9600 2>&1); ln -s $ttyname /dev/ttyxuart3

This will set up XUART port 3 to 9600 baud, 8n1, and symlink it to /dev/ttyxuart3. In your application you can open the /dev/ttyxuart3 and for most part you can access this just like any other uart. When using the PTS layer, there are several operations that are not supported. The mode and baud rate must be set up with xuartctl, and cannot be programatically changed with the standard ioctl.

The XUARTs can be managed with xuartctl. See the xuartctl page for more details on programming with XUARTs. See either of these links for more information on using serial ports in Linux:

All COM Ports on the TS-7700 are TTL. Typically the carrier board will contain any transceivers to bring this to RS232, RS485, etc.

COM Port mapping
XUART Port TX RX TX Enable [1]
0 44-pin Header pin 5 44-pin Header pin 6 N/A
1 44-pin Header pin 19 44-pin Header pin 20 44-pin Header pin 27
2 44-pin Header pin 21 44-pin Header pin 22 44-pin Header pin 28
3 44-pin Header pin 23 44-pin Header pin 24 N/A
4 44-pin Header pin 25 44-pin Header pin 26 N/A
5 44-pin Header pin 31 44-pin Header pin 32 44-pin Header pin 29
6 44-pin Header pin 33 44-pin Header pin 34 44-pin Header pin 30
7 44-pin Header pin 35 44-pin Header pin 36
  1. The TX Enable pin is used to toggle an RS485 tranciever on the baseboard from TX to RX. This functionality is not enabled by default, but can be turned on in the syscon 0x02 and 0x16
Note: XUART ports 0-6 are included in the default bitstream. See the #FPGA Bitstreams section for available bitstreams for other configurations.

6.22 CAN

The TS-7700 is capable of CAN protocol operations, however the downstream developer must provide the appropriate CAN transceiver for proper operation. The CAN transmit data pin is at 44 pin header pin 23, and the CAN receive data pin is at 44 pin header pin 24.

The CAN controller contained in the FPGA is compatible with the register interface for the SJA1000. This is implemented using either SocketCAN, or tsctl. Typically new development is done using SocketCAN, but tsctl provides compatibility on older products which used CAN before Socketcan was created. The tsctl API provides compatibility with the older canctl API, or tsctl's API.

Before proceeding with the examples, see the Kernel's CAN documentation here.

This board comes preinstalled with can-utils which can be used to communicate over a CAN network without writing any code. The candump utility can be used to dump all data on the network

## First, set the baud rate and bring up the device:
ip link set can0 type can bitrate 250000
ip link set can0 up
 
## Dump data & errors:
candump -cae can0,0:0,#FFFFFFFF &
 
## Send the packet with:
#can_id = 0x7df
#data 0 = 0x3
#data 1 = 0x1
#data 2 = 0x0c
cansend can0 7Df#03010c

This example packet is designed to work with the Ozen Elektronik myOByDic 1610 ECU simulator to read the RPM speed. This device will return data from candump with:

 can0  7DF  [3] 03 01 0C                  '...'
 can0  7E8  [8] 04 41 0C 2F C0 00 00 00   '.A./....'
 can0  7E9  [8] 04 41 0C 2F 80 00 00 00   '.A./....'

In this case, 0x2f is the current RPM value. This shows a simple way you can prove out the communication before moving to another language, but this next example sends the same packet and parses the same response in C:

#include <stdio.h>
#include <pthread.h>
#include <net/if.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <linux/can.h>
#include <linux/can/raw.h>
 
int main(void)
{
	int s;
	int nbytes;
	struct sockaddr_can addr;
	struct can_frame frame;
	struct ifreq ifr;
	struct iovec iov;
	struct msghdr msg;
	char ctrlmsg[CMSG_SPACE(sizeof(struct timeval)) + CMSG_SPACE(sizeof(__u32))];
	char *ifname = "can0";
 
	if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
		perror("Error while opening socket");
		return -1;
	}
 
	strcpy(ifr.ifr_name, ifname);
	ioctl(s, SIOCGIFINDEX, &ifr);
	addr.can_family  = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;
 
	if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		perror("socket");
		return -2;
	}
 
 	/* For the ozen myOByDic 1610 this requests the RPM guage */
	frame.can_id  = 0x7df;
	frame.can_dlc = 3;
	frame.data[0] = 3;
	frame.data[1] = 1;
	frame.data[2] = 0x0c;
 
	nbytes = write(s, &frame, sizeof(struct can_frame));
	if(nbytes < 0) {
		perror("write");
		return -3;
	}
 
	iov.iov_base = &frame;
	msg.msg_name = &addr;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = &ctrlmsg;
	iov.iov_len = sizeof(frame);
	msg.msg_namelen = sizeof(struct sockaddr_can);
	msg.msg_controllen = sizeof(ctrlmsg);  
	msg.msg_flags = 0;
 
	do {
		nbytes = recvmsg(s, &msg, 0);
		if (nbytes < 0) {
			perror("read");
			return -4;
		}
 
		if (nbytes < (int)sizeof(struct can_frame)) {
			fprintf(stderr, "read: incomplete CAN frame\n");
		}
	} while(nbytes == 0);
 
	if(frame.data[0] == 0x4)
		printf("RPM at %d of 255\n", frame.data[3]);
 
	return 0;
}

Other languages have bindings to access CAN such as Python using C-types, Java using JNI.

7 External Interfaces

7.1 44 Pin Header

The 44 pin header uses 0.1" pitch pins. The mating connector CN-PC104-40PIN-F is available on the TS-7700 order page.

Pin Name
1 JTAG_DOUT [1]
2 JTAG_TMS [1]
3 JTAG_CLK [1]
4 JTAG_DIN [1]
5 DIO 30/XUART 0 TX
6 DIO 27/XUART 0 RX
7 Console TXD
8 Console RXD
9 DIO 29
10 3.3V
11 DIO 28
12 DIO 26
13 DIO 00
14 DIO 25
15 5V
16 Ground
17 I2C_CLK
18 I2C_DAT
19 DIO 01/XUART 1 TX
20 DIO 02/XUART 1 RX
21 DIO 03/XUART 2 TX
22 DIO 04/XUART 2 RX
23 DIO 05/XUART 3 TX/CAN TX
24 DIO 06/XUART 3 RX/CAN RX
25 DIO 07/XUART 4 TX
26 DIO 08/XUART 4 RX
27 DIO 09/XUART 1 TXEN
28 DIO 22/XUART 2 TXEN
29 DIO 10/XUART 5 TXEN
30 DIO 11/XUART 6 TXEN
31 DIO 12/XUART 5 TX
32 DIO 13/XUART 5 RX
33 DIO 14/XUART 6 TX
34 DIO 21/XUART 6 RX
35 DIO 15/XUART 7 TX
36 DIO 16/XUART 7 RX
37 DIO 17
38 DIO 18
39 DIO 19
40 DIO 24
41 POE_RX
42 POE_78
43 POE_45
44 POE_TX
TS-7700-44pin.png
  1. 1.0 1.1 1.2 1.3 These pins are used for factory programming only. There is a software mechanism for soft reloading the FPGA documented here.

7.2 26 Pin Header

The 26 pin header uses 0.1" pitch pins similar to that used on the 44-pin header.

Pin Name
1 DIO 31
2 DIO 43
3 DIO 32
4 DIO 44
5 DIO 33
6 DIO 45
7 DIO 34
8 DIO 46
9 DIO 35
10 DIO 47
11 DIO 36
12 DIO 48
13 DIO 37
14 DIO 49
15 DIO 38
16 DIO 50
17 DIO 39
18 DIO 51
19 DIO 40
20 DIO 52
21 DIO 41
22 DIO 53
23 GND
24 DIO 54
25 DIO 42
26 MFP_118
TS-7700-26pin.png

8 Revisions and Changes

8.1 TS-7700 PCB Revisions

TS-7700 PCB Changelog

8.2 FPGA Changelog

You can check your revision with "tshwctl -i".

Revision Description
0 Initial revision
1 Move DIO reset switch to the correct DIO
2 Enable IRQs for EVGPIO
3 Add register at 0x34 for dio inputs 43-40
4 Fix watchdog
5 Add pullups
6 XUART Blockram corruption fix

8.3 Software Images

8.3.1 2.6 Debian Changelog

This is the changelog for the software image which is shared from the TS-4710, TS-4712, TS-4720, TS-4740, TS-7700, and the TS-7250-V2.

2.6.34 Based Image
Image File Changelog Known Issues
2gbsd-471x-20130221.dd.bz2
  • Initial release
2gbsd-471x-20130221.dd.bz2
  • Updates to Debian Wheezy
  • TS specific utilities exported to Debian
    • Including tshwctl, xuartctl, sdctl
    • Includes busybox for vconfig and devmem
  • Includes more baseboard support
    • TX EN is automatically enabled on known baseboards
  • LCD support
    • TS-TPC-8900 support added
  • Touchscreen supported added
    • TS-TPC-8900 support added
  • Initial driver for SocketCAN support added
  • ts4700ctl revised to tshwctl for consistency among other products
    • tshwctl adds simple support for FPGA DIO with --getdio --setdio --clrdio options
  • tsrf2cf support added
  • ts4700_isa16550 support added for pc104 peripherals like TS-SER4 or TS-MULTI104
  • smsc95xx ethernet support added
  • Icewm removed.
  • fullscreen-webkit added
    • Command is ./fullscreen-webkit <url> to run a full screen browser
    • Replaces icewm as default desktop
  • Fixed FPGA Reload support with release of opencore
  • Added new soft jumpers.
    • JP2 & JP3 are baseboard specific.
      • Controls support such as ethernet switch config
    • JP4 enables read only mode
    • JP5 disables network autoconfig from initramfs. This can still be set from Debian
  • CAN Controller currently inaccesible
  • Second SD card not supported in sdctl
  • smsc95xx periodically does not set MAC address correctly (already fixed in next image)
  • mdnsd is not correctly started
  • Debian Wheezy boot speed not yet optimized
2gbsd-471x-20130515.dd.bz2
  • Updated kernel. See git for the full changelog.
  • TS-8700 support
  • TS-8280 support
  • Added SocketCAN support and example userspace utilities (cansend, candump, etc)
  • Fixed FPGA reload to be reliable
  • mdnsd started correctly
  • fixed JP1 causing serial console to break
  • USB OTG not yet supported
  • Second SD card not supported in sdctl
2gbsd-471x-20130522.dd.bz2
  • Second SD card not supported in sdctl
  • No audio support
  • PCIe breaks kernel register interface to FPGA
2gbsd-471x-20130531.dd.bz2
  • Disabled PCIe pending fixes for SMC FPGA interface
  • Added TS-8150 support.
  • Added TS-8920 support.
  • Marvell switch chip drops fragmented packets (TS-4712 only)
    • Set MTU to 1501 on eth0 as a workaround.
  • PCIe disabled pending fix.
  • No Audio support
  • Second SD card not supported in sdctl
2gbsd-471x-20130806.dd.bz2
  • Implemented default splash screen, see /ts/splash
  • Audio support (sgtl5000, wm8750, sii9022)
    • Audio startup noise added, see /ts/startup.wav
  • AutoStart X11 in the initramfs
    • Configure started apps with /ts/initramfs-xinit
  • Default x session changed to icewm-lite for faster boot time
  • ifplugd is no longer run when jp1 is set due to race condition
    • Configure the network in Debian once you are booting there
  • check-usb-update implemented
    • Plug in a USB drive with 1 partition containing /tsinit which will automatically run. Used primarily for production.
  • sdctl updated to support dual SD
    • Start "nbd-client 127.0.0.1 7501 /dev/nbd1" to access second card
    • Doublestore fixes added
  • PCIe fixes included, PCIe enabled by default on suported macros with pxa168
  • compat-drivers included
    • Includes common wireless drivers
  • Marvell Switch Chip fixes added
  • Wheezy updated to latest in repository
  • Added support for both onboard/offboard switches
    • Used in cases such as TS-4720 + TS-8700
  • Added initial TS-4740 support
    • Uses Xilinx FPGA for reload, added spiflash tools
      • spiflashctl added
      • bin2coe added
      • new tshwctl commands
    • eMMC support
  • TS-4720 support added
  • Generates random MAC address if none is programmed.
    • Should only be used for production
  • Added Kexec support
    • Allows support for NFS/http/ftp/etc kernel and rootfs loading
  • Xuartctl defaults to 100hz instead of IRQ driven
    • IRQ behavior is specifically tuned for best latency, but requires high CPU
  • Debian Wheezy configured to continue booting in the event of a fsck error unless it is completely unrepairable
  • ts-sendsigs-omit script fixes so multiple nbd-clients or xuartctls are not killed early in shutdown
  • Root filesystem is now always /dev/rootfs rather than /dev/nbd0p2
    • TS-4740/TS-4720 can boot to /dev/nbd1p2, so the actual rootfs is automatically symlinked to /dev/rootfs
  • Unionfs crashes with a kernel oops when JP4 is enabled.
2gbsd-471x-20130815.dd.bz2
  • TS-8700 switch reset race condition fixed
  • Fixed FPGA reload for TS-4712/20
  • tshwctl minor fixes
    • ethinfo overflow fixed
    • tagmem is now only written if value actually changed with setjp/removejp/setmac
  • Unionfs crashes with a kernel oops when JP4 is enabled.
4gbsd-471x-20131004.dd.bz2
  • Switched to EXT3 by default
    • Doublestore users should disable journaling to reduce writes vs old ext2
  • Image sized for already shipping 4GB MicroSD cards
  • TS-8400 support completed
  • ifpulgd now starts on switch interfaces correctly
  • /ts/config file create to allow for further configuration of the initramfs. See this file for more information.
  • Soft Jumpers 2,3,4,5 have been removed and are implemented in the /ts/config file which allows more than 8 settings
    • The config file allows enabling and configuring utilities like ifplugd, xuartctl, mdnsd, and more.
    • Read only jumper 4 removed due to bugs with unionfs.
    • Behavior of JP1 and JP8 are not changed
    • JP7 added to minimize initramfs initialization for manual boot.
  • Reloading the TS-4712 and TS-4720 now resets the model number correctly after a soft reload
  • X11 in Debian started with correct HOME variable so a valid .Xauthority file is created
    • This allows DISPLAY=:0 to work, and fixes some dns resolution issues
  • /etc/init.d/motd updated to include additional information for debugging
  • tshwctl updated
    • TS-7700 EVGPIO (getdio/setdio/clrdio) added
    • --getdio is fixed which would previously change the direction for all DIO in the first register when used (DIO 0-15)
    • --rtcinfo implemented which provides more status information on the RTC
  • Kernel updated
    • Included commonly requested features in default config
        • Bluetooth, ipv6, netfilter (iptables), bridging, and more device support.
    • wm8750 support added for TS-8400
    • sgtl5000 supports an option to disable standby to prevent audible pops
    • See git for the full changelog.
  • Unionfs support disabled
4gbsd-471x-20140306.dd.bz2
  • Fixed rare reboot lockup
  • Added Marvell switch chip errata fix for 10Mb/s ethernet
  • Added minimum packet size for TS-4712/TS-4720 to work around corrupt FCS from switch chip
  • Added TS-4720 support
  • Added TS-4740 support
4gbsd-471x-20140430.dd.bz2
  • Initial TS-7250-V2 support
  • Initramfs now prints boot device on TS-7250-V2 and TS-4720
  • Initramfs zeroconf/ipv4ll IP is now only used as a fallback if dhcp fails
    • Fixes mdns resolving zeroconf to a system with no route to it
  • Updated tshwctl with rtcinfo, and 7250v2 dio/adc support
  • Updated sdctl for 7250v2
  • Debian updated with empty killprocs script
    • Normal killprocs ignores debians list of processes not to kill which kills the nbd-client
    • Empty killprocs will succeed these updates, but not restart processes
  • USB WiFi modules not compiled with the kernel. USB WiFi will not work, and requires a kernel compile and rebuilding the modules as outlined in the Compile the Kernel section.
* 4gbsd-471x-20140724.dd.bz2
  • Fixed TS-7250-V2 ADCs
  • Fixed 16550 driver for 7250v2
  • Fixed USB WIFI module regression
  • eMMC on 7250v2 is now converted to SLC.
  • Enabled /dev/i2c interface in the default kernel
  • Added new CFG options
    • CFG_MUTE_CPU_UART=1 will completely disable output on /dev/ttyS0 after the bootrom messages
    • CFG_XUART_CONSOLE_EN=<0-7> will use an XUART for console instead of /dev/ttyS0
* EVGPIO IRQ #2 requires a build from the latest kernel sources
* 4gbsd-471x-20140924.dd.bz2
  • Using older images if multiple copies of tshwctl are run at the same time which access tagmem, this can corrupt the mac address and the soft jumpers. In some cases this could also break the touchscreen loading random data as calibration. This new tshwctl includes locking that will prevent multiple copies from accessing tagmem simultaneously.
  • Removed udev rule that allocates eth# to a mac address
* 4gbsd-471x-20141013.dd.bz2
  • Switched sdctl to using Unix Domain Sockets instead of localhost tcp.
    • This gets around a rare bug that would cause the kernel to drop packets on localhost under heavy congestion.
    • This changes only involves a new kernel/initramfs and does not impact the debian filesystem.
  • Fixed touchscreen regression
    • On older images the calibration was slightly off in the bottom right corner of the TS-TPC-8390
    • Fixed in ts_lcd.c in the kernel
  • Updated Debian for shellshock vulnerability.
    • Older images can just "apt-get update && apt-get dist-upgrade"
  • Fixed booting to lun1
  • Updated touchscreen calibration for all TPCs
  • Added SLC eMMC image for TS-4720
  • Fixed tshwctl tagmem regression
  • Fixed I210 support (4740)
  • CAN fixed for TS-7250-V2
  • Full size SD now supported on TS-7250-V2
    • Make a single read to scan the device "dd if=/dev/nbd2 bs=512 count=1 of=/dev/null", and then read /dev/nbd2p1 for the first partition.
  • Updated to latest Debian Wheezy
  • Fixed initramfs so DIO9 does not reset the carrier boards without a push switch.

8.3.2 3.14 Debian Changelog

3.14 Based Image
Image File Changelog Known Issues
* 4gbsd-471x-3x-20140828.dd.bz2
  • This is a beta image
  • New 3.14.16 kernel
  • Fixed ts_lcd which would incorrectly attempt to load calibration from tagmem which is no longer used.
  • Fixed udev bug which broke keyboards & mice on x11
    • Fixed with this on older systems:
    • echo "SUBSYSTEM==\"input\", ENV{ID_INPUT}==\"\", IMPORT{builtin}=\"input_id\"" >> /etc/udev/rules.d/50-udev-default.rules
  • USB OTG host does not work. The 1 CPU USB host still works.
  • PCIe, and intel I210 (TS-4740) support not yet functional.
  • Muxed IRQs (PC104, CAN, optionally XUART) currently do not work.
  • Switched sdctl to using Unix Domain Sockets instead of localhost tcp.
    • This gets around a rare bug that would cause the kernel to drop packets on localhost under heavy congestion.
    • This changes only involves a new kernel/initramfs and does not impact the debian filesystem.
  • Fixed touchscreen regression
    • On older images the calibration was slightly off in the bottom right corner of the TS-TPC-8390
    • Fixed in ts_lcd.c in the kernel
  • Updated Debian for shellshock vulnerability.
    • Older images can just "apt-get update && apt-get dist-upgrade"
  • No Audio
  • LCD still requires timing updates since vsync is off
  • USB OTG is not currently working
  • More common devices included in default kernel
  • USB OTG Fixed
  • tshwctl tagmem regression fixed
  • LCD timing still off, not noticable on 1GHz PXA168
  • No Audio
  • Fixed I210 support (4740)
  • CAN fixed for TS-7250-V2
  • Full size SD now supported on TS-7250-V2
    • Make a single read to scan the device "dd if=/dev/nbd2 bs=512 count=1 of=/dev/null", and then read /dev/nbd2p1 for the first partition.
  • Updated to latest Debian Wheezy
  • Fixed initramfs so DIO9 does not reset the carrier boards without a push switch.
  • Fixed LCD timing
  • Fixed Ethernet link unreliability without onboard switch
  • No Audio
  • No change in SD image, eMMC image reuploaded after noticing some missing files.

9 Further Resources

For further support you can go to our Developer Forums here. You can also contact us for more information.

We recommend reading our white papers if they are relevant to your project:

For learning more about Debian:

For Linux programming in general:

10 Product Notes

10.1 FCC Advisory

This equipment generates, uses, and can radiate radio frequency energy and if not installed and used properly (that is, in strict accordance with the manufacturer's instructions), may cause interference to radio and television reception. It has been type tested and found to comply with the limits for a Class A digital device in accordance with the specifications in Part 15 of FCC Rules, which are designed to provide reasonable protection against such interference when operated in a commercial environment. Operation of this equipment in a residential area is likely to cause interference, in which case the owner will be required to correct the interference at his own expense.

If this equipment does cause interference, which can be determined by turning the unit on and off, the user is encouraged to try the following measures to correct the interference:

Reorient the receiving antenna. Relocate the unit with respect to the receiver. Plug the unit into a different outlet so that the unit and receiver are on different branch circuits. Ensure that mounting screws and connector attachment screws are tightly secured. Ensure that good quality, shielded, and grounded cables are used for all data communications. If necessary, the user should consult the dealer or an experienced radio/television technician for additional suggestions. The following booklets prepared by the Federal Communications Commission (FCC) may also prove helpful:

How to Identify and Resolve Radio-TV Interference Problems (Stock No. 004-000-000345-4) Interface Handbook (Stock No. 004-000-004505-7) These booklets may be purchased from the Superintendent of Documents, U.S. Government Printing Office, Washington, DC 20402.

10.2 Limited Warranty

Technologic Systems warrants this product to be free of defects in material and workmanship for a period of one year from date of purchase. During this warranty period Technologic Systems will repair or replace the defective unit in accordance with the following process:

A copy of the original invoice must be included when returning the defective unit to Technologic Systems, Inc. This limited warranty does not cover damages resulting from lightning or other power surges, misuse, abuse, abnormal conditions of operation, or attempts to alter or modify the function of the product.

This warranty is limited to the repair or replacement of the defective unit. In no event shall Technologic Systems be liable or responsible for any loss or damages, including but not limited to any lost profits, incidental or consequential damages, loss of business, or anticipatory profits arising from the use or inability to use this product.

Repairs made after the expiration of the warranty period are subject to a repair charge and the cost of return shipping. Please, contact Technologic Systems to arrange for any repair service and to obtain repair charge information.