Difference between revisions of "TS-7680"

From Technologic Systems Manuals
(→‎DAC: Updated DAC section, added port locations)
Line 212: Line 212:
| 0
| 0
| [[#HD4_Pin_Header|HD4_5]] / [[#24_pos._Screw_terminal|B_9]]
| [[#HD4_Pin_Header|HD4_5]] / [[#24_pos._Screw_Terminal|B_9]]
| 1
| 1
| [[#HD4_Pin_Header|HD4_3]] / [[#24_pos._Screw_terminal|B_10]]
| [[#HD4_Pin_Header|HD4_3]] / [[#24_pos._Screw_Terminal|B_10]]
| 2
| 2
| [[#HD4_Pin_Header|HD4_1]] / [[#24_pos._Screw_terminal|B_11]]
| [[#HD4_Pin_Header|HD4_1]] / [[#24_pos._Screw_Terminal|B_11]]
| 3
| 3
| [[#HD4_Pin_Header|HD4_2]] / [[#24_pos._Screw_terminal|B_12]]
| [[#HD4_Pin_Header|HD4_2]] / [[#24_pos._Screw_Terminal|B_12]]

Revision as of 13:01, 30 April 2015

Note: The TS-7680 is currently in engineering sample phase. This means software and features are very likely to change as the TS-7680 is currently under heavy development. There may also be some features that are currently not implemented or not fully tested, please see the Revisions and changes for more information.

Known issues in current image:

  • U-Boot expects environment to always be on SD card
  • NAND is non functional due to an issue in UBIFS (in kernel 3.14, kernel 2.6 in image jan092015 works properly)
  • TS-7680 PCB Rev A is engineering sampling, some changes to the hardware will be made for PCB Rev B:
    • NAND will be replaced with eMMC
    • The Cortex-M0 microcontroller will be replaced with a SiLabs part. This is for USB->serial, the SiLabs drivers are more robust and are signed by Microsoft

Product Page
Mechanical Drawing
FTP Path
Freescale i.MX286
454MHz ARM9
CPU Datasheet
128MB or 256MB DDR2
16x DIO
External Interfaces
USB 2.0 1 host 1 OTG
1x 10/100 Ethernet
2x CAN ports
5x UARTs
Internal Storage Media
2x SD
Power Requirements
Operates around 1.1W
Runs as low as 0.6W

1 Overview

Note: This product has not been released as a standard product at this time. Information contained within this manual may be incorrect and is subject to change. Additionally, the software currently available for the TS-7680 has not been finalized and is subject to change at any time

The TS-7680 Rev. A has not been officially released as a standard product, it is currently in sampling phase. This is a small embedded board with a Freescale i.MX286 454Mhz ARM9 CPU with 128-256MB DDR2.

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 platforms run Debian and if there is no personal distribution preference this is what we recommend for ease of use.


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 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.

The TS-7680 has an input voltage range of 8v to 28v DC or 24v AC through the main power connector which offers screw terminals for secure wiring. The TS-7680 will require approximately 1.4W at idle. An ideal power supply for the TS-7680 will allow up to 5W to allow peripherals to be powered as well.

Once you have applied power you should look for console output. The first output is from the bootrom:


U-Boot 2014.07-ga44367e-dirty (Aug 25 2014 - 15:52:43)

CPU:   Freescale i.MX28 rev1.2 at 454 MHz
SPI:   ready
DRAM:  256 MiB
NAND:  2048 MiB
mxsmmc_init: initialising MMC
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   FEC0 [PRIME]
Hit any key to stop autoboot:  0
Booting from the SD card ...
135179 bytes read in 160 ms (824.2 KiB/s)
2429960 bytes read in 816 ms (2.8 MiB/s)
## Booting kernel from Legacy Image at 42000000 ...
   Image Name:   Linux-
   Created:      2014-09-04  18:16:53 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2429896 Bytes = 2.3 MiB
   Load Address: 40008000
   Entry Point:  40008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
/ts/fastboot file present.  Booting to initramfs instead
Booted from SD in 4.01s
Initramfs Web Interface: http://ts7680-4f1113.local
Total RAM: 256MB

The i.MX28 internal bootrom prints out the strings of letters to indicate various stages of its internal process. The TS-BOOTROM build date reflects when then imx-bootlets were built. When building a custom kernel from source this date will be changed and may not always reflect the kernel build date.

Note: In future releases of the TS-7680, the bootup process and output will change. U-Boot will continue to be used, however planned updates will change how the process works

2.2 Get a Console

2.2.1 Option 1: Telnet

If your system is configured with zeroconf support (Avahi, Bonjour, etc) you can simply connect with:

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

When the board first powers up it has two network interfaces. The first interface eth0 is configured to use IPv4LL, and eth0 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-7680s 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-7680 console [4f47a5]                      Telnet Remote Terminal local
+   eth0 IPv4 TS-7680 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 ts7680-4f47a5.local or ts7680-4f471a.local

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-7680 console [4f47a5]
10:27:57.423  Add     3  2 local.                    _telnet._tcp.             TS-7680 console [4f471a]

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

2.2.2 Option 2: Serial Console

The TS-7680 includes a USB device port, this uses a Cortex-M0 ARM microcontroller to create a CDC ACM serial device on a host PC. The serial console is provided through this port at 115200 baud, 8n1, with 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/ttyACM0 (this is what the USB device normally appears as), 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/ttyACM0

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

screen /dev/ttyACM0 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/ttyACM0' 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
The TS-7680 uses a CDC ACM USB to serial device that needs a corresponding driver in Windows. If the device is not detected correctly when its plugged in and Windows brings up the "Found new Hardware" wizard, download this zipfile, and point the wizard to the unpacked folder.

2.3 Initramfs

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


U-Boot 2014.07-ga44367e-dirty (Aug 25 2014 - 15:52:43)

CPU:   Freescale i.MX28 rev1.2 at 454 MHz
SPI:   ready
DRAM:  256 MiB
NAND:  2048 MiB
mxsmmc_init: initialising MMC
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   FEC0 [PRIME]
Hit any key to stop autoboot:  0
Booting from the SD card ...
135179 bytes read in 160 ms (824.2 KiB/s)
2429960 bytes read in 816 ms (2.8 MiB/s)
## Booting kernel from Legacy Image at 42000000 ...
   Image Name:   Linux-
   Created:      2014-09-04  18:16:53 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2429896 Bytes = 2.3 MiB
   Load Address: 40008000
   Entry Point:  40008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
/ts/fastboot file present.  Booting to initramfs instead
Booted from SD in 4.01s
Initramfs Web Interface: http://ts7680-4f1113.local
Total RAM: 256MB
Note: Your version dates may be different depending on ship date and the image used.

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 include 8 bits for common configuration option we call soft jumpers.

For most development you will want to boot to the Debian filesystem which can be reached by typing "exit" through the serial or telnet console, or by removing the file /ts/fastboot while in Debian to make the board automatically boot to Debian.

2.3.1 /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:


/path/to/your/application &

2.3.2 USB update mechanism, tsinit

For implementing a custom production process or applying updates in the field, this SBC is capable of detecting a USB device and running a script. The behavior of this process can be tuned, see the config information section below. There are a few requirements of this script: the USB device itself must be the first or only USB storage device connected, the script must be on the first partition of said USB device and be named "tsinit", and the script must be world executable. PATH is passed to the tsinit script, it is what the initramfs environment PATH is, if additional PATHs are required that can be added in the tsinit script. Standard in/out are the standard console port, this means either the serial debug port, or telnet. Please note that if using telnet, output may be missed as the scripts will not wait for a telnet connection to establish, it is recommended to use a real serial port because of this.

2.3.3 /mnt/root/ts/initramfs-xinit

Graphical applications should use /ts/initramfs-xinit. The xinit file is used to start up a window manager and any applications. The default initramfs-xinit starts a webbrowser viewing localhost:

# 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
    sleep 0.1

# 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

2.3.4 /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

## 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

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

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

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

## 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

## 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

## 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

## 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)

## 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
## Configure xuartctl to bind on localhost
## Default binds on all interfaces
#CFG_XUARGS="--bind --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

## 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.

### 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)

### 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)

3 U-Boot

U-Boot is used on this device as the bootloader to launch the full operating system. When the i.MX28 processor starts, it loads U-Boot from the on-board SPI flash. This allows creation of a custom boot image on either the SD, eMMC, NFS, or USB. U-Boot is a general purpose bootloader that is capable of booting into common Linux distributions, Android, Windows, or custom software OSes.

On a normal boot the output will be similar to this:


U-Boot 2014.10-g4d36657 (Dec 07 2016 - 12:19:27)

CPU:   Freescale i.MX28 rev1.2 at 454 MHz
BOOT:  SSP SPI #2, master, 3V3 NOR
I2C:   ready
SPI:   ready
DRAM:  256 MiB
SF: Detected IS25LQ016B with page size 256 Bytes, erase size 4 KiB, total 2 MiB

In:    serial
Out:   serial
Err:   serial
Net:   FEC0 [PRIME]
NO CHRG jumper is set, not waiting for SuperCaps to charge
Booting from the SD Card ...
** File not found /boot/boot.ub **
3336928 bytes read in 1245 ms (2.6 MiB/s)
20378 bytes read in 265 ms (74.2 KiB/s)
## Booting kernel from Legacy Image at 42000000 ...
   Image Name:   Linux-3.14.28-g1a4251b
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3336864 Bytes = 3.2 MiB
   Load Address: 40008000
   Entry Point:  40008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 41000000
   Booting using the fdt blob at 0x41000000
   Loading Kernel Image ... OK
   Loading Device Tree to 4fb4b000, end 4fb52f99 ... OK

Starting kernel ...

3.1 U-Boot Environment

On the SPI flash U-boot has both the U-boot application and the U-boot environment. Our default build has 8KB of environment which can be used for variables and scripts to control booting your operating system. These commands are relevant to manipulating the environment:

# Print all environment variables
env print -a

# Sets the variable bootdelay to 5 seconds
env set bootdelay 5;

# Variables can also contain commands
env set hellocmd 'led red on; echo Hello world; led green on;'

# Execute commands saved in a variable
env run hellocmd;

# Commit env changes to the spi flash
# Otherwise changes are lost
env save

# Restore env to default
env default -a

# Remove a variable
env delete emmcboot

For a production environment the best option for setting depends on the number of units. For a smaller number of units it may be simplest to update any required commands manually. For example, a custom cmdline option like "debug":

env set cmdline_append rw rootwait console=ttyAMA0,115200 loglevel=3 debug
env save

3.2 U-Boot Commands

These commands are agnostic to the operating system that is running, but may be useful for testing or scripting:

# The most important command is 
# This can also be used to see more information on a specific command
help mmc

# Boots into the binary at $loadaddr.  This file needs to have
# the uboot header from mkimage.  A uImage already contains this.
# Boots into the binary at $loadaddr, skips the initrd, specifies
# the fdtaddr so Linux knows where to find the board support
bootm ${loadaddr} - ${fdtaddr}

# Get a DHCP address
# This sets ${ipaddr}, ${dnsip}, ${gatewayip}, ${netmask}
# and ${ip_dyn} which can be used to check if the dhcp was successful

# These commands are mainly used for scripting:
false # do nothing, unsuccessfully
true # do nothing, successfully

# Control LEDs
led red on
led green on
led all off
led red toggle

# This command is used to copy a file from most devices
# Load kernel from SD
load mmc 0:2 ${loadaddr} /boot/uImage
# Load kernel from USB
usb start
load usb 0:1 ${loadaddr} /boot/uImage

# View the fdt from u-boot with fdt
load mmc 0:2 ${fdtaddr} /boot/imx28-ts7680.dtb
fdt addr ${fdtaddr}
fdt print

# Blindly jump into any memory location
# This is similar to bootm, but it does not use the 
# u-boot header
load mmc 0:2 ${loadaddr} /boot/custombinary
go ${loadaddr}

# Browse fat,ext2,ext3,or ext4 filesystems:
ls mmc 0:2 /

# Similar to devmem in Linux, read/write arbitrary memory
# using mw and md
# write
mw 0x10000000 0xc0ffee00 1
# read
md 0x10000000 1

# Test memory.  Typically just used in production

# Read newly inserted SD card
mmc rescan
# Read SD card size
mmc dev 0

# The NFS command is similar to 'load', but used over the network
env set serverip
nfs ${loadaddr}

# Test ICMP

# Reboot

# SPI access is through the SF command
# Be careful with sf commands since
# this is where u-boot and the FPGA bitstream exist
# Improper use can render the board unbootable
sf probe

# Delay in seconds
sleep 10

# It is possible to load HUSH scripts that have been created with mkimage
load mmc 0:2 ${loadaddr} /boot/ubootscript
source ${loadaddr}

# Most commands have return values that can be used to test
# success, and HUSH scripting supports comparisons similar to
# test in Bash, but much more minimal
if load mmc 0:2 ${fdtaddr} /boot/uImage;
	then echo Loaded Kernel
	echo Could not find kernel

# Commands can be timed with "time" similar to Linux
time sf probe

# Print U-boot version/build information

3.3 Modify Linux Kernel cmdline

The Linux kernel cmdline can be customized by modifying the cmdline_append variable. Keeping the default options here is recommended, but additional arguments can be appended to this variable.

env set cmdline_append rw rootwait console=ttyAMA0,115200 loglevel=3
env save

You can also change the kernel command line from the onboard Linux. From the board's shell prompt run:

apt-get update && apt-get install u-boot-tools -y
echo "env set cmdline_append rw rootwait console=ttyAMA0,115200 quiet" > /boot/boot.scr
mkimage -A arm -T script -C none -n 'tsimx28 boot script' -d /boot/boot.scr /boot/boot.ub

The boot.scr includes the plaintext commands to be run in u-boot on startup, and mkimage adds a checksum and header to this file which can be loaded by u-boot. The ub file should not be manually modified.

3.4 Linux NFS Boot

U-boot includes support for NFS which can be used to load your kernel, device tree binary, and root filesystem. Our default environment contains the nfsboot command which can be updated to boot NFS on your network:

# Set this to your NFS server ip
env set nfsip;

# Set this to your NFS root path.  The server root should be accessible at this path.
env set nfsroot /nfsroot/rootfs/
env save

To boot your NFS root:

# Boot to NFS once
run nfsboot;

# To make the NFS boot the persistent default
env set bootcmd run nfsboot;
env save

3.5 Linux USB Boot

By default, U-Boot will attempt to read a U-Boot script from a USB drive when the U-Boot jumper is set. It copies /tsinit.ub into memory and jumps in to the script. To make a bootable drive, create a single ext3 partition on a USB drive and unpack the rootfs tarball located here

The one addition is to create the tsinit.ub file in the root of the USB drive. In order to do this, a U-Boot script must be created and then converted to the .ub format. This process requires a set of U-Boot specific tools. These are available on most every linux distribution, the instructions below are for Debian, either run on a host PC or on the target. See the package installation documentation for other respective distributions.

Install U-Boot tools in Debian

apt-get update && apt-get install u-boot-tools -y

Create the file tsinit.scr in the root of the USB drive with the linux filesystem:

# Prepare with:
# mkimage -A arm -T script -C none -n 'imx28 usb' -d tsinit.scr tsinit.ub


if load usb 0:1 ${loadaddr} /boot/ts${model}-fpga.vme;
        then fpga load 0 ${loadaddr} ${filesize};

load usb 0:1 ${fdtaddr} /boot/imx28-ts${model}.dtb;

load usb 0:1 ${loadaddr} /boot/uImage;

setenv bootargs root=/dev/sda1 ${cmdline_append};
bootm ${loadaddr} - ${fdtaddr};

Then in the same directory generate the tsinit.ub file:

mkimage -A arm -T script -C none -n 'imx28 usb' -d tsinit.scr tsinit.ub

You may need to install u-boot-tools or the equivalent package for your distribution.

3.6 U-Boot Recovery

The development tool, TS-9468, can be used to recover the SBC. Set the flip switch in the "Up" position so it lights up red when powered on to boot from the SPI flash on the TS-9468; the TS-9468 may not ship with a switch, without the switch populated the TS-9468 will automatically boot to the SPI flash on the TS-9468. Use the instructions in Update U-Boot to download and copy in the latest U-Boot binary to SD and boot the unit. And instead of the command listed, use the following:

env set spi onboard
run update-uboot

The script output will include a message saying that it is writing to the onboard SPI flash. The environment variable "spi" can be set to "offboard" in order to force writing to the TS-9468 in order to update the binary on there. Note that if the variable is not set, the script will write to the SPI flash of the SBC or TS-9468 based on the switch position (if there is one).

4 Debian Configuration

For development, it is recommended to work directly in Debian on the SD card. Debian provides many more packages and a much more familiar environment for users already versed in Debian. Through Debian it is possible to configure the network, use the 'apt-get' suite to manage packages, and perform other configuration tasks. Out of the box the Debian distribution does not have any default username/password set. The account "root" is set up with no password configured. It is possible to log in via the serial console without a password but many services such as ssh will require a password set or will not allow root login at all. It is advised to set a root password and create a user account when the unit is first booted.

Note: Setting up a password for root is only feasible on the uSD image.

It is also possible to cross compile applications. Using a Debian host system will allow for installing a cross compiler to build applications. The advantage of using a Debian host system comes from compiling against libraries. Debian cross platform support allows one to install the necessary development libraries on the host, building the application on the host, and simply installing the runtime libraries on the target device. The library versions will be the same and completely compatible with each other. See the respective Debian cross compiling section for more information.

4.1 Configuring the Network

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 subnet mask)
ifconfig eth0

# Set a specific subnet
ifconfig eth0 netmask

# Configure your route.  This is the server that provides your internet connection.
route add default gw

# Edit /etc/resolv.conf for your DNS server
echo "nameserver" > /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

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                                            
 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.

4.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
                    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".

4.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:

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.

4.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.

Note: The NAND image is based on the emdebian project which is no longer maintained.

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.

4.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.

Note: Setting up a password for root is only feasible on the uSD image.
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.

4.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
     ## If you are launching a daemon or other long running processes
     ## this should be started with
     # nohup /usr/local/bin/yourdaemon &
     # if you have anything that needs to run on shutdown
     echo "Usage: customstartup start|stop" >&2
     exit 3
 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":


export HOME=/root/
export ICEWM_PRIVCFG=/mnt/root/root/.icewm/

icewm-lite &

while ! xprop -root | grep -q _NET_SUPPORTING_WM_CHECK
    sleep 0.1

exec /usr/bin/fullscreen-webkit

Replace fullscreen-webkit with your own graphical application.

5 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.

5.1 MicroSD Card

MicroSD8GB.png Click to download the latest 4GB SD card image.

Using other OSs

At this time, we're unable to provide assistance with writing SD cards for our products from non-Linux based operating systems. We acknowledge however, that there are methods to write images and files from a variety of difference operating systems. If a native installation of Linux is unavailable, we recommend using a Virtual Machine. See the Getting Started section for links to common virtualization software and Linux installation.

Using a Linux workstation

An SD card can be written to allow it to be bootable. Download the above file and write this from a Linux workstation using the information below. A USB SD adapter can be used to access the card; or if the workstation supports direct connection of SD cards, that can be used instead. Once inserted in to the workstation, it is necessary to discover which /dev/ device corresponds with the inserted SD card before the image can be written.

Option 1: using 'lsblk'

Newer distributions include a utility called 'lsblk' which allows simple identification of the intended card.

Note: This command may need to be run as the root user:
$ lsblk

sdY      8:0    0   400G  0 disk 
├─sdY1   8:1    0   398G  0 part /
├─sdY2   8:2    0     1K  0 part 
└─sdY5   8:5    0     2G  0 part [SWAP]
sr0     11:0    1  1024M  0 rom  
sdX      8:32   1   3.9G  0 disk 
├─sdX1   8:33   1   7.9M  0 part 
├─sdX2   8:34   1     2M  0 part 
├─sdX3   8:35   1     2M  0 part 
└─sdX4   8:36   1   3.8G  0 part

In this case the, SD card is 4GB, so sdX is the target device and already contains 4 partitions. Note that sdX is not a real device, it could be sda, sdb, mmcblk0, etc. Technologic Systems is not responsible for any damages cause by using the improper device node for imaging an SD card. The instructions below to write to the device will destroy the partition table and any existing data!

Option 2: Using 'dmesg'

After plugging in the device, the 'dmesg' command can be used to list recent kernel events. When inserting a USB adapter, the last few lines of 'dmesg' output will be similar to the following (note that this command may need to be run as the root user):

$ dmesg
scsi 54:0:0:0: Direct-Access     Generic  Storage Device   0.00 PQ: 0 ANSI: 2
sd 54:0:0:0: Attached scsi generic sg2 type 0
sd 54:0:0:0: [sdX] 3862528 512-byte logical blocks: (3.97 GB/3.84 GiB)

In this case, sdX is shown as a 3.97GB card with a single partition. Note that sdX is not a real device, it could be sda, sdb, mmcblk0, etc. Technologic Systems is not responsible for any damages cause by using the improper device node for imaging an SD card. The instructions below to write to the device will destroy the partition table and any existing data!

The instructions below use the latest stock image.

Once the target /dev/ device has been located, the 'dd' command can now be used to backup/restore the card to our stock image:

# Specify the correct block device obtained above instead of /dev/sdX
# Note that this is a whole disk image, be sure to use /dev/sdX instead
# of a partition, e.g. /dev/sdX1
wget https://files.embeddedarm.com/ts-arm-sbc/ts-7680-linux/binaries/ts-images/ts7680-latest.dd.bz2
bzcat ts7680-latest.dd.bz2 | dd conv=fsync bs=4M of=/dev/sdX

It is also possible to use this process to update the TS-7680 to the Linux 4.9 kernel with Debian Stretch image. Please take a look at the Caveats of using Linux 4.9 before proceeding in using this image.

# Specify the correct block device obtained above instead of /dev/sdX
# Note that this is a whole disk image, be sure to use /dev/sdX instead
# of a partition, e.g. /dev/sdX1
wget http://ftp.embeddedarm.com/ftp/ts-arm-sbc/ts-7680-linux/binaries/ts-images/ts7680-linux4.9-latest.dd.bz2
bzcat ts7680-linux4.9-latest.dd.bz2 | dd conv=fsync bs=4M of=/dev/sdX

5.2 NAND Flash

The NAND is divided in to three devices, mtd0, mtd1, and mtd2. mtd0 contains the raw bootstream (kernel and initramfs in one binary), mtd1 contains what would normally be the /ts folder on the SD card, and mtd2 contains the linux root filesystem (mtd1 and mtd2 use UBI and UBIFS and can be subdivided down further with mechanisms in UBIFS, see UBI and UBIFS for more information). Since UBI/UBIFS does have a fairly linear mount time for device size, mtd1 is made fairly small, 8MB. This allows for increased startup speed when booting from NAND so that configuration, FPGA softload, or other scripts may be run as soon as possible after power is applied.

5.2.1 Kernel

The kernel build scripts will build and copy a uImage file to the SD card. This file is used by U-Boot for SD card and NAND booting. For the NAND however, and extra step is required to copy the uImage file in to a NAND partition that U-Boot can quickly load from. This can be accomplished with a single U-Boot command.

First, boot to the U-Boot shell by holding the push switch while applying power. The device does not need to be booted from SD, however the following command expects a properly formatted SD card, with the kernel to be installed, present in the system at bootup.

At the U-Boot prompt, enter the command:

run update_nand_kernel

The output will show the NAND kernel partition being erased, and then having the new kernel written to it. A valid U-Boot binary must also be installed in the NAND in order to boot from. This process is completed at the factory, however it is possible to restore or update the U-Boot binary. Please see the U-Boot section for more information.

5.2.2 Filesystem

Making a UBIFS Debian image from existing filesystem is the best way to make a custom image for production devices. Technologic Systems strongly recommends doing all development on an SD card; later, create a UBIFS image from that Debian filesystem. Copying the large amount of small files on the Debian filesystem directly to or from the NAND device is very time consuming.

In order to create a UBIFS image from a host PC mtd-utils will need to be installed, please see your distribution's documentation for instructions on installation

#/mnt/source_fs_root is the mounted Debian filesystem on an SD; /mnt/usb is a USB drive to store the image for later use
mkfs.ubifs -m4096 -e516096 -c3861 -r /mnt/source_fs_root/ nandimg.ubifs

Note that the UBI rootfs partition on NAND is 1900MiB, Make sure that the UBIFS image is smaller than this. UBI does implement compression on-disk, so the total size of a folder tree may not reflect the actual filesystem size when made in to a UBIFS image. For example, our default SD Debian root filesystem is around 1.2GB, however when made in to a UBIFS image with the above command, it is compressed to roughly 550MB and remains this size on disk.

The latest UBIFS image can be found on our FTP site.

This NAND UBIFS image can be used in conjunction with tools in our initramfs to flash the NAND device.

Copy nandimg.ubifs to the root Debian folder (partition 2) of a pre-imaged bootable SD card. The SD card can either be a freshly imaged SD card, or be one that was used for current development, provided that there is enough space to fit the UBIFS image. Boot from the SD card to the initramfs, when presented a command prompt, run the following command:


Output from the command will look like the following:


The following command can be used to flash the UBIFS image to NAND:


The UBIFS image file is expected to be located at /mnt/usbdev/nandimg.ubifs, the command is intended for use with our USB update mechanism.

WARNING: The `filesystem_from_*` commands will completely format any existing data that is on the NAND linux root partition

Using filesystem_from_usb when booted from NAND

While there is no issue in executing filesystem_from_usb when booted from SD (provided there are no flash partitions mounted), further preparation is required in order to successfully boot from eMMC/NAND, and use the USB update functionality to update the flash. A USB device is required to have the the Debian distribution on the first partition and a specific set of steps in the "tsinit" script - this ensures that all flash partitions are safely unmounted and the necessary tools are available. See the initramfs USB scripting section for more information on setting up the "tsinit" script.

Using a linux host PC, format a USB drive with the first partition (min. 2GB) formatted ext2/3. Download the distribution tarball and extract it to first partition of the USB drive.

Next, set up the "tsinit" file with the following script outline:


#We only need unmount /mnt/root and use USB if booted from NAND/eMMC
if [ "$bootmode" == "0x1" ]; then
  killall mdnsd >/dev/null #Required to cleanly umount /etc
  sleep 1
  if [ -e /dev/mtd0 ]; then
    umount /mnt/root/ts
  umount /etc
  umount /mnt/root

  mount -obind /mnt/usbdev /mnt/root
  mount -obind /mnt/root/etc /etc/

echo ""
source /ts.subr
tshwctl --greenledon --redledon
echo "Flashing kernel"
kernel_from_usb >/dev/null 2>&1
if [ "$?" != "0" ]; then
  echo "Failed flashing kernel"
  tshwctl --greenledoff
  while true; do tshwctl --redledon; sleep .5; tshwctl --redledoff; sleep .5 ; done &
  return 1
echo "Flashing filesystem"
eval `filesystem_from_usb`
if [ "$prog_ok" != "1" ] ; then
  echo "Failed flashing filesystem"
  tshwctl --greenledoff
  while true; do tshwctl --redledon; sleep .5; tshwctl --redledoff; sleep .5 ; done &
  return 1

#We only need unmount /mnt/root and use USB if booted from NAND
if [ "$bootmode" == "0x1" ]; then
  umount /etc
  umount /mnt/root

echo "Done"
while true; do tshwctl --greenledon; sleep .5; tshwctl --greenledoff; sleep .5 ; done &

Be sure to copy nandimg.ubifs and imx28_ivt_linux.sb to the root directory of the first partition of the USB drive as well!

Note, if you wish to integrate this in to your own custom USB update script, the critical sections for setting up this process are surrounded by the if blocks that check for NAND being the bootdev.

The above script will keep both LEDs on and solid while the process is happening, and will blink the green or red LED upon success or fail of the imaging process. Upon completion a power cycle or reboot is required if booted from NAND to run the update.

There are a number of different configurations and setups available when using UBI and UBIFS, see UBI and UBIFS for more information about the capabilities of the subsystem.

6 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.


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.


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.


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.

6.1 Accessing Hardware Registers

TS-7670 Accessing Hardware Registers

6.2 Cross Compiling

While it is recommend to develop entirely on the SBC itself, it is also possible to develop from an x86 compatible Linux system using a cross compiler. For this SBC use the cross compiler located here. The resulting binary will be for ARM.

[user@localhost]$ /path/to/arm-fsl-linux-gnueabi/bin/arm-linux-gcc hello.c -o hello
[user@localhost]$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

This is one of the simplest examples. For working with a larger project a Makefile will typically be used. More information about Makefiles is available here. Another common requirement is linking to third party libraries provided by Debian on the SBC. There is no exact set of steps for every project when cross compiling, but the process will be very much the same. Provide the cross compiler with access to the necessary headers, libraries, and source files, and install the binary on the target. The following example will link to sqlite from Debian.

Install the sqlite library and header on the SBC:

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

This will fetch the binaries from the internet and install them on the SBC. The installed files can then be listed with dpkg:

dpkg -L libsqlite3-0 libsqlite3-dev

The needed files from this output will be the .h and .so files, they will need to be copied to the project directory on the cross-compling host.

See the 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);
		fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
		fprintf(stderr, "SQL error: %s\n", zErrMsg);
	printf("closing test.db\n");
	return 0;

To build this with the external libraries the makefile below can be used. This will have to be adjusted for the proper toolchain path. In this example, the headers are located in external/include and the library in external/lib.

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/

        rm -rf *o sqlitetest.o sqlitetest

The resulting binary can be copied to the target and executed. 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 needed frequently during development, but will require a setup. See the host linux distribution's manual for more details. The simplest network method is using ssh/sftp. If running Windows, winscp can be used, or just scp in linux. Make sure a password is set for a user account, root or otherwise, in order to properly ssh or scp files to the target. From winscp, enter the ip address of the SBC, the root username, and the password; this will create an explorer window that can use drag-and-drop of files to copy them to the target.

For scp in linux, run:

#replace with the binary name and the SBC IP address
scp sqlitetest root@

After transferring the file to the board, execute it:

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

6.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:


All systems:

Download and unpack the cross compiler:

Note: The cross compiler set up in the Cross Compiling section is 64-bit and can be used instead of the 32-bit cross compiler below. If using the aforementioned compiler, it is not necessary to install the 32-bit compatibility libraries as is it for the 32-bit cross compiler on a 64-bit Debian Jessie installation.
wget ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7680-linux/cross-toolchains/imx28-cross-glibc.tar.bz2
tar xvf imx28-cross-glibc.tar.bz2 -C /path/to/folder/

/path/to/folder can be any directory so long as the current user has permissions to write to it. Remember this path as its used later during the kernel build procedure.


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


sudo apt-get install build-essential libncurses5-dev libncursesw5-dev git u-boot-tools

If you are on a 64-bit system, then 32-bit libraries will be required for the toolchain, for newer Debian and Ubuntu distrubutions with Multiarch support, use the command:

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6-dev:i386 zlib1g-dev:i386

On older distributions:

sudo apt-get install ia32-libs

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

Download sources and configure

git clone https://github.com/embeddedarm/linux-3.14.28-imx28.git
cd linux-3.14.28-imx28/

# These next commands set up some necessary environment variables
export ARCH=arm
export CROSS_COMPILE=/path/to/folder/arm-fsl-linux-gnueabi/bin/arm-linux-
# If using the 64-bit cross compiler from the Cross Compiling section, the following CROSS_COMPILE variable can be
# used if the environment PATH is set up properly:
# export CROSS_COMPILE=arm-linux-gnueabi-
export LOADADDR=0x40008000

# This sets up the default configuration that we ship with
make ts76xx_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. This group of commands will also output a uImage file used by U-Boot on the TS-7680.

make && make uImage && make modules

We recommend running 'make' with the -jX argument, where X is the number of CPU cores+1 present on the build machine. This will greatly increase build speed.

Install the kernel/initramfs, headers, and modules

Next you need to install the kernel and modules to the SD card. We provide a simple script to copy the kernel uImage file, kernel modules, and headers to the SD card to update everything at once.

For example, if your workstation's SD card is /dev/mmcblk0:

./install_hdr_mod mmcblk0p2

If your workstation's SD card is /dev/sdc:

./install_hdr_mod sdc2

7 Features

7.1 ADC

There are 5 Analog to Digital inputs on the bottom row of the 24-position screw terminal.

The tshwctl utility can be used to read the ADC values.

tshwctl --cpuadc

7.2 Battery Backed RTC and Temperature Sensor

This board includes a temperature compensating RTC which maintains ±5 ppm between 0C to +85C. This is accessed in software using tshwctl. By default, tshwctl will run "tshwctl --getrtc" on startup which will pull system time from the RTC, and set the system time. During the Technologic Systems production process the RTC will be programmed with an accurate time.

If time ever needs to be set you can run:

tshwctl --setrtc

This will take the system time and write it to the RTC. The battery in the RTC will last approximately 10 years for most applications, but the RTC allows you to see when the battery reaches low or critical voltages:

# tshwctl --rtcinfo             

rtcinfo_oscillator_ok is true when the RTC is operational and time is being kept
rtcinfo_batt_low is true when the battery is less than 2.805v (85% of 3.3v)
rtcinfo_batt_crit is true when the battery is less than 2.475v (75% of 3.3v)

Note: While the RTC will remain operational with a battery voltage down to 1.8v, the lithium battery used has a very steep discharge curve. Once the battery reaches critical level it should be replaced.

rtcinfo_first/lastpoweroff/on are two registers that denote the first time the RTC started using battery power, and the last time power was restored and the RTC stopped using battery power for timekeeping. The output of these registers is in the format MMDDhhmmss. Once `tshwctl --rtcinfo` is called, these registers are cleared and able to be set again. This is a great tool to check if a power off has occurred and how long it lasted.

7.3 CAN

The TS-7670 i.MX286 CPU has two FlexCAN ports that use the linux SocketCAN implementation. The ports can be set up and used with the following commands:

modprobe flexcan
ifconfig can0 up
ifconfig can1 up

In order to set the baud rate of either CAN interface, the interface must first be brought down with:

ifconfig canX down

Where "X" is interface 0 or 1. At this point, the desired baud rate can be directly entered in to the file "/sys/devices/platform/FlexCAN.X/bitrate", where X is the desired interface. For example, to set a baud rate of 750kHz on both interfaces:

echo 750000 > /sys/devices/platform/FlexCAN.0/bitrate
echo 750000 > /sys/devices/platform/FlexCAN.1/bitrate

At this point the ports can be used with standard SocketCAN libraries. In debian we provide cansend and candump to test the ports or as a simple packet send/recv tool. In order to test the two ports together, tie CAN_H of both CAN ports together, and do the same for CAN_L. Then use the following commands:

candump can0 &
cansend can1 can1 7DF#03010C
#This command will return
  can0  7DF  [3] 03 01 0C

7.4 CPU

This board features the i.MX286 454 MHz ARM9 from NXP. For more information about the processor and it's included peripherals, refer to the CPU manual.

7.5 DAC

There are four 0-9 V DAC ports on the TS-7680. These DACs can be controlled via a PWM which passes through a low pass filter. The FPGA registers contain a 12-bit register (accessible as two 8-bit registers) for each DAC channel.

By using the following equation, output voltage within 5% accuracy can be achieved:

PWMval = ((380 * Vdesired) - 98)

Once PWMval is determined, this value can be plugged in to tshwctl to set individual channels:

tshwctl --dac0 <PWMval>
tshwctl --dac1 <PWMval>
tshwctl --dac2 <PWMval>
tshwctl --dac3 <PWMval>

The DAC ports are available on the following connectors:

Port Location(s)
0 HD4_5 / B_9
1 HD4_3 / B_10
2 HD4_1 / B_11
3 HD4_2 / B_12

7.6 DIO

The TS-7680 offers DIO, inputs, and low-side switches to accommodate nearly every application. The DIO exposed to various headers and terminals are controlled via the FPGA or CPU. Some DIO have a secondary function associated with them. All DIO are 3.3 V tolerant unless otherwise noted. The low-side switches are able to sink 500 mA each with a maximum voltage input of 30 V (protected by a 30 V Zener diode). The low-side switches, when deasserted, are high impedance inputs. A logical 0 input occurs from roughly 0 V to 1.5 V, while a logical 1 input occurs from roughly 1.6 V and higher on the low-side switches when in input mode.

DIO Location Function
0 HD4_13 / T_4 Input/LS output
1 HD4_11 / T_5 Input/LS output
2 HD4_09 / T_6 Input/LS output
3 HD4_7 [1] / B_8 [1] Input Only
21 HD4_21
23 HD4_23
25 HD4_25
26 HD4_26
27 HD4_27
28 HD4_28
29 HD4_29
30 HD4_30
31 HD4_31
32 HD4_32
33 HD4_33
34 HD4_34
35 HD4_35
1_7 HD1_14
1_8 HD1_9
1_9 HD1_7
  1. 1.0 1.1 5 V Tolerant

The above DIO can be manipulated by using tshwctl:

tshwctl --setdio <dio1>,<dio2> #Output high DIO/deassert LS switch
tshwctl --clrdio <dio1>,<dio2> #Output low DIO/assert LS switch
tshwctl --getdio <dio1>,<dio2> #Tristate DIO/deassert LS switch and return input value


The TS-7680 implements a 1kbyte EEPROM, data can be accessed with

tshwctl --address <adr> --peek16
tshwctl --address <adr> --poke16 <val>

Valid addresses are 0x0 to 0x3FE. The upper addresses will be reserved in future releases for ADC calibration values. The device itself is 8bits wide per address, however tshwctl treats it as 16bit to make it more consistent with other products.

7.8 External Reset

The TS-7670 has a multi-purpose tactile button at a right angle to the PCB. This button can be used as a mechanism to issue a hardware reset to the SBC or as a way to wake up the device from its sleep modes (see Sleep for more information). The stock image for both SD and NAND enable the button to be a reset switch. This functionality can be disabled with:

tshwctl --resetswitchoff

And can be re-enabled with:

tshwctl --resetswitchon

7.9 FPGA

The TS-7680 features an FPGA designed to accentuate the i.MX28 CPU peripherals with some additional peripherals and flexibility. The FPGA is connected to the CPU through an I2C bus.

See the Syscon section for more information about the FPGA register map.

7.9.1 FPGA Bitstreams

The FPGA has the capability to be reloaded on startup and reprogram itself with different configurations. The FPGA does have an internal configuration is stored, however the FPGA SRAM can be reloaded at bootup to provide an updated FPGA logic, or other custom implementations. U-Boot will automatically load the bitstream located at /boot/ts<model>-fpga.vme on the Debian root at startup.

The FPGA can be updated to the latest revision by booting to Debian and running:

cd /boot/
wget ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7680-linux/binaries/ts-bitstreams/ts7680-fpga.vme

The FPGA is loaded in to the FPGA SRAM on every poweron, so this file will need to exist for all future boots.

An FPGA revision changelog can be found in the Revisions and Changes section.

7.9.2 FPGA Programming

Currently, creating custom bitstreams is not supported. For more information contact Technologic Systems.

7.10 I2C

The i.MX28 CPU I2C pins are not exposed to any external interfaces on this SBC. Because of this, bitbanging is strongly recommended for any attached peripherals that would utilize I2C.

Technologic Systems recommends using direct bitbanging of I2C pins from userspace to drive an I2C interface. See the DIO section for further information on manipulating DIO pins.

Another option is to implement i2c-gpio in linux. This allows for an I2C physical interface on GPIO pins, but uses the kernel I2C software interface to read and write data on the I2C bus. See linux kernel documentation and i2c-dev for more information on this.

7.11 LEDs

On all of our SBCs we include 2 indicator LEDs which are under software control. You can manipulate these using "tshwctl --greenledon --redledon" or "tshwctl --greenledoff --redledoff". The LEDs have 4 behaviors from default software.

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 SBC is not able to boot. Typically either the board is not being supplied with enough voltage, or the SBC has been otherwise damaged. If a stable voltage is being provided and the supply is capable of providing at least 1A to the SBC, 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.

7.12 MicroSD Card Interface

The i.MX28 SD card controller is used for the SD card present on the board which supports the SD and SDHC specifications. 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.

Our default software image contains 2 partitions:

Device Contents
/dev/mmcblk0 SD Card block device
/dev/mmcblk0p1 Kernel and initramfs
/dev/mmcblk0p2 Full Debian linux partition

7.13 NAND

The NAND on the i.MX286 is a 2GiB part attached directly to the CPU. The kernel handles the NAND through its MTD drivers.

Instead of a traditional flash filesystem (JFFS2 for example) the i.MX286 implements UBI and UBIFS.

7.13.1 UBI and UBIFS

UBI is the Unsorted Block Images layer, and is an erase block management layer. UBI serves two purposes, tracking NAND bad blocks and providing wear leveling. While it is possible to run a traditional flash filesystem on top of UBI, it is not recommended. UBIFS was written with UBI in mind and is able to take full advantage of what UBI provides. UBIFS has multiple advantages over JFFS2, UBIFS supports write caching, UBIFS performs better on larger NAND devices, mounts faster, allows for quicker access to large files, improved write speeds, and indexes stored in flash not in system memory.

7.13.2 Using UBI and UBIFS

UBI is implemented directly on top of linux's MTD subsystem, the first thing necessary is to format the device for UBI to use.

ubiformat /dev/mtd1 #This will prepare /dev/mtd1 to accept UBI and is mindful of UBIs erase counters

After this, the device must be attached to UBI

ubiattach -m 1

This will attach the device to the UBI subsystem. Doing this will create a /dev/ubi0 device node that represents the entire UBI device. A UBI attach does take longer on larger MTD devices.

Once this is done, at least one volume must be made. There are two types of volumes, static and dynamic. A dynamic volume is liken to a standard filesystem, it creates and uses a UBIFS filesystem. A static volume is meant to be run right on top of UBI, and does not use UBIFS. It is meant for smaller volumes with blobs of configuration data, and is protected with CRC32s. While it is possible, it is not wise to use UBIFS on top of a static volume, it will result in a much slower device since since both UBI and UBIFS will be implementing CRC32s.

7.14 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:


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

eval `tshwctl --nvram`
echo $nvram2

From the above value, this would return 0x48ca4278. To set values, the respective environment variable name can be set:

nvram0=0x42 tshwctl --nvram

Note that the command 'tshwctl --nvram' will output the current contents of NVRAM before setting any new values. At this point, running 'tshwctl --nvram' once more will print the updated contents for verification. This can be used for reading a 32-bit quantity and updating it with a single command.

7.15 Relays

The TS-7680 features 2 SPDT relays rated for 5A at 277VAC or 30VDC that the user can toggle through an FPGA register. The PCH-105D2H relay closes in 10ms, and opens in 5ms. A very safe assumption would be that it will switch after 20ms. The common, NO (Normally Open), and NC (Normally Closed) connections are brought out to multiple points. See the FPGA Syscon section for information on manipulating the relays.

Relay 1
Contact Location(s)
COM T_8 / HD4_19
NO T_7 / HD4_15
NC T_9 / HD4_17
Relay 2
Contact Location(s)
COM T_11
NO T_10
NC T_12

7.16 Sleep

The addition of a microcontroller on board this SBC allows it to play a supervisory role over the CPU. Two sleep modes are available, each with the ability to wake up after a set amount of time, or after a push of the tactile push switch on the edge of the PCB.

7.16.1 Sleep

This low power sleep mode will remove power from all of the rails, turning off the CPU and every other peripheral save for the microcontroller. This mode offers extreme power savings, only requiring around 9mW of power, with the ability to wake up after an arbitrary timeout (up to 1847297s, which is 21d 9h 8m 17s) with a 1s resolution. Note that as soon as the command to sleep is issued, the device will sleep as soon as possible. This has the ability to cause filesystem corruption if proper precautions are not taken before the SBC is put to sleep. In order to enter this mode, issue the following command:

tshwctl --sleep --timewkup <time in seconds> --resetswitchwkup

Note that both --timewkup and --resetswitchwkup are optional arguments, you can pass none, one, or both. If no arguments are passed then the SBC will remain in sleep mode forever, until power is removed completely and re-applied. This can be useful instead of halting in linux as sleeping would consume far less power than simply halting the CPU. Waking up from this mode will take roughly 4-5s from when the timer expires or when the reset button is pressed. This is normal bootup time for the CPU.

7.16.2 Standby

This sleep mode does consume more power, roughly 250mW, however the CPU is put in a standby mode with the RAM contents and CPU cache preserved. When the CPU wakes up from this mode it will continue execution from where it left off. This wakeup process takes roughly 250ms from when the sleep timer expires or the reset button is pushed. Like the sleep mode above, the timer on standby can be an arbitrary number (up to 1847297s, which is 21d 9h 8m 17s) with a 1s resolution. Unlike the above sleep mode, it is safe to enter standby at almost any time without concern for data loss. The only unsafe time is during a write to the SD card that has completed in linux, but the SD card controller is still attempting to flush the write to disk. In all of Technologic Systems' testing, we have not observed any corruption caused by entering or exiting the standby mode. The standby mode can be entered with the following command:

tshwctl --standby --timewkup <time in seconds> --resetswitchwkup

Note that both --timewkup and --resetswitchwkup are optional arguments, you can pass none, one, or both. If no arguments are passed then the SBC will remain in standby mode forever, until power is removed completely and re-applied. In the case of the standby mode however, it does not make sense to leave it in this mode indefinitely. After this mode is exited, the function of the reset switch is restored to its previous state, see External Reset for more information.

7.17 SPI

This SBC utilizes all of the i.MX28 CPU SPI ports for the SD cards, therefore there is no externally available SPI peripheral from the CPU. Because of this, bitbanging is strongly recommended for any attached peripherals that would utilize SPI.

Technologic Systems recommends using direct bitbanging of SPI pins from userspace to drive an SPI interface. See the DIO section for further information on manipulating DIO pins.

Another option is to implement spi-gpio in linux. This allows for a SPI physical interface on GPIO pins, but uses the kernel SPI software interface to read and write data on the SPI bus. See linux kernel documentation, spi-gpio, and spidev for more information on this.

7.18 Syscon

All of the registers below are 8 bits wide and are accessed through the I2C interface. The FPGA is located at 7 bit address 0x28 on the linux device /dev/i2c-0. Accessing registers can either be done directly via tshwctl with the --peek and --poke options, using tshwctl options to abstract some of the access details away, or directly accessing and manipulating the linux I2C device. See the tshwctl sources for an example of how this is implemented

Offset GPIO # Bits Usage [Initial value/MUX]
192 7:2 FPGA_22 Crossbar [GPIO] (RW)
1 FPGA_22 value [0] (RW)
0 FPGA_22 output enable [0] (RW)
193 7:2 FPGA_23 Crossbar [GPIO] (RW)
1 FPGA_23 value [0] (RW)
0 FPGA_23 output enable [0] (RW)
194 7:2 FPGA_24 Crossbar [GPIO] (RW)
1 FPGA_24 value [0] (RW)
0 FPGA_24 output enable [0] (RW)
195 7:2 FPGA_25 Crossbar [GPIO] (RW)
1 FPGA_25 value [0] (RW)
0 FPGA_25 output enable [0] (RW)
196 7:2 FPGA_26 Crossbar [GPIO] (RW)
1 FPGA_26 value [0] (RW)
0 FPGA_26 output enable [0] (RW)
197 7:2 FPGA_27 Crossbar [GPIO] (RW)
1 FPGA_27 value [0] (RW)
0 FPGA_27 output enable [0] (RW)
198 7:2 FPGA_28 Crossbar [GPIO] (RW)
1 FPGA_28 value [0] (RW)
0 FPGA_28 output enable [0] (RW)
199 7:2 FPGA_29 Crossbar [GPIO] (RW)
1 FPGA_29 value [0] (RW)
0 FPGA_29 output enable [0] (RW)
200 7:2 FPGA_30 Crossbar [GPIO] (RW)
1 FPGA_30 value [0] (RW)
0 FPGA_30 output enable [0] (RW)
201 7:2 FPGA_31 Crossbar [GPIO] (RW)
1 FPGA_31 value [0] (RW)
0 FPGA_31 output enable [0] (RW)
202 7:2 FPGA_32 Crossbar [GPIO] (RW)
1 FPGA_32 value [0] (RW)
0 FPGA_32 output enable [0] (RW)
203 7:2 FPGA_33 Crossbar [GPIO] (RW)
1 FPGA_33 value [0] (RW)
0 FPGA_33 output enable [0] (RW)
204 7:2 FPGA_34 Crossbar [GPIO] (RW)
1 FPGA_34 value [0] (RW)
0 FPGA_34 output enable [0] (RW)
205 7:2 FPGA_35 Crossbar [GPIO] (RW)
1 FPGA_35 value [0] (RW)
0 FPGA_35 output enable [0] (RW)
N/A 7:4 Reserved
3 DIG_IN 5V (RO)
2 DIO_2_IN (RO)
1 DIO_1_IN (RO)
0 DIO_0_IN (RO)
207 7:2 Reserved
1 Enable LS_DIO_0 [0] (RW)
0 Reserved
208 7:2 Reserved
1 Enable LS_DIO_1 [0] (RW)
0 Reserved
209 7:2 Reserved
1 Enable LS_DIO_2 [0] (RW)
0 Reserved
210 7:2 Reserved
1 Enable Relay 1 [0] (RW)
0 Reserved
211 7:2 Reserved
1 Enable Relay 2 [0] (RW)
0 Reserved
N/A 7:2 DC TXD Crossbar [Unassigned] (RW)
1 DC TXD value [0] (RW)
0 Reserved
N/A 7:2 COM1 TXD Crossbar [UART1_TXD] (RW)
1 COM1 TXD value [0] (RW)
0 Reserved
N/A 7:2 COM2 TXD Crossbar [UART4_TXD] (RW)
1 COM2 TXD value [0] (RW)
0 Reserved
N/A 7:2 MODBUS TXD Crossbar [UART2_TXD] (RW)
1 MODBUS TXD value [0] (RW)
0 Reserved
N/A 7:2 MODBUS TXEN Crossbar [UART2_TXEN] (RW)
1 MODBUS TXEN value [0] (RW)
0 Reserved
N/A 7:2 RS-485 TXD Crossbar [UART3_TXD] (RW)
1 RS-485 TXD value [0] (RW)
0 Reserved
N/A 7:2 RS-485 TXEN Crossbar [UART3_TXEN] (RW)
1 RS-485 TXEN value [0] (RW)
0 Reserved
N/A 7:2 Bluetooth RXD Crossbar [UART0_TXD] (RW)
1 Bluetooth RXD value [0] (RW)
0 Reserved
N/A 7:2 Bluetooth CTS Crossbar [UART0_RTS] (RW)
1 Bluetooth CTS value [0] (RW)
0 Reserved
N/A 7:2 UART0 RXD Crossbar [BT_TXD] (RW)
1 UART0 RXD value [0] (RW)
0 Reserved
N/A 7:2 UART0 CTS Crossbar [BT_RTS] (RW)
1 UART0 CTS value [0] (RW)
0 Reserved
N/A 7:2 UART1 RXD Crossbar [COM1_RXD] (RW)
1 UART1 RXD value [0] (RW)
0 Reserved
N/A 7:2 UART2 RXD Crossbar [MODBUS_RXD] (RW)
1 UART2 RXD value [0] (RW)
0 Reserved
N/A 7:2 UART3 RXD Crossbar [RS_485_RXD] (RW)
1 UART3 RXD value [0] (RW)
0 Reserved
N/A 7:2 UART4 RXD Crossbar [COM2_RXD] (RW)
1 UART4 RXD value [0] (RW)
0 Reserved
227 7:2 Reserved
1 En.# pullup AD0 [1] (RW)
0 Reserved
228 7:2 Reserved
1 En.# pullup AD1 [1] (RW)
0 Reserved
229 7:2 Reserved
1 En.# pullup AD2 [1] (RW)
0 Reserved
230 7:2 Reserved
1 En.# pullup AD3 [1] (RW)
0 Reserved
231 7:2 Reserved
1 En. Current loop AD 0-1 [0] (RW)
0 Reserved
232 7:2 Reserved
1 En. Current loop AD 2-3 [0] (RW)
0 Reserved
233 7:2 Reserved
1 En. 5v on DC header [0] (RW)
0 Reserved
N/A 7:3 Reserved
2 Disable SPI interface (en. UART2 & 3) [0] (RW)
1 Boot SPI select; 0: offbd, 1: onbd [0] (RW)
0 Override automatic Boot SPI select [0] (RW)
235 7:2 Reserved
1 Ethernet reset# [0] (RW)
0 Reserved
236 7:2 Reserved
1 WLAN En. [0] (RW)
0 Reserved
237 7:2 Reserved
1 Bluetooth En. [0] (RW)
0 Reserved
N/A 7:4 Unused
3:0 Bits 11:8 of DAC0 PWM value [0] (RW)[1]
0x2F N/A 7:0 Bits 7:0 of DAC0 PWM value [0] (RW)
N/A 7:4 Unused
3:0 Bits 11:8 of DAC1 PWM value [0] (RW)[1]
0x31 N/A 7:0 Bits 7:0 of DAC1 PWM value [0] (RW)
N/A 7:4 Unused
3:0 Bits 11:8 of DAC2 PWM value [0] (RW)[1]
0x33 N/A 7:0 Bits 7:0 of DAC02 PWM value [0] (RW)
N/A 7:4 Unused
3:0 Bits 11:8 of DAC3 PWM value [0] (RW)[1]
0x35 N/A 7:0 Bits 7:0 of DAC3 PWM value [0] (RW)
0x36 N/A 7:0 Bits 23:16 of auto-485 #0 counter #0 [0] (RW)[1][2]
0x37 N/A 7:0 Bits 15:8 of auto-485 #0 counter #0 [0] (RW)[1][2]
0x38 N/A 7:0 Bits 7:0 of auto-485 #0 counter #0 [0] (RW)[2]
0x39 N/A 7:0 Bits 23:16 of auto-485 #0 counter #1 [0] (RW)[1][3]
0x3A N/A 7:0 Bits 15:8 of auto-485 #0 counter #1 [0] (RW)[1][3]
0x3B N/A 7:0 Bits 7:0 of auto-485 #0 counter #1 [0] (RW)[3]
0x3C N/A 7:0 Bits 23:16 of auto-485 #1 counter #0 [0] (RW)[1][2]
0x3D N/A 7:0 Bits 15:8 of auto-485 #1 counter #0 [0] (RW)[1][2]
0x3E N/A 7:0 Bits 7:0 of auto-485 #1 counter #0 [0] (RW)[2]
0x3F N/A 7:0 Bits 23:16 of auto-485 #1 counter #1 [0] (RW)[1][3]
0x40 N/A 7:0 Bits 15:8 of auto-485 #1 counter #1 [0] (RW)[1][3]
0x41 N/A 7:0 Bits 7:0 of auto-485 #1 counter #1 [0] (RW)[3]
0x42 N/A 7:0 Bits 23:16 of auto-485 #2 counter #0 [0] (RW)[1][2]
0x43 N/A 7:0 Bits 15:8 of auto-485 #2 counter #0 [0] (RW)[1][2]
0x44 N/A 7:0 Bits 7:0 of auto-485 #2 counter #0 [0] (RW)[2]
0x45 N/A 7:0 Bits 23:16 of auto-485 #2 counter #1 [0] (RW)[1][3]
0x46 N/A 7:0 Bits 15:8 of auto-485 #2 counter #1 [0] (RW)[1][3]
0x47 N/A 7:0 Bits 7:0 of auto-485 #2 counter #1 [0] (RW)[3]
0x48 N/A 7:0 Bits 23:16 of auto-485 #3 counter #0 [0] (RW)[1][2]
0x49 N/A 7:0 Bits 15:8 of auto-485 #3 counter #0 [0] (RW)[1][2]
0x4A N/A 7:0 Bits 7:0 of auto-485 #3 counter #0 [0] (RW)[2]
0x4B N/A 7:0 Bits 23:16 of auto-485 #3 counter #1 [0] (RW)[1][3]
0x4C N/A 7:0 Bits 15:8 of auto-485 #3 counter #1 [0] (RW)[1][3]
0x4D N/A 7:0 Bits 7:0 of auto-485 #3 counter #1 [0] (RW)[3]
0x4E N/A 7:0 Bits 23:16 of auto-485 #4 counter #0 [0] (RW)[1][2]
0x4F N/A 7:0 Bits 15:8 of auto-485 #4 counter #0 [0] (RW)[1][2]
0x50 N/A 7:0 Bits 7:0 of auto-485 #4 counter #0 [0] (RW)[2]
0x51 N/A 7:0 Bits 23:16 of auto-485 #4 counter #1 [0] (RW)[1][3]
0x52 N/A 7:0 Bits 15:8 of auto-485 #4 counter #1 [0] (RW)[1][3]
0x53 N/A 7:0 Bits 7:0 of auto-485 #4 counter #1 [0] (RW)[3]
NA 7:3 Reserved
2 WiFi Module present
1:0 Reserved
0x7F NA 7:0 FPGA Revision
  1. 1.00 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21 1.22 1.23 MUST be written before bits 7:0
  2. 2.00 2.01 2.02 2.03 2.04 2.05 2.06 2.07 2.08 2.09 2.10 2.11 2.12 2.13 2.14 Value of counter #0 must be set to count to the mid-point of the stop bit based on a 25MHz clock
  3. 3.00 3.01 3.02 3.03 3.04 3.05 3.06 3.07 3.08 3.09 3.10 3.11 3.12 3.13 3.14 Value of counter #1 must be set to count to one-half bit time based on a 25MHz clock

7.19 Temperature Sensor

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

tshwctl --rtcinfo
tshwctl --cputemp

These commands will return the temperature of the RTC or internal CPU die temperature. Note that the --rtcinfo option will also return other information, See the Battery Backed RTC and Temperature Sensor section for more information.

7.20 UARTs

The TS-7680 offers 4 UARTs

Name Type TX/+ RX/-
ttySP0 RS-232 J4_6 J4_5
ttySP1 RS-232 J4_8 J4_7
ttySP2 RS-485 J6_4 J6_5
ttySP3 RS-485 P1T_2 P1T_3

Currently it is necessary to run the following command to load the UART driver for the CPU UARTs.

modprobe mxs_auart

This will be auto-loaded in future images.

7.20.1 RS-485

The TS-7680 offers two RS-485 ports, these ports are on CPU UART 2 and 3. RS-485 half-duplex control is managed by the FPGA using two sets of registers per port to control the TXEN line. In order to set up the auto-HD registers of the FPGA, the following commands must be issued before the TXEN will function properly:

tshwctl --485_0speed=<baud>
tshwctl --485_1speed=<baud>

Like with any standard UART, the baud rate can be changed at any time. However if the baud rate is changed, the control registers must be updated as well to ensure that the TXEN pin is correctly handled for RS-485.

7.21 USB

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. For creating custom USB support, libusb may be the easiest route.

USB 5V Power can be disabled or re-enabled using DIO 69, marked EN_USB_5V on the schematic. See the syscon for more information on using this bit.

See the WIFI-N-USB manual for information on our WIFI support.

7.22 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.

The watchdog is implemented in the microcontroller that is on this SBC alongside the CPU. This means that a completely separate device is responsible for the sanity of the CPU. The WDT has 100ms resolution, and can be fed for a length of time up to 6553.5s, which is 1h 49m 13s 500ms. Writing a 0, 1, 2, or 3 to the WDT has a special meaning that corresponds with our traditional WDT feed scheme:

Value Result
0 feed watchdog for .3s
1 feed watchdog for 2.7s
2 feed watchdog for 10.8s
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 */

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();

7.23 Wi-Fi

This SBC includes a TiWi-BLE SDIO module that uses the Texas Instruments WL1271L Transceiver. Linux provides support for this using the wl12xx driver. See the LSR site for detailed product information.

Summary Features:

  • IEEE 802.11 b/g/n
  • 2.4GHz
  • Linux drivers include support for client and AP mode
  • Industrial temp, -40 to 85C
  • Certifications
    • FCC Bluetooth® Grant
    • FCC WLAN Grant
    • IC
    • CE
    • SAR Testing
    • SAR Testing EU

Linux uses the "wireless-tools", "wpa-supplicant", and "hostapd" packages to support most of the functionality in this module. Refer to the distribution support for more information.

8 External Interfaces

8.1 HD1 Pin Header

Pin Name
HD1_2 POE_78
HD1_4 POE_45
HD1_7 DIO 1_9
HD1_9 DIO 1_8
HD1_10 UART4 RX [1]
HD1_11 USB OTG -
HD1_13 USB OTG +
HD1_14 DIO 1_7
HD1_15 5 V
HD1_16 5 V
Pin Layout
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
  1. 5V tolerant input

8.2 HD4 Pin Header

Pin Name
HD4_1 DAC_2
HD4_2 DAC_3
HD4_3 DAC_1
HD4_4 AN5 / CAN0_H
HD4_5 DAC_0
HD4_6 AN4 / CAN0_L
HD4_7 DIO 3 [1]
HD4_8 AN3
HD4_9 DIO 2
HD4_10 AN2
HD4_11 DIO 1
HD4_12 AN1
HD4_13 DIO 0
HD4_14 AN0
HD4_15 Relay 1 NO
HD4_16 CAN0 TX
HD4_17 Relay 1 NC
HD4_18 CAN0 RX [1]
HD4_19 Relay 1 Common
HD4_20 3.3 V
HD4_21 DIO 21
HD4_22 250 kHz Phase 0
HD4_23 DIO 23
HD4_24 250 kHz Phase 1
HD4_25 DIO 25
HD4_26 DIO 26
HD4_27 DIO 27
HD4_28 DIO 28
HD4_29 DIO 29
HD4_30 DIO 30
HD4_31 DIO 31
HD4_32 DIO 32
HD4_33 DIO 33
HD4_34 DIO 34
HD4_35 DIO 35
HD4_36 5 V
HD4_37 GND
HD4_38 VIN
Pin Layout
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
23 24
25 26
27 28
29 30
31 32
33 34
35 36
37 38
  1. 1.0 1.1 5V tolerant input

8.3 24 pos. Screw Terminal


Pin Name
T_2 RS-485 +
T_3 RS-485 -
T_4 DIO 0
T_5 DIO 1
T_6 DIO 2
T_7 Relay 1 NO
T_8 Relay 1 Common
T_9 Relay 1 NC
T_10 Relay 2 NO
T_11 Relay 2 Common
T_12 Relay 2 NC
Pin Name
B_2 AN0
B_3 AN1
B_4 AN2
B_5 AN3
B_6 AN4 / CAN0_L
B_7 AN5 / CAN0_H
B_8 DIO 3
B_9 DAC_0
B_10 DAC_1
B_11 DAC_2
B_12 DAC_3

8.4 J4 RJ-45

Pin Name
J4_1 CAN1_H
J4_2 CAN1_L
J4_3 GND
J4_4 GND

8.5 J6 RJ-45

Pin Name
J6_1 GND
J6_2 GND
J6_3 GND
J6_4 RS-485 +
J6_5 RS-485 -
J6_6 MODBUS Power
J6_7 MODBUS Power
J6_8 GND

9 Revisions and Changes

9.1 Microcontroller Changelog

Revision Changelog
  • Initial release
  • Read VIN to turn on CPU at 7.5V and turn off at 7V
  • Bugfix where ADC was being overdriven, resulting in improper results
  • Disabled WDT on bootup, needed for U-Boot at this time.

9.2 FPGA Changelog

Revision Changelog
  • Initial release, contains no revision register
  • Fixed pinmaps to match TS-7680 rev A PCB
  • Set up revision register at 0x3f
  • Put bt_en on its own bit
  • set wl_en and bt_en to always drive high
  • Implemented fpga_spare_0_pad as global reset pin
  • Default to turn on bt_en and wl_en
  • Set bt_en and wl_en to be controlled via register
  • Reworked 485 input pins to use proper CPU UARTs
  • Inverted PWM output to set 0x0 to 0v
  • Inverted EN_PU_ADC polarity so 1 == enabled
  • Fixed race condition with auto485 TXEN logic
  • Cleaned up possible metastability issue on input signal
  • Added reset logic for PWM and auto485 blocks
  • Change wl_en and bt_en registers to match the GPIO registers with bit 1 as the actual enable bit

9.3 PCB Revisions

Revision Changelog
  • Initial release

9.4 Software Images

Image File Changelog Known Issues


  • First official Engineering sample image release
  • WiFi interface cannot be brought down and back up again successfully. Does not affect normal behavior as a station, does break master mode however.
  • U-Boot expects environment to always be on SD card, whether booted from SD or NAND.
  • NAND images cannot be written from U-Boot, must be written from initramfs/Debian.
  • VLAN support is not enabled in kernel.
  • Extra user account support/support exists on the system and may pose a security risk.
  • Deprecated, we strongly recommend against using this image


  • Kernel is now 3.14
  • WiFi Device fully working
  • NAND does not function due to an issue with UBIFS
  • Integrated Bluetooth not functional
  • 3.14 breaks standby mode of the CPU
  • Deprecated, we strongly recommend against using this image
  • BT fully working
  • Software updates to support hardware changes
  • Fixed up FPGA GPIO expander driver (tsgpio) to be more generic and support multiple modes
  • Set up pwm-clk driver to run PWM to FPGA for FPGA clock
  • Set up default VLAN mode for ethernet switch
  • Added netfilter modules to defconfig
  • Patch in proper support for mmc name aliasing
  • Pull cmdline from U-Boot, and fallback to kernel built-in
  • Switch starts up in switch mode, should default to VLAN
  • Both VLAN ports use the same MAC
  • Deprecated, we strongly recommend against using this image
  • Patch in proper support for mmc name aliasing
  • Pull cmdline from U-Boot, and fallback to kernel built-in
  • Both VLAN ports use the same MAC
  • Deprecated, we strongly recommend against using this image


  • Changeover to Debian Jessie
  • Removed dependency on initramfs
  • Simplified and separated out functions in tshwctl
  • Added WDT kernel driver to support WDT in microcontroller
  • Enable UART4
  • Disable restart of PWM core on linux start
  • Switch VLAN mode can be configured via kernel command line
  • MAC addresses for VLAN mode are completely random
  • Short VLAN frames when the switch is in VLAN mode do not properly get passed through


  • VLAN MAC addresses are now correct TS assigned MAC addresses
  • Added tssupercapmon script and systemd service. Automatically shut down system safely if power is removed
  • Added DAC commands
  • Added tsmicroctl tool to image
  • /etc/shadow is world readable
  • Short VLAN frames when the switch is in VLAN mode do not properly get passed through
  • GPIO driver via linux sysfs has race condition when changing state and direction at the same time


  • Proper permissions set on /etc/shadow
  • Added support for MMA8451 accelerometer
  • Added support for FTDI and CP210x USB serial adapters
  • Add support for any future eMMC revision changes
  • GPIO driver via linux sysfs has race condition when changing state and direction at the same time (intentionally not updated for this release, may cause unexpected behavior change of stock image)
  • Short VLAN frames when the switch is in VLAN mode do not properly get passed through (intentionally not updated for this release, may cause unexpected behavior change of stock image)

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.

WARNING: Writing ANY of the CPU's One-Time Programmable registers will immediately void ALL of our return policies and replacement warranties. This includes but is not limited to: the 45-day full money back evaluation period; any returns outside of the 45-day evaluation period; warranty returns within the 1 year warranty period that would require SBC replacement. Our 1 year limited warranty still applies, however it is at our discretion to decide if the SBC can be repaired, no warranty replacements will be provided if the OTP registers have been written.