From embeddedTS Manuals
WARNING: This document has changed!!! This product is about to exit the Engineering Sampling program. This means the documentation and product itself have changed several times since the product was introduced. Please force-refresh (shift-f5 on most browsers) to clear your cache when visiting this page to ensure you are viewing the most recent version of this documentation. Of course also please check back often as this information is subject to change as we prepare the product for mass availability.
Product Page
Product Images
Mechanical Drawing
FTP Path
Marvell MV88F6820
Armada 385 Arm® Cortex®-A9 1.3 GHz 32-bit Dual Core CPU


The TS-7800-V2 is a Single Board Computer (SBC) based on a Marvell MV88F6820 1.3GHz Cortex-A9 (ARMv7 architecture) Dual Core CPU. The CPU features a set of high-end peripherals such as a 10/100/1000 Ethernet, mSATA, dual USB 3.0, eMMC for onboard storage, and more. This device features WIFI, Bluetooth, an accelerometer, and an FPGA allowing more DIO, UARTs, and an ISA bus to implement additional IO.

This SBC provides a migration path for customers using TS-7800 in their products. Electrically and mechanically this board is almost identical to the original TS-7800. Be sure to see our guide on migrating from TS-7800 original to the TS-7800-V2 for more information.

Getting Started

A Linux PC is recommended for development. For developers who use Windows, virtualized Linux using VMWare or similar are recommended in order to make the full power of Linux available. The developer will need to be comfortable with Linux anyway in order to work with embedded Linux on the target platform. The main reasons that Linux is useful are:

  • Linux filesystems on the microSD card can be accessed on the PC.
  • More ARM cross-compilers are available.
  • If recovery is needed, a bootable medium can be written.
  • A network filesystem can be served.
  • Builds such as Linux kernel, buildroot, yocto, distro-seed will not work from WSL1/2 on a case insensitive filesystem.
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.

First Linux Boot

Powering Up

5 Volts DC


The TS-7800-V2 has one primary power input location: The +5 Volt input located at CN4, immediately "behind" the DB9/DE9 serial port connector at the edge of the PCB. CN4 is populated with a screw terminal connector similar to the OSTTH020100 from On Shore Technology. This connector can be pulled off the SBC to reveal two relatively sharp connector posts. The default configuration out of the box has the screw terminal connector installed, however some shipping requests and situational events may have the SBC ship missing this connector. Check with your purchasing agent or contact the Technologic Sales Team (sales@embeddedTS.com) if the presence, or absence, of this connector is unexpected.

For most situations, power the SBC by connecting +5 Volts DC from a power supply rated for at least 12 watts with a fast slew rate. The positive and GND terminals are labeled under the connector, with the +5 V terminal being located closest to the DB9 connector. Specific applications may need more wattage depending on the final design specification.

Note: If custom wiring power to the screw terminal, pay VERY CAREFUL attention to the polarity of the connection. There is NO reverse-polarity protection. The positive side is the side closest to the DB9 connector, it is also noted on the PCB silk screen underneath the screw terminal connector, visible when the screw terminal plastic is pulled off.

8-28 Volts DC

Some TS-7800-V2 models include a TS-781 power regulation card. These SBCs are sold under part numbers that include a -PS appended (for example TS-7800-V2-DMW2I-PS). On these specific SBCs, there are two places to provide power to the SBC. Note that only *ONE* of these power receptacles should be used at any time. Either the +5 V screw terminal connector covered above, OR the screw terminal connector provided by the TS-781 daughter card. If using the TS-781, the power supply connected to it should provide between 8 and 30 volts DC, with a minimum rating of 12 watts for best compatibility. The +5V connector should never be used when using the TS-781's power connector to power the SBC.

TS-781 Polarity Diagram.svg

On the TS-782 power regulation board, the positive terminal is on the left hand side when facing the connector end and the coil is on the top far right corner.

Connect to the Console

Set the "EN Con" jumper, and use a null modem cable to connect the board's DB-9 connector to your workstation's COM port. Alternatively, connect a micro USB Type B cable to CN12, with the other end going to a USB port on a workstation.

DB9 The DB9 console port comprises of RS232 serial communication at 115200 baud, no parity, 8 data bits, 1 stop bit, no handshaking, no flow control.

Micro USB The Micro USB type B port hosts a USB virtual serial port on the managing microcontroller. Some users may require the OS-appropriate driver provided by SiLabs found here: https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers The TS-7800-V2 will respond over the virtual serial port at 115200 baud, no parity, 8 data bits, 1 stop bit, no handshake.

Note: Some terminal software will default to software flow control XON/XOFF. This setting is not compatible with the TS-7800-V2. Be sure to turn off both hardware flow control and software flow control (sometimes called "handshake") when configuring the console interface for the TS-7800-V2.

Console from Linux

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

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

Picocom is a very small and simple client.

picocom -b 115200 /dev/ttyUSB0

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

screen /dev/ttyUSB0 115200

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

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

Console from Windows

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

Device Manager Putty Configuration Putty Configuration B

The TS-7800-V2 receives power through the +5VDC power connector with a 2A recommended minimum supply. Once power is applied, the device will output information via the console. The first output is from U-Boot:

U-Boot SPL 2017.09-g2113ce6a21 (Mar 06 2018 - 16:20:06)
Detected Device ID 6820 (SAR1 0xCB00230D)
mv_ddr: mv_ddr-armada-17.10.3-g2113ce6a21 (Mar 06 2018 - 16:20:23)
DDR3 Training Sequence - Switching XBAR Window to FastPath Window
mv_ddr: completed successfully
Trying to boot from MMC1
force part -> 1

U-Boot 2017.09-g2113ce6a21 (Mar 06 2018 - 16:20:06 -0700)

SoC:   MV88F6820-A0 at 1332 MHz
I2C:   ready
DRAM:  1 GiB (666 MHz, ECC not enabled)
MMC:   mv_sdh: 0
*** Warning - bad CRC, using default environment

  00:01.0     - 1204:0001 - Does not fit any class
Model: Technologic Systems TS-7800-V2
Found FPGA at 00.01.00
Bootflags: WDOG+ ECC- PCIE- MSATA+
SATA link 0 timeout.
SATA link 1 timeout.
AHCI 0001.0000 32 slots 2 ports 6 Gbps 0x3 impl SATA mode
flags: 64bit ncq led only pmp fbss pio slum part sxs
Net:   eth0: ethernet@70000
Press ESC twice to abort autoboot in 0 second(s)
Booting from the eMMC ...
** File not found /boot/boot.ub **
18642 bytes read in 145 ms (125 KiB/s)
4796480 bytes read in 937 ms (4.9 MiB/s)
## Flattened Device Tree blob at 00100000
   Booting using the fdt blob at 0x100000
   Loading Device Tree to 0fff8000, end 0ffff8d1 ... OK

Starting kernel ...

Note the message "*** Warning - bad CRC, using default environment" is expected unless there is a custom u-Boot configuration present. For more information on loading custom u-Boot configurations please see the Custom U-boot section.

The "SD Boot" jumper, when set, will cause U-Boot to load the kernel from eMMC and then boot to SD, and when unset, U-Boot will load the kernel from eMMC and boot to eMMC.

Note: The "*** Warning - bad CRC, using default environment" can be safely ignored. This indicates that u-boot scripts are not being customized. Typing "env save" will hide these messages, but this is not needed.

U-Boot Environment

The U-Boot environment on the TS-7800-V2 is stored in the on-board eMMC flash.

# 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

U-Boot Commands

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

# Boots into the compressed binary at $loadaddr.  
# Boots into the compressed binary at $loadaddr, specifies the fdtaddr 
# so Linux knows where to find the board device-tree
bootz ${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 used for scripting:
false # do nothing, unsuccessfully
true # do nothing, successfully

# This command lets you set fuses in the processor
# Setting fuses can brick your board, will void your warranty,
# and should not be done in most cases

# This command is used to copy a file from most devices
# Load kernel from SD
ext4load mmc 1:2 ${loadaddr} /boot/zImage
# Load Kernel from eMMC
ext4load mmc 0:2 ${loadaddr} /boot/zImage

# You can view the fdt from u-boot with fdt
ext4load mmc 0:2 $fdtaddr /boot/armada-38x.dtb
fdt addr ${fdtaddr}
fdt print

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

# Browse fat,ext2,ext3,or ext4 filesystems:
ext4ls mmc 0:1 /

# Access memory like devmem in Linux, you can read/write arbitrary memory
# using mw and md
# write
mw 0x10000000 0xc0ffee00 1
# read
md 0x10000000 1

# Test memory.

# Check for new SD card
mmc rescan
# Read SD card size
mmc dev 1
# Read eMMC Size
mmc dev 0

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

# Test ICMP

# Reboot

# Delay in seconds
sleep 10

# You can load HUSH scripts that have been created with mkimage
ext4load mmc 0:1 ${loadaddr} /boot/ubootscript
source ${loadaddr}

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

# Commands can be timed with "time"
time bdinfo

# Print U-boot version/build information

Updating U-Boot

There is a very small possibility that during development it becomes necessary to update the U-Boot binary, either due to a published bug fix or very low-level implementation by the down-stream developer. The U-Boot binary resides in a read-only protected portion of the eMMC device on the TS-7800-V2. To write a new U-Boot binary, this part of the chip must be write-enabled in Linux.

echo 0 > /sys/block/mmcblk0boot0/force_ro
dd if=u-boot-spl.kwb of=/dev/mmcblk0boot0
echo 1 > /sys/block/mmcblk0boot0/force_ro

WARNING: If this process fails, DO NOT REBOOT. If the mmcblk0boot0 partition does not contain a valid u-boot binary during boot, the SBC will fail to boot. This means it is VERY possible to brick the SBC in the attempt to update U-Boot. Technologic Systems strongly advises this activity should only be undertaken if there is no other means of achieving a needed functionality.

Modify Linux Kernel cmdline

The Linux kernel cmdline can be customized by modifying the cmdline_append variable. The variable contents are clobbered when set, so be sure to specify the full desired cmdline string.

env set cmdline_append console=ttyS0,115200 init=/sbin/init quiet
env save

The kernel command line can also be modified from from the on-board Linux. Debian (and other distributions) provide a U-Boot utilities package that contains the tools necessary to create a U-Boot script:

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

The boot.scr includes the plain text commands to be run in U-Boot on startup. The mkimage tool adds a checksum and header to this file which can be loaded by U-Boot. The .ub file should not be edited directly.

Boot Paradigms

U-Boot is always loaded from the onboard eMMC boot partitions (/dev/mmcblk0boot*). U-boot can access the eMMC, SATA, Network, and USB. By default it will load Linux from the first partition on the eMMC, but it can be configured to boot to SATA, USB, or Network by default. When the U-Boot jumper is present the board will attempt to boot to USB for our #Production Mechanism.

The eMMC and SD cards shipped with the unit are pre-programmed with our Debian Stretch image.

Booting to U-Boot

The U-Boot bootloader resides in a special, protected, part of the eMMC chip that is normally read-only to the operating system. When the SBC is powered on, the processor will load u-boot from this protected eMMC section and launch into U-Boot execution. If the physical jumper labeled U-Boot is installed (with no bootable USB media present), the SBC will then stop at the U-Boot shell and await further user interaction.

Booting From USB

With the U-Boot jumper installed, the SBC will automatically look for bootable media on USB and attempt to boot that media. If no bootable USB media is present, the SBC will drop to the U-Boot prompt and await further instruction via the console.

Booting From eMMC

Without the "SD Boot" jumper, the default U-Boot behavior will attempt to mount and load the kernel from the first available regular partition on eMMC. The kernel will then load essential driver functionality, properly mount necessary filesystems, and begin execution of the Debian environment.

Booting From SD

With the "SD Boot" jumper populated, the default U-Boot behavior attempt to mount and load the kernel from the first available regular partition on the SD media. The kernel will then load essential driver functionality, properly mount necessary filesystems, and begin execution of the Debian environment.

Changing Boot Paradigm / Booting from SATA

The TS-7800-V2 can automatically boot from any recognized bootable media. The default TS-7800-V2 U-Boot environment provides for automatic booting from USB, SD, and eMMC. The downstream developer may alternatively choose to boot from SATA or network. The pre-defined boot scripts in U-Boot include:


Any of these commands can be swapped for another in the bootcmd script. Editing the bootcmd script is the same procedure as modifying the kernel command line:

setenv bootcmd 'if test ${jpsdboot} = ' \''on'\' '; then run sataboot; else run emmcboot; fi;'
env save

If the ability to change boot modes based on the SDBOOT jumper is not needed, the above script can be simplified significantly:

setenv bootcmd run sataboot;
env save

Jumper Configuration

Jumper Function
SD Boot Boot to SD if populated, otherwise boot to eMMC.
EN Console Enables the console, when populated, ttts9 is TTL on PC104 pins 14 and 15. When depopulated, ttts9 is on DB9 pins 2 and 3, replacing console RS232.
U Boot Boots to USB if present (see Production Mechanism). Stops boot in u-boot rather than booting to the disk image if no USB present.

Boot Flags

Some features of the board can only be configured in early boot. These behaviors can be changed from Linux using the ts7800ctl.

Boot flags byte
Bit Description
7 Reserved
6 1 = Enable ECC and only use one chip

0 = Use both chips as RAM

5:1 Reserved
0 1 = Enable watchdog by default

0 = Disable watchdog

Bit 6 controls whether ECC is enabled or not. The default builds of the TS-7800-V2 use two 512MB DDR3 chips, and ECC is enabled by dedicating one of those chips to ECC. This will split the usable RAM in half, but allow auto correction of single bit errors, or detection of double bit errors.

Bit 0 allows disabling the watchdog right out of reset. This only enables whether it is enabled on power on, but the default u-boot will start feeding the watchdog as soon as it starts. To completely disable the watchdog later software would need to not feed the watchdog, or stop feeding and send a byte to turn off the watchdog. See the #Watchdog section for more information.

On startup u-boot will print out: Model: Technologic Systems TS-7800-V2

 Bootflags: WDOG+ ECC- PCIE- MSATA+
 SATA link 0 timeout.

This bootflags shows which boot flags are enabled/disabled. To modify these, use ts7800ctl from Linux.

# Default boot strapping.  Disables ECC, enables mSATA and WDOG
ts7800ctl -A 7 -D 0x1

# Enable ECC, enable mSATA and WDOG
ts7800ctl -A 7 -D 0x41

# Disable ECC, Enable PCIe and WDOG
ts7800ctl -A 7 -D 0x81


The ts7800ctl utility allows the downstream developer access to core functionalities in the microcontroller, FPGA, CPU, and other hardware features of the TS-7800-V2 not specifically supported by other common Linux software.

Usage: ts7800ctl [OPTION] ...
Examine/Modify state of TS-7800-V2 hardware.

General options:
  -s    seconds         Number of seconds to sleep for
  -r    CHANS           Sample ADC channels CHANS, e.g. "0-2,4", "1,3,4"output raw data to standard out
  -S    CHANS           Sample ADC channels CHANS, e.g. "0-2,4", "1,3,4"output string parseable data to standard out
  -n                    Red LED on
  -F                    Red LED off
  -g                    Green LED on
  -G                    Green LED off
  -i                    Display board info
  -o                    Display one time programmable data
  -m                    Display contents of non-volatile memory
  -a[N]                 Display accelerometer data, loop N times (0=forever)
  -t                    Display board temperature
  -A    ADDR            Write DATA to ADDR in non-volatile memory
  -D    DATA            Write DATA to ADDR in non-volatile memory
  -M[xx:xx:xx:xx:xx:xx] Display [or optionally set] the MAC address
  -O                    Display odometer(hrs board has been running for)
  -l   RATE             Set CPU clock rate, or if no argument lists possible rates (max default)
  -c   CORES            Set 1/2 Cores (max default)
  -V                    Verbose output

Running ts7800ctl -i will output useful status information about the current running state of the TS-7800-V2. The output will be in this format:



The TS-7800-V2 can enter a very low-power sleep state to assist in power management. This state effectively will power the main components (CPU, RAM, storage, peripherals, etc.) completely off, leaving just a low-power management chip counting an internal timer while waiting for the power-up signal. Power drawn while in this state is documented here. Sleep is a timed function of the management IC. When used, the sleep command is given a number of seconds to hold the device in low-power mode before causing it to boot again. This is the default functionality. This timer can be interrupted at any time by pulling either DIO_04 or ISA_B32 to 3.3 V for 100 milliseconds.

Note: Issuance of the sleep command is the equivalent of an immediate power loss. Doing this during otherwise normal operation can cause filesystem corruption and data loss. It is advised to properly perform Linux shutdown tasks, or at least remount all write-able media into a read-only state before issuing the sleep command.

Backup / Restore

While all of our products ship with images pre-loaded in to any supplied media, there are many situations where new images may need to be written. For example, to restore a device to its factory settings or apply a customized image/filesytem for application deployment. Additionally, specific units may be used for development and that unit's disk images need to be replicated to other units to be deployed in the field.

We offer a number of different ways to accomplish both capturing images to be written to other units, and the actual writing process itself. See the sections below for details on our USB Image Replicator tool to capture and/or write images, as well as details on manual processes to capture and write images on each of this device's media.

Image Replicator

This platform supports our Image Replicator tool. The Image Replicator tool is intended for use by developers as a means to write bootable images or filesystems on to a device's media (SD / eMMC / SATA / etc.) as part of their production or preparation process. In addition to writing media, the Image Replicator tool is capable of capturing images from a device's media and preparing them to be written to other devices.

The Image Replicator tool is a USB disk image that can be booted on a target device to capture or write its media directly without the need for a host workstation. The USB disk image is based on Buildroot and contains a set of scripts which handle the capture and write process. The process and its scripts are flexible and can be used as-is or adapted in to larger production processes to format and load data on to devices. The single USB drive can be used to capture images from a device, and then can be inserted in to other devices to write those same images on to other devices. The capture process is not necessary if it is not needed. Images for the target device can be copied to the USB drive, booted on compatible units, and have the target images written to that unit's media.

Image Capture Process

The image capture process performs the following steps. For more detailed information, see the Image Capture section below.

  1. If no valid images exist on the disk, image capture starts.
  2. For each valid media present on the unit, a bit for bit copy of the source is made.
  3. This image is mounted, sanitized (to remove unneeded files and allow safe copying of the image to other units), and saved as either a disk image or a tarball depending on the partition layout of the source disk.
  4. All images and tarballs are compressed, with both the output files having their MD5 hash saved as well as all of the files contained in the root partition having their MD5 hashes saved to a file for later verification.

The captured images and tarballs are named such that the USB Image Replicator disk can be immediately used to boot another unit and have it perform the Image Write process to write that unit's media with the captured images.

Note: When using this process, the USB drive used for the Image Replicator must be sized large enough to handle multiple compressed images as well as the uncompressed copy of the media image actively being worked with. If the image capture process runs out of space, the process will indicate a failure.

Image Write Process

The image write process performs the following steps. For more details information see the Image Write section below.

  1. For each valid media present on the unit, find the first valid source image file for it.
  2. If a source image exists for a media that is not present on the unit, then the process indicates a failure.
  3. If the source image is a tarball, format the target disk with an appropriate filesystem, and unpack it to the target disk, verifying all files against the MD5 hash file list after they are written.
  4. If the source image is a disk image, write that to the target disk. If an MD5 file for the disk image exists, read back the written disk and compare it to the hash.

Creating a USB Image Replicator Disk

Image Replicator USB disk images can be found below:

Disk image: ts7800v2-usb-image-replicator.dd.xz

Tarball: ts7800v2-usb-image-replicator-rootfs.tar.xz

Two types of USB Image Replicator images are available for this platform, a tarball and an actual disk image. They both have the same contents and are intended to provide different methods to write the Image Replicator tool to a USB disk.

Disk Image (.dd.xz)
The disk image is easier to write from different workstation OSs, will auto-expand to the full disk length on its first boot, and is intended to be used for image capture (and later image writing) due to its small size and auto-expansion process. We recommend this route for users who may not have access to a Linux workstation or need to capture images from a golden unit first.
Tarball Image (.tar.xz)
The tarball image is easiest to write from a Linux workstation, but requires creating a partition table on the USB disk (if one does not already exist), formatting the filesystem, and unpacking the tarball. It can readily be used for for both image capture and writing, but is the easiest route when image capture is not needed due to the auto-expansion process.

Note: It is recommended to use USB drives with solid-state media for this process. Slower USB drives, especially those with spinning media, may take too long to enumerate and the bootloader will not boot the Image Replicator disk. Additionally, the use of low quality, damaged, and/or worn out USB drives may cause unexpected errors that appear unrelated to the USB drive itself. If there are issues using the Image Replicator, we recommend first trying a new, fresh, high-quality USB drive from a trusted named brand.

Disk Image

This process uses a small disk image that can be written to a USB device. This disk image uses an ext3 filesystem which expands on its first boot to the full length of the disk before beginning the image capture process. This disk is recommended for users who may not have access to a Linux workstation or who need to capture images from a golden unit.

It is possible to use the disk image for just image writing, however, in order to ensure full disk space is available it is recommended to write the disk image to a USB drive, boot it on a unit, let the image capture process complete, insert the USB drive in to a workstation, and then remove the captured image files before copying in the desired image files for the target unit from the workstation.

Writing Disk Image From a Linux Workstation

The disk image can be written via the command line with the dd command (replace /dev/sdX with the correct USB device node):

xzcat <platform>-usb-image-replicator.dd.xz | dd of=/dev/sdX bs=1M conv=fsync

Graphical tools also exist for this purpose, for example balenaEtcher[1] offers this functionality.

Writing Disk Image From a Windows Workstation

A number of tools exist for writing an image to a USB drive, including (but not limited to) balenaEtcher[1] and Win32DiskImager[2]

Writing Disk Image From a MacOS Workstation

We recommend using a tool such as balenaEtcher[1] to write disk images.

  1. 1.0 1.1 1.2 embeddedTS is not affiliated with this tool. balenaEtcher version 1.5.101 tested in Windows 10 on 20220216
  2. embeddedTS is not affiliated with this tool. Win32DiskImager 1.0.0 tested in Windows 10 on 20220216. Cannot handle compressed images, must first decompress disk image.


This process is easiest on a Linux workstation, but can be performs on other operating systems as well so long as they can support a compatible filesystem, the xz compression algorithm, as well as the tarball archive format. Note that in many cases, one of our computing platforms running our stock Linux image can be used if a Linux workstation is not available. After writing the tarball to a USB disk, the full length of the USB disk would be available to copy source images to in order to write them to other units.

The image replicator and scripts require a minimum of 50 MB; this plus the size of any target disk images or tarballs to be used dictates the minimum USB disk size required. The USB drive should have only a single partition, which is formatted ext2[1] / 3 / 4[2] or FAT32/vfat[3] Note that other filesystems are not compatible with U-Boot and therefore cannot be used.

Writing Tarball From a Linux Workstation

# This assumes USB drive is /dev/sdc:
sudo mkfs.ext3 /dev/sdc1
sudo mkdir /mnt/usb/
sudo mount /dev/sdc1 /mnt/usb/
sudo tar --numeric-owner -xf /path/to/<platform>-usb-image-replicator-rootfs.tar.xz -C /mnt/usb/
sudo umount /mnt/usb/

Writing Tarball From a Windows Workstation

It is recommended to use a third party tool, as native Windows archive tools have been observed to not work correctly. Tools such as 7-Zip[4] or PeaZip[5] are known working. It may also be possible to use Windows Subsystem for Linux following the Linux Workstation instructions above, but this has not been tested.

Note that some Windows tools may attempt to use the whole disk, rather than create a partition table. A partition table with a single partition is required for U-Boot support.

With a formatted USB disk, the archive can be unpacked to the root folder of the USB disk. Be sure to not unpack the tarball contents in to a new folder on the drive as this will not be bootable.

  1. The ext2 filesystem has a max file size limit as low at 16 GiB. This may cause issues for Image Capture.
  2. Use of ext4 may require additional options. U-Boot on some platforms does not support the 64-bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options -O ^64bit,^metadata_csum may need to be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed, nor are they needed for ext2 / 3.
  3. The FAT32 (supported by vfat in Linux) filesystem has a max file size limit of 4 GiB. This may cause issues for Image Capture.
  4. embeddedTS is not affiliated with this tool. 7-Zip 21.07 tested in Windows 10 on 20220222
  5. embeddedTS is not affiliated with this tool. PeaZip 7.2.0 tested in Windows 10 on 20220222

Running the Image Replicator Tool

U-Boot on the TS-7800-V2 will attempt to boot from an attached USB disk if the U-Boot jumper is set. This is the mechanism to boot either of the two disk images on the TS-7800-V2.

Once a USB drive is formatted with the Image Replicator tool (see Creating a USB Image Replicator Disk for the correct files and process), boot to this USB drive (note that the Image Replicator already sets up the correct U-Boot boot scripts to boot to the USB drive, see the aforementioned section for details on how to make U-Boot call the scripts on the USB drive). This will start either image capture if no disk images/tarballs are present on the USB drive, or image write if there are disk images/tarballs present on the USB drive.

The Image Replicator tool, while in progress, will flash the green LED once per second while the red LED remains solidly lit. Upon completion, the red LED turns off and the green LED will slowly blink to indicate success, while a blinking red LED with the green LED off indicates a failure.

On each boot, startup scripts will check if the single partition of the USB drive can be expanded and do so if possible. If this process fails, then any further operations will not be run and the LEDs will blink to indicate a failure.

Image Capture

If no valid images to write exist on the booted USB Image Replicator drive, the image capture process starts automatically.

Note that while in progress, the USB Image Replicator drive is mounted read-write. It is not advised to remove power or disconnect the USB Image Replicator drive until the whole process has completed.

To help diagnose failures, files in /tmp/logs/ contain output from each capture process.

For each media present on the unit (SD / eMMC / SATA / etc.), the image capture process will do the following:

  1. Copy the entire media image to an appropriately named file on the USB Image Replicator drive, e.g. sdimage.dd. No data is written to the source media and it is never mounted. The source disk can follow the stock partition layout, or implement a customized one.
  2. Perform an fsck on the Linux rootfs partition in the image file. Note that, if deviating from the standard partition layout, it may be necessary to modify the scripts handling the capture process.
  3. Mount the Linux rootfs partition from the image file and sanitize the filesystem. The sanitization process removes temporary files (e.g. /log/ files), unique files (e.g. ssh private key files, machine ID files), adds a file to indicate that it is a custom image with the date as its contents, etc. The full list of operations can be found in this script. It may be necessary to modify this file for unique situations.
  4. If the media's partition layout uses only a single partition, the filesystem is packed in to a tarball on the USB Image Replicator drive which is appropriately named and compressed, e.g. sdimage.tar.xz. The image file is then unmounted and removed from the USB Image Replicator drive.
  5. If the media's partition layout uses multiple partitions, the image file is then unmounted, an md5sum of the image file taken, it is compressed and appropriately named on the USB Image Replicator drive, e.g. emmcimage.dd.xz, and then an md5sum of the compressed image is taken.

Note that when using this process, the USB Image Replicator drive that is used must be sized large enough to handle multiple compressed images as well as the uncompressed copy of the media image actively being worked with. If the image capture process runs out of space, the process will indicate a failure via the LEDs.

The images files captured are saved to the root folder of the USB Image Replicator drive. Upon completion, it is safe to remove power or unplug the USB drive.

For more details on the image capture process, see this script.

Image Write

This process is used to write existing images to media on a target unit. If appropriately named disk images or tarballs (see table below) are present in the root folder of the USB Image Replicator drive when booted, then the startup scripts will start the image writing process. The latest disk images we provide for our platforms can be downloaded from our FTP site, see the backup and restore section for links to these files.

Note that the USB Image Replicator drive remains read-only through the entire process but target devices may be mounted or actively written. It is not advised to remove power or disconnect the USB Image Replicator drive until the whole process has completed.

To help diagnose failures, files in /tmp/logs/ contain output from each writing process.

The Image Replicator script expects disk images or tarballs to have specific names to match the target media. The script will attempt to match tarball and then disk image names (in the order they are listed in the table below) for each target media, using the first file that is found to write to the target media. Note that symlinks can be used on the USB Image Replicator disk if formatted with a filesystem that supports symlinks. This can be used, for example, to write the same tarball to both SD and eMMC from only a single copy of the source tarball.

Upon completion, it is safe to remove power or unplug the USB drive.

For more details on the image write process, see this script.

The following table is the list of valid file names and how they are processed:

Target media Accepted filenames Description
SD Card

/sdimage.tar.xz /sdimage.tar.bz2 /sdimage.tar.gz /sdimage.tar

Tar of the filesystem. This will repartition the SD card to a single partition and extract this tarball to the filesystem. If present, a file named /md5sums.txt in the tarball will have its contents checked against the whole filesystem after the tarball is extracted. This md5sums.txt file is optional and can be omitted, but it must not be blank if present. This file is present in our official images and is created during image capture with the Image Replicator tool.

/sdimage.dd.xz /sdimage.dd.bz2 /sdimage.dd.gz /sdimage.dd

Disk image of the media. This will be written to the SD card block device directly. If present on the USB Image Replicator drive, a file named /sdimage.dd.md5 will be used to verify the data written to the SD card against this checksum. This file is provided with our official images and is created during image capture with the Image Replicator tool.

/emmcimage.tar.xz /emmcimage.tar.bz2 /emmcimage.tar.gz /emmcimage.tar

Tar of the filesystem. This will repartition the eMMC to a single partition and extract this tarball to the filesystem. If present, a file named /md5sums.txt in the tarball will have its contents checked against the whole filesystem after the tarball is extracted. This md5sums.txt file is optional and can be omitted, but it must not be blank if present. This file is present in our official images and is created during image capture with the Image Replicator tool.

/emmcimage.dd.xz /emmcimage.dd.bz2 /emmcimage.dd.gz /emmcimage.dd

Disk image of the media. This will be written to the eMMC block device directly. If present on the USB Image Replicator drive, a file named /emmcimage.dd.md5 will be used to verify the data written to the SD card against this checksum. This file is provided with our official images and is created during image capture with the Image Replicator tool.

/sataimage.tar.xz /sataimage.tar.bz2 /sataimage.tar.gz /sataimage.tar

Tar of the filesystem. This will repartition the first SATA drive with a single partition and extract this tarball to the filesystem. If present, a file named /md5sums.txt in the tarball will have its contents checked against the whole filesystem after the tarball is extracted. This md5sums.txt file is optional and can be omitted, but it must not be blank if present. This file is present in our official images and is created during image capture with the Image Replicator tool.

/sataimage.dd.xz /sataimage.dd.bz2 /sataimage.dd.gz /sataimage.dd

Disk image of the media. This will be written to the first SATA block device directly. If present on the USB Image Replicator drive, a file named /sataimage.dd.md5 will be used to verify the data written to the SD card against this checksum. This file is provided with our official images and is created during image capture with the Image Replicator tool.


U-Boot binary blob. This will be written to the bootloader area of eMMC. If the file /u-boot.kwb.md5 is present on the USB drive, this will be used to verify the data written to disk.

Building the Image Replicator from Source

The Image Replicator tool uses Buildroot to create the bootable USB disk image and tarball. See the project repository on github for information on compatibility and instructions on building: https://github.com/embeddedTS/buildroot-ts

Backup/Restore SD Card

Note: Our Image Replicator tool can be used to automate this process.

MicroSD is a storage media ubiquitous to embedded computing. When sourced through authorized distribution its characteristics can be very consistent and reliable across a product line. Combined with a good backup/restore strategy, hardware deployments can be simplified to a handful of commands resulting in a finished product with minimal effort.

The current shipping image tarball is located here.

Note: Only either the full-size SD card, or the micro SD card may be present on the TS-7800-V2. Attempting to use both interfaces at the same time will result in corruption on both media.

Using a TAR archive is the preferred method for moving mass data to or from filesystems on the TS-7800-V2. This method allows for significant variations in media size without the need to calculate and modify image size based on specific media characteristics. So long as the data fits on the media, the "image file" does not need to be specially tailored to the target media.

Preparing the Media

This step may or may not be necessary, depending on the filesystem status of the target media. EXT3 and EXT4 are used interchangeably in this document because the TS-7800-V2 supports both. EXT4 is newer and generally considered better, but ext3 is more compatible across a variety of other systems. Care should be taken to ensure these commands are pointed at the correct device: Accidentally using the wrong device node with these commands could cause catastrophic data loss.

umount /dev/mysdcard1
mkfs.ext4 /dev/mysdcard1

Performing the backup/restore

Note: Our Image Replicator tool can be used to automate this process.

From Workstation --- Restore Note this example uses generalities to describe the path to an SD card, and presumes root access (meaning 'sudo' may be necessary, depending on the particular OS). Replace 'mysdcard1' and 'mountpoint' with names appropriate to your specific situation.

mkdir mountpoint
mount /dev/mysdcard1 mountpoint
tar -xJf ts7800v2-deb_stretch-latest.tar.xz -C mountpoint/ --numeric-owner # note the capital letters J and C in this command line:  These are important.
umount mountpoint

Back Up Note general terminology and paths are used in this example. Replace general terms with those specific to your computing platform.

mkdir mountpoint
mount /dev/mysdcard1 mountpoint
cd mountpoint
tar -cJf ../mysdcard_backup.tar.xz * --numeric-owner #note the capital J in this line: It is important.
cd .. && umount mountpoint

From TS-7800-V2 Boot the TS-7800-V2 to eMMC, USB, or SATA. Use the instructions above. The SD card's first partition on the TS-7800-V2 is defined as /dev/tssdcarda1.

Backup/Restore eMMC

The TS-7800-V2 eMMC media backup and restore process must be performed while the TS-7800-V2 is booted from a separate media resource. There are several possible devices. These instructions will focus largely on USB and SATA media, but any other possible boot media could be used instead (eg. Network boot or micro SD). This is the preferred backup/restore method.

Note: These instructions include commands that will erase target media. Be careful not to accidentally erase the wrong media.

Preparing the backup media

Use Linux PC to install image onto 8GB or greater USB media (or SATA).

Prepare the transfer media using the Linux PC:

wget ftp://ftp.embeddedTS.com/ts-arm-sbc/ts-7800-v2-linux/distributions/ts7800v2-deb_stretch-latest.tar.xz
sudo mkdir mount
sudo mkfs.ext4 /dev/your_usb_or_sata_drive_partition_1  #this erases the media - make sure it doesn't have anything you want to keep on it!
sudo mount /dev/your_usb_or_sata_drive_partition_1 mount
cd mount
sudo tar -xJf ../ts7800v2-deb_stretch-latest.tar.xz -C . --numeric-owner
sudo cp ../ts7800v2-deb_stretch-latest.tar.xz root/
cd ..
sudo umount mount

Backing up eMMC

Note: Our Image Replicator tool can be used to automate this process.

This backs up the data partition of the eMMC device -- note this backup does NOT include uBoot or any other special partitions. Be sure the backup media has sufficient free space.

Populate the U BOOT jumper. Install backup media. Power on SBC.

#at U-Boot prompt, if USB media was used:
run usbboot
#at U-Boot prompt, if SATA media was used:
run sataboot

#Debian will load from the selected media.
#Log in as root, no password is required.

mkdir mount
mount /dev/mmcblk0p1 mount
cd mount
tar -cJf ../emmcBackup.tar.xz -C . --numeric-owner *  #this will take a while.  Note the capital J.
cd ..
umount mount
shutdown -h now

Once the SBC indicates it has halted, remove power from the SBC and disconnect your backup media, the backup file is at "/root/emmcBackup.tar.xz" on the backup media.

Restoring eMMC

Note: Our Image Replicator tool can be used to automate this process.

Remove the media from the PC and install it onto the TS-7800-V2. Populate the U BOOT jumper.

Use the media to install the new image onto the eMMC on the TS-7800-V2:

#at U-Boot prompt, if USB media was used:
run usbboot 
#at U-Boot prompt, if SATA media was used:
run sataboot

#debian loads from selected media.
#login as root, there is no password required.

umount /dev/mmcblk0p1 mount
mkfs.ext4 /dev/mmcblk0p1  #note:  This step erases the eMMC user data partition.
mount /dev/mmcblk0p1 mount
cd mount
tar -xJf ../ts7800v2-deb_stretch-latest.tar.xz -C . --numeric-owner


Debian is a community run Linux distribution. Debian provides tens of thousands of precompiled applications and services. This distribution is known for stability and large community providing support and documentation. The installation is specific to our board, but most Debian documentation applies:

Getting Started with Debian

Once installed the default user is "root" with no password. Services such as telnet, ssh, or others will typically require a password set and other configuration before they allow remote connections.

The current shipping image can always be downloaded here:

There is a newer distribution for those who would prefer Debian Buster, here:

Prepare a USB media device (thumb drive, memory stick, etc.). Use a partitioning tool such as 'fdisk' 'cfdisk' or 'gparted' in linux to create a single linux partition on the media. The default shipping images use GPT partitions MBR will also work. Then format the device using 'sudo mkfs.ext3 /dev/devicename_here' if your preferred partition tool (such as fdisk) does not format the media for you. Once the media is formatted, extract the above tarball with:

# Assuming your media card is /dev/sdc with one partition
mkfs.ext3 /dev/sdc1
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar --numeric-owner -xJf ts7800v2-deb_stretch-latest.tar.xz -C /mnt/sd     #note the capital J for xz decompression
sudo umount /mnt/sd
Note: The ext4 filesystem can be used instead of ext3, but it may require additional options. U-Boot does not support the 64bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options "-O ^64bit,^metadata_csum" must be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed nor are they needed for ext3.

To rewrite the eMMC the unit must be booted to media that is not eMMC. Once booted, run the following commands:

mkfs.ext3 /dev/mmcblk0p1
mkdir /mnt/emmc
mount /dev/mmcblk0p1 /mnt/emmc
wget ftp://ftp.embeddedTS.com/ts-arm-sbc/ts-7800-v2-linux/distributions/ts7800v2-deb_stretch-latest.tar.xz
tar -xJf ts7800v2-deb_stretch-latest.tar.xz -C /mnt/emmc/
umount /mnt/emmc

The same commands can be used to write a SATA drive by substituting /dev/mmcblk2p1 with /dev/sda1.

Debian Networking

From almost any Linux system you can use "ip" or the ifconfig/route commands to initially set up the network from the command line. For more permanent network setup, the /etc/network/interfaces file should be edited to conform with the target network's setting requirements.

# Bring up the CPU network interface
ifconfig eth0 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

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

  auto eth0                                                         
  iface eth0 inet static                                            
#  auto eth1                                                         
#  iface eth1 inet dhcp

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.

It's also handy to have the loopback device defined:

  auto lo                                                           
  iface lo inet loopback

Debian WIFI Client

The wifi drivers and client software are installed on the TS-7800-V2 by default. See the WiFi section for further details on this software.

Wireless interfaces are also managed with configuration files in "/etc/network/interfaces.d/". For example, to connect as a client to a WPA network with DHCP. Note some or all of this software may already be installed on the target SBC.

Install wpa_supplicant:

apt-get update && apt-get install wpasupplicant -y


wpa_passphrase youressid yourpassword

This command will output information similar to:


Use the hashed PSK in the specific network interfaces file for added security. Create the file:


allow-hotplug wlan0
iface wlan0 inet dhcp
    wpa-ssid youressid
    wpa-psk 151790fab3bf3a1751a269618491b54984e192aa19319fc667397d45ec8dee5b

To have this take effect immediately:

service networking restart

For more information on configuring Wi-Fi, see Debian's guide here.

You can of course swap dhcp for a fixed IP address, if that is your preference, by changing the /etc/network/interfaces.d/wlan0 file appropriately. Documentation on how Debian's network setup works can be found in the full Debian networking documentation here.

Note: The default IP address for eth0 is Even if there is no Ethernet network plugged in, eth0 will take routing precedence for all 192.168.*.* addresses. If the wireless network also uses 192.168.*.* subnets, the eth0 port should be given a different static address, or brought down by running ifconfig eth0 down.

Debian WIFI Access Point

This section will discuss setting up the WiFi device as an access point that is bridged to an ethernet port. That is, clients can connect to the AP and will be connected to the ethernet network through this network bridge. The ethernet network must provide a DHCP server; this will be passed through the bridge to WiFi client devices as they connect.

It is also possible to run a DHCP client on the platform itself. In this case the hostapd.conf file needs to be set up without bridging and a DHCP server needs to be configured. Refer to Debian's documentation for more details on DHCP server configuration.

The 'hostapd' utility is used to manage the access point of the device. This is usually installed by default, but can be installed with:

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

Note: The install process may start an unconfigured 'hostapd' process. This process must be killed before moving forward.

Modify the file "/etc/hostapd/hostapd.conf" to have the following lines:

wpa_pairwise=TKIP CCMP
Note: Refer to the kernel's hostapd documentation for more wireless configuration options.

The access point can be started and tested by hand:

hostapd /etc/hostapd/hostapd.conf

Systemd auto-start with bridge to eth0

It is possible to configure the auto-start of 'hostapd' through systemd. The configuration outlined below will set up a bridge with "eth0", meaning the Wi-Fi connection is directly connected to the ethernet network. The ethernet network is required to have a DHCP server present and active on it to assign Wi-Fi clients an IP address. This setup will allow Wi-Fi clients access to the same network as the ethernet port, and the bridge interface will allow the platform itself to access the network.

Set up hostapd

First, create the file "/etc/systemd/system/hostapd_user.service" with the following contents:

Description=Hostapd IEEE 802.11 AP

ExecStart=/usr/sbin/hostapd /etc/hostapd/hostapd.conf -P /run/hostapd.pid -B


Then enable this in systemd:

systemctl enable hostapd_user.service
systemctl enable systemd-networkd

Set up bridging

Create the following files with the listed contents.









Debian Installing New Software

Debian provides the apt-get system which allows management of pre-built applications. The apt tools require a network connection to the internet in order to automatically download and install new software. The update command will download a list of the current versions of pre-built packages.

Older Debian releases are moved to a different server to indicate it is no longer getting security updates. To download packages for these older distributions, edit /etc/apt/sources.list to only have the following lines:


deb http://archive.debian.org/debian/ jessie main
deb-src http://archive.debian.org/debian/ jessie main


deb http://archive.debian.org/debian/ wheezy main
deb-src http://archive.debian.org/debian/ wheezy main

After modifying that file, be sure to update the package list:

apt-get update

A common example is installing Java runtime support for a system. Find the package name first with search, and then install it.

root@ts:~# apt-cache search openjdk
jvm-7-avian-jre - lightweight virtual machine using the OpenJDK class library
freemind - Java Program for creating and viewing Mindmaps
icedtea-7-plugin - web browser plugin based on OpenJDK and IcedTea to execute Java applets
default-jdk - Standard Java or Java compatible Development Kit
default-jdk-doc - Standard Java or Java compatible Development Kit (documentation)
default-jre - Standard Java or Java compatible Runtime
default-jre-headless - Standard Java or Java compatible Runtime (headless)
jtreg - Regression Test Harness for the OpenJDK platform
libreoffice - office productivity suite (metapackage)
icedtea-7-jre-jamvm - Alternative JVM for OpenJDK, using JamVM
openjdk-7-dbg - Java runtime based on OpenJDK (debugging symbols)
openjdk-7-demo - Java runtime based on OpenJDK (demos and examples)
openjdk-7-doc - OpenJDK Development Kit (JDK) documentation
openjdk-7-jdk - OpenJDK Development Kit (JDK)
openjdk-7-jre - OpenJDK Java runtime, using Hotspot Zero
openjdk-7-jre-headless - OpenJDK Java runtime, using Hotspot Zero (headless)
openjdk-7-jre-lib - OpenJDK Java runtime (architecture independent libraries)
openjdk-7-source - OpenJDK Development Kit (JDK) source files
uwsgi-app-integration-plugins - plugins for integration of uWSGI and application
uwsgi-plugin-jvm-openjdk-7 - Java plugin for uWSGI (OpenJDK 7)
uwsgi-plugin-jwsgi-openjdk-7 - JWSGI plugin for uWSGI (OpenJDK 7)

In this case you will want the openjdk-7-jre package. Names of packages are on Debian's wiki or the packages site.

With the package name apt-get install can be used to install the prebuilt packages.

apt-get install openjdk-7-jre
# More than one package can be installed at a time.
apt-get install openjdk-7-jre nano vim mplayer

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

Debian Setting Up SSH

To install ssh, install the package as normal with apt-get:

apt-get install openssh-server

Make sure the device is configured on the network and set a password for the remote user. SSH will not allow remote connections without a password or a valid SSH key pair.

passwd root
Note: The default OpenSSH server will not permit root to login via SSH as a security precaution. To allow root to log in via ssh anyway, edit the /etc/ssh/sshd_config file and add the line PermitRootLogin yes in the authentication section. This change will take effect after reboot or after sshd service restart.

After this setup it is now possible to connect from a remote PC supporting SSH. On Linux/OS X this is the "ssh" command, or from Windows using a client such as PuTTY.

Note: If a DNS server is not present on the target network, it is possible to save time at login by adding "UseDNS no" in /etc/ssh/sshd_config.

Debian: Starting Automatically

A systemd service can be created to start up headless applications. Create a file in /etc/systemd/system/yourapp.service

Description=Run an application on startup



If networking is a dependency add "After=network.target" in the Unit section. Once you have this file in place add it to startup with:

# Start the app on startup, but will not start it now
systemctl enable yourapp.service

# Start the app now, but doesn't change auto startup
systemctl start yourapp.service
Note: See the systemd documentation for in depth documentation on services.

Debian Application Development

The choice of Debian as a primary Linux Distribution on the TS-7800-V2 came from two primary reasons: First, the original TS-7800-V2 used Debian and the goal is for the TS-7800-V2 to be as close to "drop-in" compatible as possible. Second, the Debian Linux distribution provides a number of advantages to the downstream developer. From the exceptionally large 27,000+ package repository of software packages to the provision of known-good cross-compilers, the choice of distribution seems relatively obvious. Our goal is to provide the downstream with the greatest access to supporting software, and the Debian Linux distribution provides it in spades.

Debian Buster Cross Compiling

Buster and probably newer Debians have simplified the cross compiler setup significantly.

To prepare the system for ARM cross-compiling, add the armhf cross-architecture to host Debian system:

sudo dpkg --add-architecture armhf
sudo apt-get update
sudo apt-get install build-essential libncurses-dev libncursesw5-dev bc

From this point the host system is set up and ready to compile binaries for most ARMHF platforms.

Debian Stretch Cross Compiling

Debian Stretch provides cross compilers from the Debian apt repository archive for Debian Stretch. An install on a workstation can build for the same release on other architectures. A Linux desktop or laptop PC, virtual machine, or chroot will need to be used for this. Debian Stretch for a workstation can be downloaded from here.

From a Debian workstation (not the target), run these commands to set up the cross compiler:

# Run "lsb_release -a" and verify Debian 9.X is returned.  These instructions are not
# expected to work on any other version or distribution.
su root
# Not needed for the immediate apt-get install, but used
# so we can install package:armhf for cross compiling
dpkg --add-architecture armhf
apt-get update
apt-get install curl build-essential crossbuild-essential-armhf -y

This will install a toolchain that can be used with the prefix "arm-linux-gnueabihf-". The standard GCC tools will start with that name, eg "arm-linux-gnueabihf-gcc".

The toolchain can now compile a simple hello world application. Create hello-world.c on the Debian workstation:

#include <stdio.h>
int main(){
    printf("Hello World\n");

To compile this:

arm-linux-gnueabihf-gcc hello-world.c -o hello-world
file hello-world

This will return that the binary created is for ARM. Copy this to the target platform to run it there.

Debian Stretch supports multiarch which can install packages designed for other architectures. On workstations this is how 32-bit and 64-bit support is provided. This can also be used to install armhf packages on an x86 based workstation.

This cross compile environment can link to a shared library from the Debian root. The package would be installed in Debian on the workstation to provide headers and libraries. This is included in most "-dev" packages. When run on the arm target it will also need a copy of the library installed, but it does not need the -dev package.

apt-get install libcurl4-openssl-dev:armhf

# Download the simple.c example from curl:
wget https://raw.githubusercontent.com/bagder/curl/master/docs/examples/simple.c
# After installing the supporting library, curl will link as compiling on the unit.
arm-linux-gnueabihf-gcc simple.c -o simple -lcurl

Copy the binary to the target platform and run on the target. This can be accomplished with network protocols like NFS, SCP, FTP, etc.

If any created binaries do not rely on hardware support like GPIO or CAN, they can be run using 'qemu'.

# using the hello world example from before:
# Returns Exec format error
apt-get install qemu-user-static

Debian Read Only

Debian supports running as a read only filesystem. This is useful for systems that may lose power and shut down at any time. This is the simplest way to prevent filesystem corruption.

An example /etc/fstab would include:

/dev/root            /                    auto       defaults              1  1
proc                 /proc                proc       defaults              0  0
devpts               /dev/pts             devpts     mode=0620,gid=5       0  0
usbdevfs             /proc/bus/usb        usbdevfs   noauto                0  0
tmpfs                /run                 tmpfs      mode=0755,nodev,nosuid,strictatime 0  0
tmpfs                /var/run                 tmpfs      mode=0755,nodev,nosuid,strictatime 0  0
tmpfs                /var/volatile        tmpfs      defaults              0  0
tmpfs                /tmp                 tmpfs      defaults              0  0
tmpfs                /var/tmp             tmpfs      defaults              0  0

/dev/root is an abstraction to the real root filesystem device. This actually refers to the device u-boot specifes in the kernel cmdline as 'root='. Check "cat /proc/cmdline" to see what device this is on your system, but /dev/root can be left for these purposes.

To make Linux mount this as read only, change the mount options on /dev/root/ from "defaults" to "ro".

/dev/root            /                    auto       ro              1  1

After this, reboot. Some applications may fail to start because they are failing to write.

Debian Fix Read Only Services

Most services will just run while the OS is read only, but some may fail to start because writes are failing. The steps to fix this are application specific, but normally the writes need to be moved to a tmpfs, or disabled. This example will show fixing Apache2 to work while read only.

root@ts7800-v2:/root# /usr/sbin/apache2
(30)Read-only file system: AH00091: apache2: could not open error log file /var/log/apache2/error.log.
AH00015: Unable to open logs

There are two ways to handle this. The writes can be put into a tmpfs, or logs can be disabled. To put these logs in a tmpfs, first temporarily enable read/write:

mount -o remount,rw /

Now edit /etc/fstab and add the line:

tmpfs                /var/log/apache2     tmpfs      defaults              0  0

This will cause writes to /var/log/apache2 to go to a tmpfs, but these must be rotated or the tmpfs may run out of room. If the writes fail apache will stop crash.

The filesystem cannot be remounted read only while there are open file handles, so now reboot the system. Apache will start as normal.

Alternatively, logs can be shut off. Instead of the /var/log/apache2 fstab line, this can be run to disable logs:

# Disable logs on specific apache2 sites.
find /etc/apache2/sites-enabled/* -exec sed -i 's/#*[Cc]ustom[Ll]og/#CustomLog/g' {} \;
find /etc/apache2/sites-enabled/* -exec sed -i 's/#*[Ee]rror[Ll]og/#ErrorLog/g' {} \;

# disable the vhost access log
echo "" > /etc/apache2/conf-enabled/other-vhosts-access-log.conf

vim /etc/apache2/apache2.conf
## Replace: 
# ErrorLog ${APACHE_LOG_DIR}/error.log
## with:
ErrorLog /dev/null

Reboot, and apache should start up while the filesystem is read only.

Debian Stretch Create a read/write partition

While keeping the OS read/write it may be beneficial to keep one partition read/write to save log or configuration data. Our default images use one partition for the "/" partition including all of the Linux rootfs, but this example will resize that partition and create one other for data. First, boot to the disk and check the size of the partition:

Filesystem     1M-blocks  Used Available Use% Mounted on
/dev/root           3487  1484      1807  46% /

In this case the /dev/root filesystem is using 1484MB. As an example we will resize the filesystem to 1750MB which leave some room to grow if new packages are needed.

Use fdisk to get the sector count of the emmc: root@ts7800-v2:~# fdisk -l /dev/mmcblk0 Disk /dev/mmcblk0: 3.5 GiB, 3783262208 bytes, 7389184 sectors

Take a backup copy of the eMMC in a tar as described here. Copy this to your Linux workstation and the new image will be created there.

Create a file on your workstation the same size as the eMMC: dd if=/dev/zero bs=512 count=7389184 of=my-image.dd

LOOPDEV=$(losetup -f)
sudo losetup $LOOPDEV my-image.dd
sudo fdisk $LOOPDEV

Set up your partitions to your rootfs image size, and make the second partition cover the rest of the disk.

Welcome to fdisk (util-linux 2.30.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x8e8595de.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-7389183, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-7389183, default 7389183): +1750M

Created a new partition 1 of type 'Linux' and of size 1.7 GiB.

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 2
First sector (3586048-7389183, default 3586048): 
Last sector, +sectors or +size{K,M,G,T,P} (3586048-7389183, default 7389183): 

Created a new partition 2 of type 'Linux' and of size 1.8 GiB.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Invalid argument

The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).

Detach the loopback device and recreate it with kpartx which will understand these new partitions.

sudo losetup -d $LOOPDEV
sudo kpartx -va my-image.dd

In my case this created loop1p1/loop1p2:

add map loop1p1 (253:0): 0 3584000 linear 7:1 2048
add map loop1p2 (253:1): 0 3803136 linear 7:1 3586048

Create the filesystems and extract your image:

sudo mkfs.ext4 /dev/mapper/loop1p1
sudo mkfs.ext4 /dev/mapper/loop1p2
sudo mkdir /mnt/emmc
sudo mount /dev/mapper/loop1p1 /mnt/emmc
sudo tar -xf /path/to/your/image.tar.xz -C /mnt/emmc
sudo mkdir /mnt/emmc/srv/

Open the /mnt/emmc/etc/fstab and add a line:

 /dev/mmcblk0p2   /srv          auto    ro                 0    2

This will mount the new partition automatically on startup.

sudo umount /mnt/emmc
sudo kpartx -d my-image.dd
xz my-image.dd

Write this my-image.dd.xz to your eMMC as described here. On startup the new data partition will be mounted at /srv. Make this partition read/write with:

mount -o remount,rw /srv/

# Whenever possible, make read only when done writing
mount -o remount,ro /srv/

The remount to read only will fail if there are any open file handles on this disk. See the lsof tool for more information on tracking down open file handles.

Compile The Kernel



This guide is intended to run on an x86 compatible Linux workstation. While you may be able to compile the kernel on the board, we do not recommend it. A typical workstation compile will take several minutes. The same compile on the board may take several hours. It is also possible to compile this kernel under a Windows 10 operating system, however the developer must make absolutely certain that they are performing all operations within the boundaries of an ext4 filesystem. Due to case-sensitivity issues, the kernel compile process will not generally work in NTFS.

This guide also presumes the reader has already completely read, understood, and set up a cross-development platform as described in chapter 4.6 of this product manual.


yum install ncurses-devel ncurses
yum groupinstall "Development Tools" "Development Libraries"
Ubuntu/Debian (before 12):
apt-get install build-essential libncurses5-dev libncursesw5-dev bc
Debian 12:
apt-get install build-essential libncurses5-dev libncursesw5-dev bc crossbuild-essential-armhf

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

#Download the kernel sources
git clone https://github.com/embeddedTS/linux-armada38x.git

cd linux-armada38x

If using a nonstandard or custom cross-compiler (ie not the one covered in chapter 4.6), export the CROSS_COMPILE variable with a path that points to the appropriate cross-compiler prefix.

export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm

Now you will want to configure your settings. You can start with our default config by running:

make ts7800_v2_defconfig

At this point you can configure any additional options with:

make menuconfig

After you saved the configuration, you can build your kernel and modules with:

make -j4 && make -j4 modules

Next generate a tar including the new kernel, device trees, and modules.

mkdir -p target/boot
INSTALL_MOD_PATH="target/" make modules_install 
cp arch/arm/boot/zImage  target/boot/zImage
cp arch/arm/boot/dts/armada-385-ts*.dtb target/boot/
cd target
tar --owner=0 --group=0 -cJf ../newkernel-$(git rev-parse --short HEAD).tar.xz .
cd ../

This will create a file like newkernel-8cac5540.tar.xz. The git hash indicates the source revision. Copy this to your target media. For example, if are booted to the target eMMC or SATA on the board:

tar -xf newkernel-8cac5540.tar.xz -C /

Reboot the board, and run "uname -a". This will print out the running kernel's revision: 4.4.8-g8cac5540.


The features of the TS-7800-V2 SBC are broken into several categories.

CPU Functionality

The TS-7800-V2 utilizes a Marvell MV88F6820 Armada 385 ARM Cortex-A9 1.3 GHz Dual Core CPU. Its features follow:


This CPU optionally supports ECC which is turned off by default. The TS-7800-V2 off the shelf builds include two RAM chips supporting 512MiB each. Enabling ECC will use one of these chips to store the ECC data only which halves the usable RAM.

ECC is enabled by modifying the #Boot Flags.

Once enabled, the CPU is capable of autocorrecting single bit failures, and detecting double bit failures. The mvebu_edac driver will report any failures to the kernel log. In the case of a single bit failure:

 EDAC MC0: 1 CE MVEBU on mc#0csrow#0channel#0 (csrow:0 channel:0 page:0xc8e offset:0xc8e000 grain:8 syndrome:0x5b99e5 - Single bit ECC Failure)

A double bit failure will print out this message, and also attempt a system reboot.

 EDAC MC0: 1 UE MVEBU on mc#0csrow#0channel#0 (csrow:0 channel:0 page:0x8e offset:0x8e000 grain:8 - Double bit ECC Failure)

To have the system not reboot in case of a double bit failure and just report change the kernel cmdline to include "mvebu_edac.edac_reboot_on_fail=0". See the section on modifying the kernel command line for details.


The TS-7800-V2 has 1 GB of DDR3. Optionally the RAM can be placed in ECC mode through a software switch covered in the Boot Flags section.


The 88F6820 features a Memory Management Unit, enabling high level operating systems such as Embedded Linux to run on the TS-7800-V2. In the same way, the Linux Kernel takes advantage of the MMU functionality. The MMU is controlled by page tables stored in system memory and is responsible for virtual address to physical address translation, memory protection through access permissions and domains, MMU cache and write buffer access. In doing so, software applications can access larger "virtual" memory space than the available physical memory size, allowing multiple programs to run and use the system memory simultaneously.


The 88F6820 has 192 interrupts available on chip as well as another 16 implemented in the PCIe connected FPGA through MSI interrupts. There are 3 interrupts on the PC104 bus which can be used by end users.

IRQ Description
109 16550 port 0
110 16550 port 1
111 16550 port 2
112 16550 port 3
113 16550 port 4
114 16550 port 5
115 16550 port 6
116 16550 port 7
117 16550 port 8
118 16550 port 9
119 16550 port 10
120 FPGA CAN core
121 Reserved
122 PC104 IRQ5
123 PC104 IRQ6
124 PC104 IRQ7

In Linux, interrupts are not available to software outside the kernel. Note, interrupts are assigned dynamically and depend on both the fpga_gpio driver and the device tree. Changes to the shipping device tree may change how the interrupts are numbered in unpredictable ways, so care should be taken to test any new driver solution against the final device tree with instrumentation to ensure the interrupt being sought is actually the interrupt being used.

Onboard eMMC Flash

This board includes an eMMC module. Our off the shelf builds are 4GiB, but up to 64GiB are available for larger builds. The eMMC flash appears to Linux as an SD card at /dev/mmcblk0. Our default programming will include one partition programmed with our Debian image.

The CPU boots out of the emmc's hardware boot partitions /dev/mmcblk0boot0 and /dev/mmcblk0boot1. These are both 16MB, and are separate from the mmcblk0 flash. Erasing or manipulating /dev/mmcblk0 and its partitions will not affect these hardware partitions. The board boots to /dev/mmcblk0boot0 by default, but boot1 can be selected if it has been written with a valid bootloader. This allows atomic updates in the field of u-boot, but should only be done with care as it can leave your board not booting if a bad image is written before switching the active boot partition.

WARNING: This may need a development board or RMA to recover the SBC if the CPU fails to boot. Make certain a valid u-boot is present on the boot device before switching to it.

Write a u-boot to mmcblk0boot1 with:

echo 0 > /sys/block/mmcblk0boot1/force_ro
dd if=/path/to/u-boot.kwb bs=1M of=/dev/mmcblk0boot1

Once the data has been verified as written, the active boot partition can be switched to mmcblk0boot1:

# The argument after enable should be 2 for mmcblk0boot1, or 1 for mmcblk0boot0
mmc bootpart enable 2 1 /dev/mmcblk0

The active partition can be read as part of the extcsd read:

mmc extcsd read /dev/mmcblk0

USB Host

The USB Connector on the TS-7800-V2 provide two USB 3.0 interfaces for the user. These are directly connected to the MV88F6820 processor, which integrates a USB dual-port Extensible Host Controller Interface (xHCI), providing serial communications ports at a baud rate of up to 5 Gbit/s ("SuperSpeed"). The MV88F6820 also has a USB 2.0 controller, with Enhanced Host Controller Interface (EHCI) for full compatibility with USB 2.0 at speeds up to 480 Mbits/sec ("High-Speed"). The USB 3.0 ports are backwards-compatible with USB 2.0 and will fall back to EHCI to support older USB devices.

Linux provides support for most USB devices through drivers. Direct access to communicate with USB peripherals is typically done with libusb.

Additional non-volatile storage may be added with a USB flash drive. This device supplies additional non-volatile storage either for data or for a complete operation system distribution, such as Debian. A tar-file of Debian is available on the Technologic Systems FTP site.

Testing indicates the USB3.0 functionality should be capable of operating at line rate. To date all testing has been limited by the external test apparatus being unable to saturate the USB 3.0 pipe.


The TS-7800-V2 provides up to two SATA 3.0 ports at data rates of up to 6 Gbits/sec.

SATA drives will appear (in Linux) as /dev/sda and (with the optional second SATA port) /dev/sdb. In U-Boot, after executing the "scsi scan" command, they will appear as SCSI drives "scsi 1:0" and (with the optional second SATA port) "scsi 0:0".

If the drive is formatted, with the required files in the "/boot" subdirectory, the board may be booted from the drive by substituting (for example) "scsi 0:1" for "mmc 0:2" in the ext4load command (see the U-Boot Commands section for more details on booting). It will also be necessary to modify the bootargs from (for example) "root=/dev/mmcblk0p2" to "root=/dev/sda1".

The PCIe port (on select TS-7800-V2 models) is configurable for mSATA functionality by setting a Boot Flag.

Speed Scale

By default the CPU included is rated for 1333MHz. The CPU will be clocked up to this max speed by default at all times. It is possible to adjust this clock speed to 1066MHz, or 666MHz. Note that this improves power consumption when the cpu is loaded, but reducing the clock speed of this CPU does not reduce power consumption when the cpu is idle: Running at 1.3GHz with both cores enabled at idle is the same power consumption as 666MHz with only one core.

See the #Power_Consumption section for more information on these savings when the CPU is under load.

To reduce the clock speed:

# Specify the rate you want with 1066 or 666 directly:
ts7800ctl -l 1066

# Specify 0 to attempt to auto set back to the max:
ts7800ctl -l 0

# Specify 1 core instead of two
ts7800ctl -c 1

These commands will require a power cycle.

SiLabs Functionality

The TS-7800-V2 features a SiLabs C8051F381 microcontroller. This microcontroller is used primarily as a power management coprocessor. The microcontroller also provides the TS-7800-V2 with ADC capabilities.

ADC Sampling

The TS-7800-V2 provides an analog to digital capture function through the on-board SiLabs microcontroller. The microcontroller has five 10 bit 0-5V analog inputs. This microcontroller is connected over I2C to the ARM CPU and provides approximately 7sps. The analog input channels are brought out to the A/D header (see A/D Header below for pin-outs). A voltage divider is used on each input to divide the input voltage by two; therefore, the maximum input voltage at the header should not exceed 6.6V.

The ADC is implemented using ts7800ctl:

root@ts7800:root# ts7800ctl -S 0,1
[0x00000000, 0]=1023
[0x00000001, 1]=0810
[0x00000002, 0]=1023
[0x00000003, 1]=1023
[0x00000004, 0]=1023

This requests ts7800ctl to output ADC in string data. This returns:

 [Hex counter, Channel]=Value

If you prefer to implement this in your own code, you can get the ts7800ctl source code here.


# Capture 1000 raw binary samples from channel 0 and print the output to a file in a comma separated format.
ts7800ctl -r"0" | dd bs=2 count=1000 2>/dev/null | hexdump -v -e '1/2 "%u, "' > ch0_500_samples.csv

#Capture 500 samples from channel 0 and 500 samples from channel 1. Write the 
#samples to a file where all channel 0 samples are in the first column and all 
#channel 1 samples are in the second column.
ts7800ctl -r"0-1" | dd bs=2 count=1000 | hexdump -v -e '1/2 "0x%x\t" 1/2 "0x%x\n"' > ch0_ch1_1k_samples.dat

#Capture 1000 samples from channel 0, and then print the output to standard out in ASCII.
ts7800ctl -S"0,1" 2>/dev/null | dd bs=19 count=1000

#Capture 5 samples from channel 0 and 5 samples from channel 1, then print the output to standard out in ASCII.
ts7800ctl -S"0-1" 2>/dev/null | dd bs=19 count=10

FPGA Functionality

The 20,000 LUT Altera Cyclone IV FPGA is an integral part of the TS-7800-V2 design. After an operating system has booted, the FPGA provides the CPU access to the PC/104 connector. 89 PC/104 pins are connected to the FPGA. The default FPGA load allows these pins to be used either as a standard PC/104 bus or for GPIO. Due to the flexibility of FPGAs, many other functionalities are possible such as quadrature encoders, PWM outputs, extra serial ports, DMX, or other unique communications protocols. Please contact Technologic Systems if you require custom FPGA logic.

The default FPGA has several cores available at 0xe8000000 as a 32-bit bus. Most of these are abstracted by existing drivers or utilities.

Offset Description
0x00-0xff Syscon
0x100-0x1ff SD card controller
0x200-0x2ff IRQ controller
0x400-0x4ff DMA channel interface
0x800-0x8ff NAND controller

FPGA Syscon

By default the Altera FPGA on the TS-7800-V2 is loaded with a system controller core at base physical address 0xFC081000. Add that base to the offsets below to access these registers. With the exception of the UART control registers, these registers are all 32 bits wide and should therefore be accessed with 32 bit writes. The UART registers are 16 bit registers.

Offset Bits Description
0x0 31-8 Board ID: 0xb480
7-0 FPGA Revision
0x4 31 U-Boot jumper status (1 = on)
30 SD Boot jumper status (1 = on)
29 LCD header data pin 14 [1]
28 LCD header data in pin 13
27 LCD header data in pin 12
26 LCD header data in pin 11
25 LCD header data in pin 10
24 LCD header data in pin 9
23 LCD header data in pin 8
22 LCD header data in pin 7
21 LCD header data in pin 6
20 LCD header data in pin 5
19 Reserved
18 LCD header data in pin 3
17:16 Reserved
15-0 DIO header data in pins 16-1
30 Green LED (1 is on)
29:16 LCD header Data Output (pin 1:14)
15:0 DIO Header Data Output (pin 1:16)
0xc 31:23 Reserved
22 WIFI_RESET# (disables ttts8)
20 Red LED (1 is on)
19 EN_CONSOLE jumper status (1 = on)
18 Reserved
17 UART CTS for COM3
16 UART RTS for COM3
15 1 = RS422 on COM2 using TSUART2

0 = dual RS485 using TSUART2 and TSUART3

14 UART DTR for COM1
13 UART RTS for COM1
12 ISA OSC select (0 = 14.318MHz, 1 = 25MHz), 0 default
11 TS alternate ISA Pinout enable (default 1)
10 Enable honor ISA OWS/ENDX signal
9:6 ISA setup length (in 10ns periods)
5:0 ISA strobe length (in 10ns periods)
0x10 31:0 PC104 row A GPIO data
0x14 31:0 PC104 row B GPIO data
0x18 31:20 Reserved
19:0 PC104 row C GPIO data
0x1c 31:20 Reserved
19:0 PC104 row D GPIO data
0x20 31:0 PC104 row A GPIO data direction
0x24 31:0 PC104 row B GPIO data direction
0x28 31:20 Reserved
19:0 PC104 row C GPIO data direction
0x2c 31:20 Reserved
19-0 PC104 row D GPIO data direction
0x30 31:0 PC104 row A MUX function
0x34 31:0 PC104 row B MUX function
0x38 31:20 Reserved
19:0 PC104 row C MUX function
0x3c 31:20 Reserved
19:0 PC104 row D MUX function
0x40 31:0 Free running microsecond counter
0x44 31:0 32 bits of random data updated every second
0x48 31:0 Arbitrary Baud Rate Register
0x4c 31:0 #FPGA MUX Register
0x5c 10:0 Arbitrary Baud Clock Switch [2]
  1. (1 = tristate with pullup, 0 = low)
  2. bit number is uart number, 1= 1.8432 MHz (default), 0=custom defined clock in syscon reg. 0x48. See serial ports for details.


The LCD and DIO headers are normally controlled through the Linux sysfs GPIO driver, as documented in the GPIO section above.

Alternatively, the DIO and LCD headers are controlled by 32 bit registers at 0xe8000004 and 0xe8000008. Bits 15-0 control the DIO header and bits 29-16 control the LCD header. The register at 0xe8000008 is the output register. Writing a 0 drives the pin low but writing a 1 only tri-states. To use these pins for input, write a 1 to the output register and read the register at 0xe8000004. See the LCD Header and DIO Header sections for more details on the pinout. See the syscon for more information on the FPGA Register map that controls these IO.


There are six PWM channels available, and these are presented on the DIO header, pins 1,3,5,7,9, and 11. To use these, use the pwmctl utility. The source for this utility is available for download here There are two independent 'generators' that may be programmed with a period between 1us (1MHz) and 409.5ms (2.44Hz). The PWM channels may select either of the two generators.

Some examples of using the PWM follows.

# Setup the first generator to have a frequency of 10KHz (ie, period=100us)
pwmctl -c 6 -d 100 -g 0

# Setup the second generator to have a frequency of 10Hz (ie, period=100ms)
pwmctl -c 7 -d 1000 -g 1

# Put a signal on DIO pin 1, 10KHz, 50% duty-cycle, using the 10KHz generator
pwmctl -c 0 -d 50% -g 0

# Put a signal on DIO pin 3, 10Hz, 20% duty-cycle, using the 10Hz generator
pwmctl -c 1 -d 20% -g 1
Note: The DIO pins are active low, which means that a signal with, for example, a 20% duty-cycle will be low 20% of the time.

The PWM core on the 7800v2 can be talked to via 32-bit syscon register offset 0x4c. There are 6x 12-bit PWM outputs, and 2x programmable frequency generators. To write any one of the 8 registers, do a 32-bit write at 0x4c. Bit 29 must be set, bit 24-8 is the 16-bit PWM opcode, as defined below. The 6 PWM outputs are XOR'ed into dio header pins 1-6 so both the legacy dio registers or the PWM control can work simultaneously.

Bits Function
15:13 PWM Channel (0-5)
12 Frequency Generator Select (0 or 1)
11:0 Duty Cycle (0x0 - 0xFFF)
15:13 PWM Generator (6-7)

0=Generator Ch. 6 1=Generator Ch. 7

12 Period Scale

0=1ms 1=100ms

11:0 Period (0x0 - 0xFFF)


To access peripherals on the PC104 bus it is necessary to add the base address from the table below to the offset of the peripheral to get a memory address for accessing the peripheral. For example, for ISA 8-bit I/O address 0x100, add 0xFA000000 to 0x100 to get 0xFA000100.

Memory I/O
8-bit 0xF8000000 0xFA000000
16-bit 0xF9000000 0xFB000000

For backward-compatibility with the TS-7800, the linux devmem driver has been adapted to allow the old addresses to be used as before from within an application. These addresses are shown in the next table.

Memory I/O
8-bit 0xEC000000 0xEE000000
16-bit 0xED000000 0xEF000000

IRQs 5, 6, and 7 on the PC104 bus from the TS-7800-V2 are 122 + the PC104 IRQ number. These will be IRQs 122, 123, and 124.

WARNING: The Ethernet connector near the PC/104 bus is near the edge of the PC/104 specification. It is advised to apply a piece of electrical tape on top of the ethernet connector when using a PC/104 daughter board to help prevent any damage.

The TS-7800-V2 provides control over some of the ISA parameters of the PC-104 bus through a 32-bit register located at address 0xE800000C, which is defined as follows:

Bit(s) Function
5-0 ISA strobe length
9-6 ISA setup length
10 Honor ISA 0WS/ENDX signal (1=true)
11 TS special ISA pinout enable (1=true)
12 ISA oscillator select
Value Function
0 high-jitter approximation of 14.318Mhz
1 clean 25Mhz

(Other bits in this register should be masked out.)

The ISA strobe length and ISA setup length are both given as the number of extra 10ns periods.

The ISA strobe length is the amount of additional time that ISA_IOR, ISA_IOW, ISA_MEMR, and ISA_MEMW are held asserted. The minimum (when bits are zero) is 20ns. The default power-on value is 40, for a 420ns strobe length. If configured to honor the ISA 0WS/ENDX signal, the peripheral will skip the remaining strobe time for an early transaction end, allowing for faster devices than standard ISA allows.

The ISA setup length is the additional amount of time above 20ns that the address and data are held stable before asserting the strobe. The default is 14 (160ns).

There is an additional 20ns hold time at the end of the strobe where address and data are kept valid. The default total bus cycle length is then 160ns (setup) plus 420ns (strobe) plus 20ns (hold) for a total of 500ns (2Mhz). This is very conservative for modern hardware and most designs can actually run much faster.

The TS special ISA pinout is designed to enable compatibility with products from TS that use the 16-bit bus on the 64-pin PC/104 header. For example the TS-ETH2 is a 16-bit peripheral that has a jumper labeled "ARM." When this jumper is shorted it will expect to use the TS special ISA pinout, if it is left open it will expect to use standard PC/104 16-bit pinout. Please note that disabling the special pinout is generally not required as both 8 and 16-bit bus cycles will still function normally when it is enabled. Disabling the special ISA mode will result in quirky behavior that may show double read strobes.


The PC-104 connector can be multiplexed between PC-104 functionality and GPIO functionality. There are up to 89 general purpose digital I/O pins available. This corresponds to 104 pins total minus fifteen pins carrying power or ground rails.

These GPIO can be accessed either through the /sys/class/gpio driver in Linux, or directly through register manipulation.

Each GPIO pin has a two corresponding register bits, one in the GPIO data register, and one in the GPIO direction register. The direction register determines if the pin is an output (actively driven) or an input (tri-stated, driven externally). A high ("1") value sets a particular pin to be an output, while a low ("0") value sets it to be an input. The data register, when read, contains the current state of all pins in GPIO mode. When written, the value written will determine the state of all pins in GPIO mode, but only for pins which have their direction set to "output".

The GPIO register map is as follows:

Address Row Register
0xE8000010 A Data
0xE8000014 B Data
0xE8000018 C Data
0xE800001C D Data
0xE8000020 A Direction
0xE8000024 B Direction
0xE8000028 C Direction
0xE800002C D Direction

A simple command-line example to toggle pins on Row A is thus:

#connect an LED from ground (cathode) to Row A pin 2 (andode).
#set row A to all GPIO mode
peekpoke 32 0xe8000030 0x0
#set row A to all output:
peekpoke 32 0xe8000020 0xffffffff
#turn on the pin we attached an LED to with 0b000000010
peekpoke 32 0xe8000010 0x2
#turn off the pin
peekpoke 32 0xe8000010 0x0
#... or turn on the whole row:
peekpoke 32 0xe8000010 0xffffffff

Row A is the row nearest the edge of the board on the longer PC104 socket. Pin 1 is at the end nearest the DB9 connector. From outside (nearest to the edge of the board) to inside (closest to the center of the board) the pin row labels are D, C, A, B. For more pin descriptions and positions, see the master GPIO table.

PC104 16550

Many of our PC104 peripherals interface with the TS-7800-V2 using a 16550 UART. To connect to these devices we provide a generic driver. For example, to use a TS-SER4 with jumpers IRQ2 and IRQ4 on:

source /sbin/ts7800.subr
modprobe ts7800_isa16550 irq=6 io=0x3e8

# On the TS-SER4, we have multiple 16550 devices.  To use
# these, the parameters for each must be specified:
rmmod ts7800_isa16550
modprobe ts7800_isa16550 irq=6,7,6,7 io=0x2e8,0x3a8,0x2a8,0x3a0

After loading dmesg will indicate the new device name for each uart discovered:

 serial8250: **ttyZ2** at MMIO 0xee0002e8 (irq = 123) is a 16550A
 serial8250: **ttyZ3** at MMIO 0xee0003a8 (irq = 124) is a 16550A
 serial8250: **ttyZ4** at MMIO 0xee0002a8 (irq = 123) is a 16550A
 serial8250: **ttyZ5** at MMIO 0xee0003a0 (irq = 124) is a 16550A

Note that the interrupts for the PC104 bus start at #122, so "irq = 123" will be shown when "irq=6" is specified.

FPGA IRQ Controller

The TS-7800-V2 supports 32 MSI IRQs.

IRQ Description
0 dma_cpu_pci_dack_o
1 dma_fpga_dack_o
2 SD Busy#
3 isa_irq3
4 isa_irq4
5 isa_irq5
6 isa_irq6
7 isa_irq7
8 Reserved
9 isa_irq9
10 isa_irq10
11 isa_irq11
12 isa_irq12
13 Reserved
14 isa_irq14
15 isa_irq15
16:26 uart_irqs
31:29 Reserved

While most users should use the IRQ abstractions present in the kernel, this is provided for driver / OS development.

FPGA BASE + 0x200
Offset Description
0x0 Doorbell Address
0x4 MASK (1 = masked)
0x8 IRQ STATUS (1 = asserted)

If unmasked, the IRQ controller will write the (IRQ STATUS & MASK) to the address specified in the doorbell address register, and trigger an MSI. This will also trigger MPP_7.

FPGA MUX Register

The MUX register at 0x4C of the syscon includes a window register for CAN and the PWM core.

The upper 3 bits determine how the remaining bits in this 32-bit register are used.

bits 31:29
Value Description
0x0 Reserved
0x1 PWM Core Write
0x2 Reserved
0x3 Reserved
0x4 CAN Core Read
0x6 CAN Core Write

The PWM access only allows writes and does not allow read back. When a write is issued with (0x1 << 29) set, these bits will map to the PWM core:

Bits Description
23:8 data
7:0 addr

See the #PWM section for more detail on the PWM registers.

For CAN Reads/Writes:

Bits Description
15:8 SJA1000 address
7:0 SJA1000 value (Write data ignored on CAN read)

To read a value from address 0x0 of the SJA1000:

peekpoke 32 0xFC08104C 0x80000000 # Selects CAN Read, writes address 0.  Write values are ignored. 
# Issue reads until bit 31 clears, and then the SJA1000 value is valid
peekpoke 32 0xFC08104C

See the #CAN section for more details, or the SJA1000 datasheet for more details on the CAN registers.

PC/104 Peripherals

With the wide variety of PC104 peripherals available through Technologic Systems' product catalog, some products require supplementary documentation to remain current with newer hardware. This documentation section contains supplementary documentation for Technologic Systems' PC/104 products, and can be considered to be authoritative whenever a conflict arises between the older documentation and this documentation.


Note: This section is new and currently under publishing review. It may change. Technologic Systems advises refreshing this page frequently to ensure the latest information is displayed.

The TS-7800-V2 coincides with enhanced support for the TS-IRIDIUM SBD transceiver module. The TS-IRIDIUM SBD transceiver provides satellite data communication from anywhere in the world provided its antenna has a full, clear view of the sky.

The IRIDIUM satellite constellation consists of 66 low orbit satellites, moving from north to south. For best connectivity, the SBD antenna should have a clear view of approximately 95% of the open sky, or full sky visibility above 8.2 degrees from the horizon.

To check the height of potential obstructions, it is useful to hold a fist at arm's length with the wrist parallel to the horizon. Obstructions larger than that fist above the horizon could interfere with the Iridium signal. Cliffs, buildings, vehicles, and dense foliage will interfere with the satellite signal. Smoke, clouds, fog, rain, and weather will not interfere with the satellite signal.

Iridium infographic.jpg

IRIDIUM Getting Started

To connect to the TS-IRIDIUM modem hardware, configure the TS-IRIDIUM jumper configuration and load the serial port driver thus:

source /sbin/ts7800.subr
modprobe ts7800_isa16550 irq=5 io=0x3f8

Once the driver has been loaded, a quick test of modem functionality can be achieved by using your choice of terminal emulator and querying the modem using some AT commands, for example:

root@ts7800-v2:~# picocom -b 19200 /dev/ttyS12
picocom v1.7

port is        : /dev/ttyS12
flowcontrol    : none
baudrate is    : 19200
parity is      : none
databits are   : 8
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv
imap is        :
omap is        :
emap is        : crcrlf,delbs,

Terminal ready
IRIDIUM 9600 Family SBD Transceiver

Call Processor Version: TA16005

Modem DSP Version: 1.7 svn: 2358

DBB Version: 0x0001 (ASIC)

RFA Version: 0x0007 (SRFA2)

NVM Version: KVS

Hardware Version: BOOT07d2/9602NrvA-D/04/RAW0d

BOOT Version: TA16005 (rev exported)


The modem's IMEI is available using at+gsn. This number identifies the modem on the satellite network and will be used both during setup with the satellite provider, and in sending/receiving data on the modem device.

Theory of Operation

The IRIDIUM SBD system is a satellite radio network primarily used for short data reporting or command and control applications. Network operations are largely obfuscated from the downstream developer such that communication with the modem requires very little software support. Communication with the remote device (mobile terminated messages) is achieved through an email to data@sbd.iridium.com, where the subject is the IMEI of the target IMU, and the message to be sent is a 320 byte file attachment with the suffix ".sbd". Communication from the remote device (mobile originated messages) is achieved by the IMU (the 9602 satellite modem) sending up to 320 bytes to the satellite network. The destination for this data is determined when the satellite account for that modem was set up, and is typically either a short list of email addresses (typically up to 5 email addresses), or a fixed IP network socket.

With this description in mind, a typical round-trip communcaiton might look something like this:

  1. Fixed operator sends an email to data@sbd.iridium.com, subject: 1234567890, file attachment "helloworld.sbd". The Iridium network checks the .sbd file and IMEI (1234567890) for validity and sends it to the satellite network for dissemination to the target IMU.
  2. IMU (the satellite modem) makes periodic checkin and pulls in most recent message from SBD mailbox, updating message counter.
    1. SBC (such as the TS-7800-V2) application reads IMU status and copies MT data from message buffer.
    2. SBC parses message buffer and prepares response.
    3. SBC writes response back to IMU (modem)
  3. IMU performs periodic checkin per SBC instruction and transmits MO (Mobile Originated) message to Satellite network.
  4. Satellite network sends MO message via email to predefined destination email address list (or IP address).
  5. Fixed operator receives email from sbdservice@sbd.iridium.com containing attachment data from IMU 1234567890.


TS-IRIDIUM Jumper Settings

COM and IO Jumpers:

COM Address JP1 JP2 JP3
COM1 0x3F8 Off Off Off
COM2 0x2F8 On Off Off
COM3 0x3E8 Off On Off
COM4 0x2E8 Off On On
COM5 0x3A8 Off Off On
COM6 0x2A8 On Off On
COM7 0x3A0 Off On On
COM8 0x2A0 On On On

PLD Base Address Selection:

JP4 Off JP4 On
0x140 to 0x14F 0x190 to 0x19F

Base + 0 will always return 0x9. This can be used to detect the presence of the board.

Base + 1 will return 0x6 on the first access, 0x7 on the second, 0x8 on the third, and on the 4th access it will return the PLD version.

Base + 2:

Bit Access Function
0 R JP1 On
1 R JP2 On
2 R JP3 On
3 R JP4 On

Base + 3:

Bit Access Function
0 RW Modem Power Toggle
1 R Modem Power Status
2 R LED Status (1 on)
3 R JP5 On


The sbdctl application is an example application that can send and receive data on the IRIDIUM network. It requires an IRIDIUM 9602 modem and an appropriate account through a third-party satellite network provider. The source code example is located on the Technologic Systems public github here.

The sbdctl application uses multiple command line switches, and uses stdin/stdout where input or output are necessary:

root@ts7800-v2:~# sbdctl 
Usage: sbdctl [options] ...
Technologic Systems SBD Control Utility
Status output goes to stderr.  All other IO uses stdin/stdout.
Options are executed in the order given on the command line.
For example:
sbdctl -D <data_len_bytes> -c < myfile.bin
This would read myfile.bin into the MO buffer, then initiate an SBD session
(if possible) to transmit the data to the network.
NOTE:  Maximum input is 340 bytes for either text or binary transmissions.
NOTE2:  The MO and MT buffers can only contain one message each.

 -p, --port </dev/ttyEX1>  Define which serial port to use.
 -c, --connect             Connect to satellite and initiate SBD session.
 -t, --tread               Read text from SBD modem's receive buffer.
 -d, --dread               Read binary data from SBD modem's receive buffer.
 -T, --twrite <len>        Write <len> bytes text data from stdin to SBD modem's transmit buffer.
 -D, --dwrite <len>        Write <len> bytes binary data from stdin to SBD modem's tx buffer.
 -r, --rssi                Request new RSSI reading from SBD modem.
 -s, --status              Get local MO and MT message queue status.
 -e, --events              Enable unsolicited event reporting from modem.
 -i, --info                Dump modem-related info in BASH-compatible variables.
 -x, --indexes             Report message index number for MO and MT.
 -y, --clearindex          Clear Mobile Originated Message Sequence Number.
 -k, --clearbuffers        Clear both MO and MT buffers.
 -l, --clearmobuf          Clear Mobile Originated (MO) buffer.
 -m, --clearmtbuf          Clear Mobile Terminated (MT) buffer.
 -a, --cpymomtbuf          Copy MO to MT buffer on modem.

AT Command Set

When interfacing with the Iridium 9602 SBD directly, the communication protocol is a serial AT command set. The commands supported by the Iridium 9602 are described here in brief. See the official IRIDIUM 9602 modem user's manual for full descriptions (The latest should be available from the satellite service provider).

A/ -- Repeat last AT command.
AT -- Command prefix used for all other commands. Returns "OK<CR><LF>"
En -- Echo characters to DTE. n=0 no echo n=1 echo.
In -- Indentification. Requests ISU to display information about itself.
n=0 2400
n=1 0000
n=2 OK
n=3 "XXXXXXXX" Software revision level (TA16005)
n=4 IRIDIUM 9600 Family
n=5 8816
n=6 "XXX" Factory Identity (1OK)
n=7 "XXXXXXXX" Hardware specification (BOOT07d2/9602NrvA-D/04/RAW0d)
Qn -- Quiet Mode
n=0 ISU responses are sent to the DTE. n=1 ISU resopnses are NOT sent to the DTE.
Vn -- Verbosity
n=0 Numeric responses n=1 Text responses.
Zn -- Soft Reset
n=0 restore config 0 n=1 restore config 1.
%R -- Displays all S registers
&Dn -- DTR Control
n=0 DTR off, n=1 DTR on (DTR not supported on TS-IRIDIUM)
&Fn -- Restore Default Configuration (n = 0 or 1)
&Kn -- Flow Control
n=0 Disable n=3 RTS/CTS N=4 XON/XOFF n=6 Both
&V -- View active and stored configurations.
&Wn -- Store Active Configuration in profile slot n (0 or 1)
&Yn -- Designate default reset profile (0 or 1)
*F -- Flush to Eeprom
Modem shutdown prep / save volatile buffer data.
*Rn -- Radio Enable
n=0 disable radio n=1 enable radio.
+CCLK -- Real-Time Clock
+CCLK? -- Query RTC (see +cclk).
+CGMI -- Query Manufacturer Information
+CGMM -- Model Identification
+CGMR -- Query Revision Information
+CGSN -- Query IMEI
+CIER -- Unsolicited Event Reporting
Causes modem to actively report changes in status when changes are detected.
mode 0=disable 1=enable. See IRIDIUM documentation for more detail.
+CRIS -- Ring Indication Status
tri not used on 9602
sri: 0=no ring, 1=ring
timestamp = number of seconds since IRIDIUM epoch.
+CSQ -- Signal Quality
+CSQ: 0-5 signal quality rating. 0=none 5=best
+CULK=n-- Unlock.
n=unlock code given by network provider.
+CULK? -- Query if unlock is needed.
0 = not locked (all modems shipped from Technologic Systems are unlocked).
+GEMON -- Power Consumption Meter.
+GEMON function was removed by Iridium in firmware version TA16005.
+GMI -- Get Manufacturer Information. See +CGMI.
+GMM -- Get Model Information. See +CGMM
+GMR -- Get Revision Information. See +CGMR
+GSN -- Get IMEI. See +CGSN
+IPR=n -- ISU Data rate (default 19200 baud).
+IPR=<rate> rates from 0=600 baud to 7=38400 baud. 6 is default at 19200 baud.
+SBDAREG=n -- Short Burst Data Automatic Registration. +SBDAREG=<mode>
0=disable 1=automatic 2=ask 3=auto w/event report 4=ask w/event report
See IRIDIUM documentation.
+SBDC -- Clear MOMSN (Mobile Originated Message Sequence Number).
+SBDDn -- Short Burst Data Clear SBD Message Buffer(s) +SBDD[<type>]
n=0 clear MO buffer n=1 clear MT buffer n=2 clear both buffers
Caveats: See IRIDIUM documentation.
+SBDDET -- Detach ISU from Gateway. See docs for error list.
+SBDDSC -- Delivery Short Code.
IRIDIUM documentation.
+SBDI -- Initiate SBD session.
Connect ISU to ESS, download oldest message from ESS to MT buffer.
Transmit/upload MO buffer to ESS. ISU is modem, ESS is satellite service.
Detach automatically after operation complete.
See IRIDIUM documentation.
+SBDIX -- Extended SBDI.
Required if using SBD Ring Alerts. See IRIDIUM documentation
+SBDMTA -- Mobile-terminated alert
enable/disable ring alerts +sbdmta=0 disable =1 enable see docs.
+SBDRB -- Read binary data from ISU. outpts MT binary. Format is high order byte first
{2-byte length} + {binary message} + {2 byte checksum}
Caveats. See docs.
+SBDREG -- Force manual network registration. Optional include location data.
+sbdreg[=<location>] where <location> is [+|-] DDMM.MMM,[+|-]ddmm.mmm
DD deg lat (00-89) MM minutes lat (00-59) MMM 1/1000 min lat (000-999)
ddd deg lon (000-179) mm min lon (00-59) mmm 1/1000 min lon (000-999)
Resonse is +SBDREG:<status>,<err> 0=det 1=not reg 2=reg 3=denied, 0=no err
See below for error code list.
+SBDREG? -- Check for current registration.
0=detached 1=not reg'd 2=reg'd 3=reg denied
+SBDRT -- Read text from MT buffer.
Format: +SBDRT:<CR>{MT buffer}
+SBDS -- Checks state of MT and MO buffers.
Response +SBDS:<MO flag>,<MOMSN>,<MT flag>,<MTMSN>
Flags: 0=no message 1=message in buffer MTMSN=-1 means nothing in buffer.
+SBDST -- Set Session Timeout
+sbdst=<timeout> in seconds. See IRIDIUM documentation.
+SBDSX -- SBD Status Extended. It's +sbds with ring alert status and waiting msg count.
Note waiting msg count updated after every SBD session (sbdi/sbdix/sbdreg/sbddet).
+SBDTC -- Transfer MO buffer to MT buffer.
Mostly used to test software without using satellite network.
+SBDWB -- Write binary to ISU MO buffer.
+sbdwb=[<sbd msg len in bytes>] len does not inc checksum.
Modem will respond "READY<CR><LF>"
Send {binary sbd message} + {2 byte checksum}.
Checksum calculation is least significant 2 byte sum of whole message.
Send high order byte first.
example: "hello" in ascii would be sent as:
hex 68 65 6c 6c 6f 02 14
Modem will emit 0 on success, 1 on timeout of 60 seconds.
+SBDWT -- Write text message to ISU MO buffer.
Two usages:
  • +sbdwt alone will allow full length 340 bytes
Modem will emit "READY<CR><LF>" After <LF> send text message terminated by <CR>.
  • +sbdwt=[<text message>] <text message> maximum 120 bytes if sent this way.
Modem will emit "OK" on success or "ERROR" if something went wrong.
+SBDGW[n] -- Query what gateway this iridium is configured to use.
Responses are +SBDGW <gateway_text> either "EMSS" or "non-EMSS".
if 'n' version is used: +SBDGWN: <1 or 2>. n=1 default commercial gateway. n=2 some other gateway.
+SBDLOE -- Iridium Traffic Management Status.
Returns +SBDLOE:<status>,
If traffic management is NOT in effect,
-MSGEO -- Request Geolocation. Response -MSGEO
x,y,z is geolocation grid code from a Cartesian coordinate system.
The axes are aligned suhch that at 0 lat and 0 lon, both y and z are 0 and x is +6376, representing the nominal earth radius in KM. Coords are minimum -6376, max +6376, with a resolution of 4.
-MSSTM -- Request System Time.
32 bit integer expressing number of seconds since the most recent Iridium Epoch Rollover. Should not be used to calculate current date and time. Use +cclk for current date and time.
Status Codes
AT+SBDIX Status Codes
<these come from the gateway>
0: MO message successful send.
1: MO message sent successful, but the MT message queue was too big to receive.
2: MO message sent, but requested location update was not accepted.
3-4:Reserved, but indicates MO session success.
5-8:Reserved, but indicates MO session failure.
10: Gateway reported timeout.
11: MO message queue full at gateway.
12: MO message has too many segments.
13: Gateway reported session did not complete.
14: Invalid segment size.
15: Access Denied!
<these come from the transceiver>
16: Transceiver is locked and may not make SBD calls (see +CULK). AKA call the service provider.
17: Gateway not responding (local session timeout).
18: Connection lost (RF drop).
19-31: Reserved, but indicate MO session failed.
32: No network service, unable to initiate call.
33: Antenna fault, unable to initiate call.
34: Radio is disabled, unable to initiate (turn on the radio with at*r1).
35: Transceiver is busy, try again (transceiver is probably doing auto-negotiation).
36: Reserved, but indicates failure.

Checking the Hardware

To sanity-check the TS-IRIDIUM without transmitting messages over the satellite network, the IRIDIUM module includes a data transfer function, copying data from the transmit buffer to the receive buffer. The sbdctl utility can be used to exercise this function:

root@ts7800-v2:/u/home/mpeters/code/iridium# sbdctl --info
root@ts7800-v2:/u/home/mpeters/code/iridium# sbdctl -D 10 < qwerty.txt
root@ts7800-v2:/u/home/mpeters/code/iridium# sbdctl -a
root@ts7800-v2:/u/home/mpeters/code/iridium# sbdctl -d | hexdump -c
0000000   q   w   e   r   t   y   u   i   o   p 004   i


Note: This section is still under construction and may contain internal engineering notes, typos, and other developmental artefacts.

When used on the TS-7800-V2, the TS-NVRAM should be configured for linear, non-paged memory access using 16 bit memory access mode. Care should be taken that the jumper configuration matches the software register descriptions (16 bit, non-paged). The IO memory address can be set where the downstream developer likes, and 8 bit IO access is recommended for reading and setting the IO mapped registers at offsets 0x0 through 0x5. Nonvolatile memory, when properly configured, will appear at 0xf9000000 through 0xf9100000 or 0xf9200000 depending on whether the TS-NVRAM2 was configured with one or two megabytes of RAM.

Serial Ports

The TS-7800-V2 has 10 UARTs. Two of these UARTs, which appear on the COM1 (DB9) header and the COM2 (10-pin) header are driven by the CPU. Under Linux these show up under /dev as ttyS0 and ttyS1. The other 8 UARTs are driven by the FPGA. Under Linux these show up under /dev as tttsn where n is the UART number listed in the table below.

Please note that the pin numbering on the 10 pin COM headers is as shown here:

6 7 8 9 10
1 2 3 4 5

When some UART ports are enabled, they override the meanings of other pins with their own meanings. When disabled, the pins revert to their original meaning. The table below describes the ten UART ports. The "Type" column indicates whether the port is RS-232, RS-485/422, or TTL.

WARNING: Pay special attention to the pin definitions on this chart. These definitions are made specifically for compatibility with the original TS-7800 and may not match other TS products.

Note, unless otherwise specified, the port numbering is for /dev/tttsN where N is the port number below.

Number Type Connector TX RX TXEN
ttts0 RS232 DB9 7 8 N/A
ttts1 RS232 DB9 4 1 N/A
ttts2 RS485/RS422 COM2 +6 -1 +4 -9 N/A
ttts3 RS485 COM2 +4 -9 N/A N/A
ttts4 RS232 COM3 3 2 N/A
ttts5 RS232 COM3 7 8 N/A
ttts6 TTL DIO 13 15 11
ttts7 TTL LCD 13 14 12
ttts8 TTL[1]<[2] PC104 C17 C18 C16
ttts9 TTL[3][2] PC104 C14 C15 C13
/dev/ttyS0 CONSOLE[3] DB9 3 2 N/A
/dev/ttyS1 RS-232 COM2 3 2 N/A
  1. If the WIFI_RESET bit in SYSCON is set to a 1, then ttts8 is routed instead to the wifi/bluetooth module, and is no longer available as a general-purpose serial port.
  2. 2.0 2.1 This port's default mapping is disabled when PC104 is active. The port can still be used when routed to its alternate pin definition.
  3. 3.0 3.1 The location of ttts9 depends on the EN_CON jumper. If populated, ttts9 behaves as documented above. If the jumper is depopulated, /dev/ttts9 is routed instead as RS232 to DB9 pins 3(TX) and 2(RX).

You can select RS-422 on port 2 by setting bit 15 of register 0xe800000C to 1. If it is 0, it will default to RS485. Setting port 2 to RS422 mode will cause port 3 to become read-only while port 2 will take the rx data from port 3 and become full-duplex per RS422 specification.

For ports ttts6 through ttts9, automatic TXEN is enabled by setting the associated GPIO pin to "out" and set 0. For example:

root@ts7800-v2:~# echo 73 > /sys/class/gpio/export
root@ts7800-v2:~# echo "out" > /sys/class/gpio/gpio73/direction
root@ts7800-v2:~# echo 0 > /sys/class/gpio/gpio73/value

The above sets the DIO_11 pin (ttts6 TXEN) to output low when idle. When properly connected to an RS485 transceiver, this signal will automatically go high when the UART is transmitting, and return to LOW when the UART has finished transmitting, allowing the transceiver and UART to immediately begin receiving any response on the wire.


RTS and CTS are higher order flow control signals defined in the RS-232 specification for 5- 7- and 9- wire RS-232 serial communication. These signals are not implemented on the TS-7800-V2, but can be "bit banged" when needed. The COM3 header provides pins 7 and 8 as GPIO for this usage. For further usage details about COM3 pins 7 and 8, see also the syscon register 0xC, bit 13.

Arbitrary Baud Rate

The Linux driver for the 16550 UART only allows for speeds up to 115200, however, the hardware is capable of supporting faster speeds such as ~921600 baud. To enable a higher data rate, we replace all data rate settings offset by your chosen baud rate, which replaces the maximum rate of 115200. Multiply your desired baud rate by 16, and write that value to Syscon offset 0x48. Then choose which ports (from the table above) you wish to have using the alternative baud rate and set the appropriate bit(s) in syscon 0x5c bits 10:0. For example, to achieve a baud rate of 230400, set the UART to 115200 in C or in the OS, and have this apply to ttts1 then do this:

#replaces 115200 bps setting globally with 230400
peekpoke 32 0xfc081048 $((230400*16))
peekpoke 32 0xfc08105c 0xFD
Note: The arbitrary baud rate setting is selectable on a per-port basis, however there is only one arbitrary rate. All ports set to use the arbitrary rate setting will use the same setting. Use SYSCON 0x5c, bits 10:1 to set which ports are to use the arbitrary baud rate setting. Bit 0 corresponds to port 0, and so on.
Note: The current maximum rate available using the arbitrary baud rate generator is approximately 1 megabit per second.

Realtime Clock

Prototype P2: The TS-7800-V2 uses the Realtime Clock on the Marvell 88F6820. Linux supports this RTC with the armada38x-rtc driver.

Revision A: The TS-7800-V2 uses an M41T00S Realtime Clock. Linux supports this RTC with the rtc_ds1307 driver.

To set the RTC, first set the system time, then use hwclock --systohc to set the hardware RTC. To set the system time from the RTC, use hwclock --hctosys.

Temperature Sensor

The TS-7800-V2 uses the temperature sensor in the SiLabs microcontroller. This device has an I2C interface to the CPU. The temperature may be read with the ts7800ctl utility

ts7800ctl -t

The temperature is printed in millicelsius.


The TS-7800-V2 offers optional WiFi (and Bluetooth) using an | Atmel ATWILC3000-MR110CA IEEE 802.11 b/g/n Link Controller Module With Integrated Bluetooth® 4.0. Linux provides support for this module using the wilc driver.

Note: This driver is automatically loaded and configured by the default TS-7800-V2 image when the correct hardware is present. This section is provided for informative purposes.

Summary features:

  • IEEE 802.11 b/g/n RF/PHY/MAC SOC
  • IEEE 802.11 b/g/n (1x1) for up to 72 Mbps PHY rate
  • Single spatial stream in 2.4GHz ISM band
  • Integrated PA and T/R Switch Integrated Chip Antenna
  • Superior Sensitivity and Range via advanced PHY signal processing
  • Advanced Equalization and Channel Estimation
  • Advanced Carrier and Timing Synchronization
  • Wi-Fi Direct and Soft-AP support
  • Supports IEEE 802.11 WEP, WPA, and WPA2 Security
  • Supports China WAPI security
  • Operating temperature range of -40°C to +85°C

To install the driver, run the following command:

modprobe wilc-spi

See the WiFi Client and WiFi Access Point sections for more details on connecting to networks.


The TS-7800-V2 includes a watchdog on the supervisory microcontroller. This is armed immediately from power on for 10 seconds. As soon as U-boot loads it will start feeding the watchdog. U-boot will feed for 60 seconds every 1 second. Once Linux takes over, there is a kernel driver which can feed the watchdog. This must be initiated by userspace. By default we use the watchdog software daemon to handle feeding.

To take over feeding in your application entirely, remove the "watchdog" daemon. The kernel provides an interface to the watchdog driver at /dev/watchdog. Refer to the kernel documentation for more information on interfacing with this directly:


The Wi-Fi option for this platform also includes a Bluetooth 5.0 LE module. Support for Bluetooth is provided by the BlueZ project. BlueZ has support for many different profiles for HID, A2DP, and many more. Refer to the BlueZ documentation for more information.

Both Wi-Fi and Bluetooth can be active at the same time on this platform. Note however, that either the Wi-Fi interface needs to be not brought up if Wi-Fi is unused, or it needs to actively connect to an access point or act as an access point. The Bluetooth module can be activated with the following commands:

# Install bluez if it is not already present
apt-get update
apt-get install bluez bluez-tools

# Enable Bluetooth, and load the firmware
echo BT_POWER_UP > /dev/wilc_bt
sleep 1
echo BT_FW_CHIP_WAKEUP > /dev/wilc_bt
sleep 1
echo BT_DOWNLOAD_FW > /dev/wilc_bt
sleep 1

# On Debian Stretch
hciattach /dev/ttts8 any 115200 noflow
# If using Debian Buster or newer, or BlueZ built from newer sources, the following can be used instead
# btattach -N -B /dev/ttts8 -S 115200

sleep 1

At this point, the device is fully set up ready to be controlled by various components of BlueZ tools. For example, to do a scan of nearby devices:

power on
scan on

This will return a list of devices such as:

root@ts-imx6ul:~# bluetoothctl  
Agent registered
[CHG] Controller F8:F0:05:XX:XX:XX Pairable: yes
[bluetooth]# power on
Changing power on succeeded
[CHG] Controller F8:F0:05:XX:XX:XX Powered: yes
[bluetooth]# scan on
Discovery started
[CHG] Controller F8:F0:05:XX:XX:XX Discovering: yes
[NEW] Device 51:DD:C0:XX:XX:XX Device_Name
[NEW] Device 2A:20:E2:XX:XX:XX Device_Name
[CHG] Device 51:DD:C0:XX:XX:XX RSSI: -93
[CHG] Device 51:DD:C0:XX:XX:XX RSSI: -82
[NEW] Device E2:08:B5:XX:XX:XX Device_Name
[CHG] Device 51:DD:C0:XX:XX:XX RSSI: -93
[CHG] Device 2A:20:E2:XX:XX:XX RSSI: -94
[NEW] Device 68:62:92:XX:XX:XX Device_Name
[NEW] Device 68:79:12:XX:XX:XX Device_Name
[bluetooth]# quit

The module supports some other commands as well:

# Allow the BT chip to enter sleep mode
echo BT_FW_CHIP_ALLOW_SLEEP > /dev/wilc_bt

# Power down the BT radio when not in use
echo BT_POWER_DOWN > /dev/wilc_bt


The TS-7800-V2 offers optional 3-axis Accelerometer, using a Freescale MM8451 chip. The device may be accessed via the i2c bus, at slave-address 0x1C. The ts7800ctl program also has an option to display the acceleration value for the X,Y, and Z axes.

ts7800ctl -a                                 

Alternatively, you may use the kernel driver for the MMA8451...

modprobe mma8451

Now the chip may be accessed through the kernel 'event' interface: That is, events from the chip may be read from "/dev/input/event0".

Status LEDs

There are two status LEDs (one green, one red, next to the 5V power input near the PC104 header) on the TS-7800-V2. Both are normally quiescent (un-lit) in the default shipping image. The downstream developer has complete liberty to define the behavior of these LEDs in their software.

Default behavior of the LEDs is the red LED will blink once during during U-Boot load, then illuminate and stay on as U-Boot begins to execute. All other activity is defined by the downstream developer.

There is also one green status LED at the rear of the SBC near the micro USB port. This LED will illuminate when there is power to the SBC and flicker during various bus activities. This cannot be controlled by the downstream developer.

Simple control of the two LEDs is provided in the ts7800ctl software

Auxiliary Power Source

A 5-volt power supply is available on CN1 (if populated). Power to this header is controlled by GPIO #43. To turn on the power:

echo 43 > /sys/class/gpio/export 
echo out > /sys/class/gpio/gpio43/direction
echo 1 > /sys/class/gpio/gpio43/value

To turn it off again:

echo 0 > /sys/class/gpio/gpio43/value


The linux kernel provides a "bit-banging" SPI driver, which uses GPIO pins, including those that are presented on the DIO, LCD, and PC/104 connectors. The default device-tree for the TS-7800-V2 includes the configuration required to connect any SPI device to the DIO connector. The device tree can be modified to use any normal GPIO pin defined through the dtsi entry below:

 spi_gpio@0 {
  compatible = "spi-gpio";
  #address-cells = <0x1>;
  #size-cells = <0>;
  num-chipselects = <1>;

  cs-gpios  = <&ts7800v2_gpio 4  GPIO_ACTIVE_LOW>; /* CN8 pin  6*/
  gpio-miso = <&ts7800v2_gpio 8  GPIO_ACTIVE_HIGH>; /* CN8 pin 10*/
  gpio-mosi = <&ts7800v2_gpio 10  GPIO_ACTIVE_HIGH>; /* CN8 pin 12*/
  gpio-sck  = <&ts7800v2_gpio 12  GPIO_ACTIVE_HIGH>; /* CN8 pin 14*/
  status = "okay";
  spi_offboard: spi_offboard@0 {
    compatible = "spidev";
    reg = <0>;
    spi-max-frequency = <1000000>;
    status = "okay";

The external device will appear as '/dev/spidev32766' or similar. You may interact with your device using the standard linux SPI API. The source code for a simple command-line-driven utility can be found in the kernel source tree, in the 'Documentation/spi' directory.

If a kernel driver exists for your external SPI device, you may choose to use that. For example, if you have an AT25-compatible EEPROM connected, then you can use the kernel's at25 driver. The device tree will need to be modified: Remove the 'spi_offboard' block completely, and replace it with the following...

   eeprom: at25@0 {
     compatible = "atmel,at25";
     at25,byte-len = <0x8000>;
     at25,addr-mode = <2>;
     at25,page-size = <64>;

     reg = <0>;
     spi-max-frequency = <1000000>;
     status = "okay";

Rebuild the kernel, and copy the 'arch/arm/boot/dts/armada-385-ts7800-v2.dtb' file to the '/boot' directory on the board, and reboot. After inserting the at25 kernel module (use 'modprobe at25') the EEPROM should appear as '/sys/class/spi_master/spi32765/spi32765.0/eeprom', or similar.

To use a different configuration, perhaps for different pins, or a different SPI device, the device-tree must be modified and the kernel recompiled. For more information on spidev, please see the kernel.org documentation here.


The linux kernel has a "bit-banging" I2C driver, which can use any GPIO pin, including those that are presented on the DIO, LCD, and PC/104 connectors. The default device-tree for the TS-7800-V2 includes the configuration required to connect an off-board I2C OLED display to the DIO connector. The TS-7800-V2 does not provide CPU-native I2C.

i2c_gpio@0 {
      compatible = "i2c-gpio";
      gpios = <
         &ts7800v2_gpio 0 GPIO_ACTIVE_LOW /* sda = CN8 pin 1*/
         &ts7800v2_gpio 1 GPIO_ACTIVE_LOW /* scl = CN8 pin 3*/

      status = "okay";
      i2c-gpio,delay-us = <2>;	/* ~100 kHz */
      #address-cells = <1>;
      #size-cells = <0>;

      ssd1306: oled@3c {   /* Used for a generic OLED display on i2c */
         compatible = "solomon,ssd1306fb-i2c";
         reg = <0x3c>;
         reset-gpios = <&ts7800v2_gpio 11 0>;   // CN8 pin 13
         solomon,height = <64>;
         solomon,width = <128>;
         solomon,page-offset = <0>;
         solomon,com-offset = <0>;
         solomon,prechargep1 = <1>;
         solomon,prechargep2 = <0xF>;
         status = "okay";

With such an display connected, run "modprobe ssd1307fb" and the display will be available as a framebuffer device at /dev/fb0.

For more information on programming with the i2c-dev interface, please see the kernel.org documentation here.


The TS-7800-V2 includes one SJA1000 compatible CAN controller in the FPGA. This is supported in the kernel through the socketcan interface. This port is available at COM3 pins 4 (CAN_H) and 9 (CAN_L).

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

   modprobe ts7800v2-can
   ip link set can0 type can bitrate 125000
   ifconfig can0 up
   cansend can0 123#

The remaining two examples rely on using a specific ODB Simulator device:

## First, set the baud rate and bring up the device:
ip link set can0 type can bitrate 250000
ip link set can0 up

## Dump data & errors:
candump can0 &

## Send the packet with:
#can_id = 0x7df
#data 0 = 0x3
#data 1 = 0x1
#data 2 = 0x0c
cansend can0 -i 0x7Df 0x3 0x1 0x0c
## Some versions of cansend use a different syntax.  If the above
## commands gives an error, try this instead:
#cansend can0 7DF#03010C

The above example packet is designed to work with the Ozen Elektronik myOByDic 1610 ECU simulator to read the RPM speed. In this case, the ECU simulator would return data from candump with:

 <0x7e8> [8] 04 41 0c 60 40 00 00 00 
 <0x7e9> [8] 04 41 0c 60 40 00 00 00 

In the output above, columns 6 and 7 are the current RPM value. This shows a simple way to prove out the communication before moving to another language.

The following example sends the same packet and parses the same response in C:

#include <stdio.h>
#include <pthread.h>
#include <net/if.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <linux/can.h>
#include <linux/can/raw.h>

int main(void)
	int s;
	int nbytes;
	struct sockaddr_can addr;
	struct can_frame frame;
	struct ifreq ifr;
	struct iovec iov;
	struct msghdr msg;
	char ctrlmsg[CMSG_SPACE(sizeof(struct timeval)) + CMSG_SPACE(sizeof(__u32))];
	char *ifname = "can0";
	if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
		perror("Error while opening socket");
		return -1;
	strcpy(ifr.ifr_name, ifname);
	ioctl(s, SIOCGIFINDEX, &ifr);
	addr.can_family  = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;
	if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		return -2;
 	/* For the ozen myOByDic 1610 this requests the RPM guage */
	frame.can_id  = 0x7df;
	frame.can_dlc = 3;
	frame.data[0] = 3;
	frame.data[1] = 1;
	frame.data[2] = 0x0c;
	nbytes = write(s, &frame, sizeof(struct can_frame));
	if(nbytes < 0) {
		return -3;

	iov.iov_base = &frame;
	msg.msg_name = &addr;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = &ctrlmsg;
	iov.iov_len = sizeof(frame);
	msg.msg_namelen = sizeof(struct sockaddr_can);
	msg.msg_controllen = sizeof(ctrlmsg);  
	msg.msg_flags = 0;

	do {
		nbytes = recvmsg(s, &msg, 0);
		if (nbytes < 0) {
			return -4;

		if (nbytes < (int)sizeof(struct can_frame)) {
			fprintf(stderr, "read: incomplete CAN frame\n");
	} while(nbytes == 0);

	if(frame.data[0] == 0x4)
		printf("RPM at %d of 255\n", frame.data[3]);
	return 0;

See the Kernel's CAN documentation here. Other languages have bindings to access CAN such as Python, Java using JNI.

In production use of CAN we also recommend setting a restart-ms for each active CAN port.

ip link set can0 type can restart-ms 100

This allows the CAN bus to automatically recover in the event of a bus-off condition.

SocketCAN Driver for TS-7800-V2

The Linux Kernel provides upstream compatibility for ISA-based SJA1000 CAN controllers. This driver can make up to three TS-CAN1 peripherals show up as network devices in Linux thus:

root@ts-7800-v2:~# ifconfig can1
can1: flags=128<NOARP>  mtu 16
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 10  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 123  base 0x100


The driver module is provided already installed in all embeddedTS software packages that supports SocketCAN with the TS-CAN1. Set the PLD registers for operation and load the driver with the appropriate comma-separated IO and IRQ configurations (commas only necessary for multiple TS-CAN1). Example, for one TS-CAN1 used on the TS-7800-V2:

root@ts-7800-v2:~# source /sbin/ts7800.subr   #load the TS-7800-V2 BASH Macro set
root@ts-7800-v2:~# pc104on                    #enable PC104 with the appropriate macro
root@ts-7800-v2:~# peekpoke 8 0xfa000150      #Check the peripheral ID for presence of the TS-CAN1
root@ts-7800-v2:~# peekpoke 8 0xfa000155 0x40 #Enable SJA1000 functions on PC104 IO offset 0x100
root@ts-7800-v2:~# modprobe sja1000_isa mem=0xfa000100 irq=123 clk=25000000
[   92.146672] sja1000_isa sja1000_isa.0: sja1000_isa device registered (reg_base=0xf1634100, irq=123)
[   92.159233] Legacy sja1000_isa driver for max. 8 devices registered

Two TS-CAN1 would be very similar to the above example, instead set up each TS-CAN1 with addreses separately, then call the driver just once with the list of TS-CAN1 to be instantiated:

root@ts-7800-v2:~# modprobe sja1000_isa mem=0xfa000100,0xfa000200 irq=6,6


The TS-7800-V2 uses a Linux sysfs GPIO driver to access all GPIO. See the master gpio table for information on disambiguation of GPIO numbers and pin names. The Linux Kernel Sysfs GPIO driver is documented at kernel.org here: https://www.kernel.org/doc/Documentation/gpio/sysfs.txt

In the most general of sense, a GPIO on the TS-7800-V2 is treated the same as a set of files in the filesystem. Here is an example in Bash to set and clear DIO_4 (CN8 pin 4) as an output, and then read the value of DIO_5 as an input:

root@ts7800-v2:~# echo 66 > /sys/class/gpio/export  # DIO_4 is GPIO number 66
root@ts7800-v2:~# echo 67 > /sys/class/gpio/export  # DIO_5 is GPIO number 67
root@ts7800-v2:~# echo "out" > /sys/class/gpio/gpio66/direction
root@ts7800-v2:~# echo "in" > /sys/class/gpio/gpio67/direction
root@ts7800-v2:~# echo 1 > /sys/class/gpio/gpio66/value
root@ts7800-v2:~# echo 0 > /sys/class/gpio/gpio66/value
root@ts7800-v2:~# cat /sys/class/gpio/gpio67/value  # DIO_5 has a nominal pull-up to 3.3.

In this manner, dio4 and dio5 could be wired together to demonstrate both functionalities simultaneously. Run the above example, then wire CN 8 pin 4 and CN 8 pin 5 together, and confirm functionality thus:

root@ts7800-v2:~# echo 0 > /sys/class/gpio/gpio66/value
root@ts7800-v2:~# cat /sys/class/gpio/gpio67/value
root@ts7800-v2:~# echo 1 > /sys/class/gpio/gpio66/value
root@ts7800-v2:~# cat /sys/class/gpio/gpio67/value

Note: The GPIO functionality of any pin will be overridden by other drivers, such as the userspace SPI and I2C drivers. If a GPIO is not responding as expected, check the device tree to see if another driver already has that pin taken. Normally when this is the case, an attempt to modify the GPIO through sysfs will generate a "busy" error in the OS.

External Interfaces

DIO Header

Access to the DIO header is described here. These pins can be driven low, otherwise they are inputs with pull-up resistors. The pull-ups are via 2.2k Ohms on the odd numbered pins 1-15. Pin 10 has a 10k pull-up and is a read-only input. The rest are pulled up by the FPGA through 20k-150k nominal resistance. The pinout for the DIO header is shown below.

DIO Header
2 4 6 8 10(RO) 12 14 16
1 3 5 7 9 11 13 15
DIO_01 DIO_03 DIO_05 DIO_07 DIO_09 DIO_11 DIO_13 DIO_15

LCD Header

This header is laid out to drive our LCD-LED product. The file tolcd.c in our samples directory demonstrates this. Like the DIO header, pins 7-14 can be driven low, otherwise they tri-state with a 2.2k Ohm pull-up. Pins 4 and 5 are pulled up by 475 Ohm and 51 Ohm inline resistance, respectively.

LCD Header
2 4 6 8 10 12 14
1 3 5 7 9 11 13

Ethernet Port

The MV88F6820 Ethernet LAN controller incorporates all the logic needed to interface directly to the low-power Marvell 88E1512 Ethernet PHY, which in turn is connected to the integrated RJ-45 connector with built-in 10/100/1000 transformer and LED indicators.

The RJ-45 connector has a pair of built-in LEDs, both of them green. By default, the LED on the left indicates link status (on=link; off=no link), and the LED on the right indicates activity. The 88E1512 PHY supports many other configurations for these LEDS, such as blinking the link LED once, twice, or three times, to indicate 10, 100, or 1000 Gbps, respectively. See the 88E1512 datasheet for more details.

Note: TS-Kernel provides all the software support to use the MV88F6820 10/100/1000 Ethernet core. For more details, find the TCP/IP configuration instructions on the Linux documentation.

SD Connectors

There is a micro-SD connector on the top of the TS-7800-V2, and a full-size SD connector on the underside. These connectors are wired in parallel, which means that only one of them may have a card installed at any given time. The card shows up as /dev/tssdcarda on the TS-7800-V2.

SD Memory Card technology provides large capacity and fast access combined with a compact and slim profile, making it very appealing for a wide range of next generation products and applications. In addition, SD Cards feature content protection, planned capacity growth, high-speed data transfer, and a write protect switch. These devices supply additional non-volatile storage either for data or for a complete operation system distribution, such as Debian, to be used with the TS-7800-V2 SBC.

The TS-7800-V2 fully supports SDHC cards as well.

mSATA / Mini Card Connector

Some variants of the TS-7800-V2 include a mini card connector. This interface provides mSATA and USB for cell modem and mSATA integration. This interface does not support PCIe.

See the schematic page 24 for pinout details.

Power Supply Connector

The TS-7800-V2 requires regulated 5VDC at minimum 2000 mA. This power can enter the SBC in a number of ways. The default and most direct method of powering the SBC is through the press-fit screw terminal connector at CN4. The power inlet at CN4 presumes external protection and fully conditioned 5 VDC with a recommended minimum of 2000 mA available current.

WARNING: Supply voltages of 6 VDC or more on the 5 VDC power rail may damage the TS-7800-V2. This product will tolerate no more than 5% over the specified voltage for a given signal net.

Be sure to use a regulated 5 VDC power supply, preferably with current limiting to 2 to 3 Amps. A current-limited supply is very forgiving of common errors during development. A PC power supply that may be capable of supplying 20 Amps or more is not recommended. It is possible to do irreversible damage to the TS-7800-V2 if the polarity of the supply is reversed.

The second method of providing power to the SBC is through the optional TS-781 power adapter. This is a soldered-on option installed while building the SBC. The TS-781 requires 8-38 VDC external power and converts the external power to a clean 5 VDC intended for use by the TS-7800-V2 and its peripherals. Note this device provides excellent power conditioning, but ferrite beads for external EMI noise abatement are still recommended, and the extended range power option does not provide reverse-polarity protection. When the TS-781 extended power input option is in use, there is a mechanical conflict with the USB Serial console. The downstream developer should be prepared to obtain console via RS232 on the DB9 connector at the front of the SBC.

A third method of providing power to the SBC is through a peripheral such as the TS-13W or TS-BAT10. These devices provide their own methods for power input and inject power onto the 5 VDC signal net through the PC104 connector. If using a tertiary method for provisioning power to the SBC please consult the product manual for that peripheral, with the understanding that the TS-7800-V2 must not exceed 5.2 VDC on the 5 VDC main power rail, and we advise current-limiting input power to 2 to 3 amps, as discussed above.

DB9 Connector

The DB9 connector brings out 1 CPU serial port (COM1, /dev/ttyS0, by default the Linux console) and 2 other RS-232 UARTs. Tx and Rx signals for COM1 are on pins 3 and 2. All signals are at RS-232 levels. See the Serial Ports section for pinout details.

TS-7800-V2 DB9.jpg

USB Host Connectors

The USB Connectors on the TS-7800-V2 provide two USB 3.0 interfaces. These operate at a baud rate of up to 5 Gbit/s ("SuperSpeed"). The host-controller also provides full compatibility with USB 2.0 at speeds up to 480 Mbits/sec ("High-Speed").

USB Power can be controlled via CPU GPIO #45. This control is useful for resetting errant USB devices, or for temporary power saving efforts when operating in power-limited environments (such as limited battery power).

echo 45 > /sys/class/gpio/export                 #Enables software control of USB power
echo "out" > /sys/class/gpio/gpio45/direction    #Default USB power is off in this mode.
echo 1 > /sys/class/gpio/gpio45/value            #turns USB power on.
echo 0 > /sys/class/gpio/gpio45/value            #turns USB power off.

Micro USB Connector

The micro USB connector provides the downstream developer with a dedicated USB Serial console interface. This port will always echo the activity of ttyS0, and the interface at the CN12 (USB Mini) location is available regardless of the status of the EN_CON jumper.

COM2 Header

The COM2 header brings out COM2, /dev/ttyS1, with Tx and Rx on pins 3 and 2 at RS-232 levels. RS-485 (or RS-422) ports are also available on this header. See the Serial Ports section for more details.

TS-7800-V2 COM2.jpg

COM3 Header

The COM3 header brings out two UARTs at RS-232 levels. See the Serial Ports section for more details. CAN is also on this header at pins 4 (CAN_H) and 9 (CAN_L).

TS-7800-V2 COM3.svg

A/D Header

The A/D header makes available 5 channels of 10 bit resolution A/D conversion. See the #ADC Sampling section for more details.

The A/D header is laid out as follows:

2 4 6 8 10
1 3 5 7 9

PC104 Header

The PC-104 connector consists of pins in four rows labeled A, B, C, and D. The numbering of the pins in each row is shown below, with the low numbers being nearest the RTC Battery:

D 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
C 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
A 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01
B 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01

The PC-104 connector can be multiplexed between different functionalities including ISA bus and GPIO. The power-up default is GPIO mode, with all I/Os in a neutral state. To enable the PC-104 bus (ISA) signals, it is necessary to write the following values to the registers specified:

 0x55555555 to address 0xE8000030
 0x55555555 to address 0xE8000034
 0x55555 to address 0xE8000038
 0x55555 to address 0xE800003C

This is to say, you should add these commands to the startup service of your application if your design will rely on PC104 hardware:

 peekpoke 32 0xE8000030 0x55555555
 peekpoke 32 0xE8000034 0x55555555
 peekpoke 32 0xE8000038 0x55555
 peekpoke 32 0xE800003C 0x55555

More specifically, the functionality of the PC-104 connector can be configured in a more fine-grained manner, two pins at a time. Each pin pair will have one of two functions:

Value Description
2 Reserved
3 Reserved

Setting the function of each pair of pins is done by writing the function number to the appropriate pair of bits in the register corresponding to the row in question. The table below shows the bit positions in each register on the top row, while the cells below in the same column give the corresponding pin numbers for each row which are programmed with those bits at the specified register address.

Row Register bits 31
B 0xE8000034 31
A 0xE8000030 31
D 0xE800003C 19
C 0xE8000038 19

For example, to set the function of pins B19 and B20, this the table above indicates to use bits [19:18] of the register at address 0xE8000034.

The function of the PC-104 connector pins are given in the table below. The "ISA" column gives the name of the pin signal when it is configured as ISA, while the "GPIO" column gives the name of the pin signal when it is configured as GPIO. To save space, there are two sets of columns in each table, whereby the pin name is listed first, followed by the ISA signal and then the GPIO signal, and then this order is repeated for the other set of pins on the same physical header.

The 64-pin connector is given first:

A2 D7 A[1] B2 RESET B[1]
A3 D6 A[2] B3 +5V +5V
A4 D5 A[3] B4 IRQ9 B[3]
A5 D4 A[4] B5 3.3V 3.3V
A6 D3 A[5] B6 DRQ2 B[5]
A7 D2 A[6] B7 NC B[6]
A8 D1 A[7] B8 ENDX# B[7]
A9 D0 A[8] B9 8V_30V 8V_30V
A11 AEN A[10] B11 MEMW# B[10]
A12 A19 A[11] B12 MEMR# B[11]
A13 A18 A[12] B13 IOW# B[12]
A14 A17 A[13] B14 IOR# B[13]
A15 A16 A[14] B15 DACK3# B[14]
A16 A15 A[15] B16 DRQ3 B[15]
A17 A14 A[16] B17 DACK1# B[16]
A18 A13 A[17] B18 DRQ1 B[17]
A19 A12 A[18] B19 RFRSH# B[18]
A20 A11 A[19] B20 BCLK B[19]
A21 A10 A[20] B21 IRQ7 B[20]
A22 A9 A[21] B22 IRQ6 B[21]
A23 A8 A[22] B23 IRQ5 B[22]
A24 A7 A[23] B24 IRQ4 B[23]
A25 A6 A[24] B25 IRQ3 B[24]
A26 A5 A[25] B26 DACK2# B[25]
A27 A4 A[26] B27 TC B[26]
A28 A3 A[27] B28 BALE B[27]
A29 A2 A[28] B29 +5V +5V
A30 A1 A[29] B30 OSC B[29]
A31 A0 A[30] B31 GND GND
A32 GND GND B32 ISA_B32 B[31]

Here are the pin assignments for the 40-pin connector:

C1 SBHE# C[1] D1 MEM16# D[1]
C2 LA23 C[2] D2 IO16# D[2]
C3 LA22 C[3] D3 IRQ10 D[3]
C4 LA21 C[4] D4 IRQ11 D[4] (RO)
C5 LA20 C[5] D5 IRQ12 D[5] (RO)
C6 LA19 C[6] D6 IRQ15 D[6] (RO)
C7 LA18 C[7] D7 IRQ14 D[7] (RO)
C8 LA17 C[8] D8 3.3V 3.3V
C9 MEMR# C[9] D9 DRQ0 D[9]
C10 MEMW# C[10] D10 DACK5# D[10]
C11 SD8 C[11] D11 DRQ5 D[11]
C12 SD9 C[12] D12 DACK6# D[12]
C13 SD10 C[13] D13 DRQ6 D[13]
C14 SD11 C[14] D14 DACK7# D[14]
C15 SD12 C[15] D15 DRQ7 D[15]
C16 SD13 C[16] D16 +5V +5V
C17 SD14 C[17] D17 MASTER# D[17]
C18 SD15 C[18] D18 GND GND
Note: The GPIO nomenclature in these tables is such that, for example, "A[0]" means "Bit 0 of GPIO Register A", and in general "X[n]" means "Bit n of GPIO Register X" and "X[n:m]" means "Bits n through m of GPIO register X", where X is one of A, B, C, or D.

GPIO Master Table

To ease development of complex systems, all GPIO are listed in this single, sortable table. Note that the GPIO numbering in this table assumes userspace context for use in the /sys/class/gpio driver. If using this table to modify the Kernel Device Tree, subtract 64 from the GPIO number.

GPIO Num Name Connector Pin R/W Function(s) Source Sink Default

Startup State

64 DIO_1 DIO CN8 pin 1 RW GPIO / I2C DAT 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PU
65 DIO_3 DIO CN8 pin 3 RW GPIO / I2C CLOCK 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PU
66 DIO_04 DIO CN8 pin 4 RW GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
67 DIO_5 DIO CN8 pin 5 RW GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PU
68 SPI_FRAME DIO CN8 pin 6 WO SPI_CS / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
69 DIO_7 DIO CN8 pin 7 RW GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PU
70 DIO_8 DIO CN8 pin 8 RW GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
71 DIO_9 DIO CN8 pin 9 RW GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PU
72 SPI_MISO DIO CN8 pin 10 RO SPI MISO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 10k ohm PU
73 DIO_11 DIO CN8 pin 11 RW GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PU
74 SPI_MOSI DIO CN8 pin 12 WO SPI MOSI / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
75 DIO_13 DIO CN8 pin 13 RW GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PU
76 SPI_CLK DIO CN8 pin 14 WO SPI CLOCK / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
77 DIO_15 DIO CN8 pin 15 RW GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PU
78 LCD_RS LCD CN7 pin 3 RW LCD RS / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 2.2k ohm PU
79 LCD_BIAS LCD CN7 pin 4 WO LCD BIAS / GPIO 3.3 V @ 2 mA 2 mA (3.3 V toleran 475 ohm PD
80 LCD_EN LCD CN7 pin 5 RW LCD EN / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 51 ohm PU
81 LCD_RW LCD CN7 pin 6 RW LCD RW / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 2.2k ohm PU
82 LCD_DB1 LCD CN7 pin 7 RW LCD DAT 1 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 2.2k ohm PU
83 LCD_DB0 LCD CN7 pin 8 RW LCD DAT 0 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 2.2k ohm PU
84 LCD_DB3 LCD CN7 pin 9 RW LCD DAT 3 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 2.2k ohm PU
85 LCD_DB2 LCD CN7 pin 10 RW LCD DAT 2 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 2.2k ohm PU
86 LCD_DB5 LCD CN7 pin 11 RW LCD DAT 5 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 2.2k ohm PU
87 LCD_DB4 LCD CN7 pin 12 RW LCD DAT 4 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 2.2k ohm PU
88 LCD_DB7 LCD CN7 pin 13 RW LCD DAT 7 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 2.2k ohm PU
89 LCD_DB8 LCD CN7 pin 14 RW LCD DAT 8 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 2.2k ohm PU
90 ISA_A[0] ISA 64 PIN CN5 pin A1 RW ISA IOCHK# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
91 ISA_A[1] ISA 64 PIN CN5 pin A2 RW ISA DAT 7 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
92 ISA_A[2] ISA 64 PIN CN5 pin A3 RW ISA DAT 6 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
93 ISA_A[3] ISA 64 PIN CN5 pin A4 RW ISA DAT 5 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
94 ISA_A[4] ISA 64 PIN CN5 pin A5 RW ISA DAT 4 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
95 ISA_A[5] ISA 64 PIN CN5 pin A6 RW ISA DAT 3 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
96 ISA_A[6] ISA 64 PIN CN5 pin A7 RW ISA DAT 2 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
97 ISA_A[7] ISA 64 PIN CN5 pin A8 RW ISA DAT 1 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
98 ISA_A[8] ISA 64 PIN CN5 pin A9 RW ISA DAT 0 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
99 ISA_A[9] ISA 64 PIN CN5 pin A10 RW ISA IORDY / GPIO 3.3 V @ 2 mA 2 mA (3.3 V toleran 20k-150k ohm PU
100 ISA_A[10] ISA 64 PIN CN5 pin A11 RW ISA AEN / GPIO 3.3 V @ 2 mA 2 mA (3.3 V toleran 20k-150k ohm PU
101 ISA_A[11] ISA 64 PIN CN5 pin A12 RW ISA ADDR 19 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V toleran 20k-150k ohm PU
102 ISA_A[12] ISA 64 PIN CN5 pin A13 RW ISA ADDR 18 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V toleran 20k-150k ohm PU
103 ISA_A[13] ISA 64 PIN CN5 pin A14 RW ISA ADDR 17 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V toleran 20k-150k ohm PU
104 ISA_A[14] ISA 64 PIN CN5 pin A15 RW ISA ADDR 16 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V toleran 20k-150k ohm PU
105 ISA_A[15] ISA 64 PIN CN5 pin A16 RW ISA ADDR 15 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
106 ISA_A[16] ISA 64 PIN CN5 pin A17 RW ISA ADDR 14 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
107 ISA_A[17] ISA 64 PIN CN5 pin A18 RW ISA ADDR 13 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
108 ISA_A[18] ISA 64 PIN CN5 pin A19 RW ISA ADDR 12 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
109 ISA_A[19] ISA 64 PIN CN5 pin A20 RW ISA ADDR 11 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
110 ISA_A[20] ISA 64 PIN CN5 pin A21 RW ISA ADDR 10 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
111 ISA_A[21] ISA 64 PIN CN5 pin A22 RW ISA ADDR 9 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
112 ISA_A[22] ISA 64 PIN CN5 pin A 23 RW ISA ADDR 8 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
113 ISA_A[23] ISA 64 PIN CN5 pin A24 RW ISA ADDR 7 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
114 ISA_A[24] ISA 64 PIN CN5 pin A25 RW ISA ADDR 6 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
115 ISA_A[25] ISA 64 PIN CN5 pin A26 RW ISA ADDR 5 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
116 ISA_A[26] ISA 64 PIN CN5 pin A27 RW ISA ADDR 4 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
117 ISA_A[27] ISA 64 PIN CN5 pin A28 RW ISA ADDR 3 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
118 ISA_A[28] ISA 64 PIN CN5 pin A29 RW ISA ADDR 2 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
119 ISA_A[29] ISA 64 PIN CN5 pin A30 RW ISA ADDR 1 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
120 ISA_A[30] ISA 64 PIN CN5 pin A31 RW ISA ADDR 0 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
122 ISA_B[1] ISA 64 PIN CN5 pin B2 WO ISA RESET / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 10k ohm PU
123 ISA_B[3] ISA 64 PIN CN5 pin B4 RW ISA IRQ9 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
124 ISA_B[5] ISA 64 PIN CN5 pin B6 RW ISA DRO2 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
125 ISA_B[6] ISA 64 PIN CN5 pin B7 RW Wake From Sleep / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
126 ISA_B[7] ISA 64 PIN CN5 pin B8 RW ISA ENDX# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
127 ISA_B[10] ISA 64 PIN CN5 pin B11 RW ISA MEMW# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
128 ISA_B[11] ISA 64 PIN CN5 pin B12 RW ISA MEMR# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
129 ISA_B[12] ISA 64 PIN CN5 pin B13 RW ISA IOW# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
130 ISA_B[13] ISA 64 PIN CN5 pin B14 RW ISA IOR# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
131 ISA_B[14] ISA 64 PIN CN5 pin B15 RW ISA DACK3# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
132 ISA_B[15] ISA 64 PIN CN5 pin B16 RW ISA DRO3 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
133 ISA_B[16] ISA 64 PIN CN5 pin B17 RW ISA DACK1# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
134 ISA_B[17] ISA 64 PIN CN5 pin B18 RW ISA DRO1 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
135 ISA_B[18] ISA 64 PIN CN5 pin B19 RW ISA RFRSH# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
136 ISA_B[19] ISA 64 PIN CN5 pin B20 RW ISA BCLK / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
137 ISA_B[20] ISA 64 PIN CN5 pin B21 RW ISA IRQ7 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PD
138 ISA_B[21] ISA 64 PIN CN5 pin B22 RW ISA IRQ6 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PD
139 ISA_B[22] ISA 64 PIN CN5 pin B23 RW ISA IRQ5 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 4.4k ohm PU
140 ISA_B[23] ISA 64 PIN CN5 pin B24 RW ISA IRQ4 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
141 ISA_B[24] ISA 64 PIN CN5 pin B25 RW ISA IRQ3 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
142 ISA_B[25] ISA 64 PIN CN5 pin B26 RW ISA DACK2# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
143 ISA_B[26] ISA 64 PIN CN5 pin B27 RW ISA TC / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
144 ISA_B[27] ISA 64 PIN CN5 pin B28 RW ISA BALE / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
145 ISA_B[29] ISA 64 PIN CN5 pin B30 RW ISA OSC / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
146 ISA_B[31] ISA 64 PIN CN5 pin B32 RW Wake From Sleep / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
147 ISA_C[1] ISA 40 PIN CN6 pin C1 RW ISA SBHE / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
148 ISA_C[2] ISA 40 PIN CN6 pin C2 RW ISA LA23 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
149 ISA_C[3] ISA 40 PIN CN6 pin C3 RW ISA LA22 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
150 ISA_C[4] ISA 40 PIN CN6 pin C4 RW ISA LA21 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
151 ISA_C[5] ISA 40 PIN CN6 pin C5 RW ISA LA20 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
152 ISA_C[6] ISA 40 PIN CN6 pin C6 RW ISA LA19 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
153 ISA_C[7] ISA 40 PIN CN6 pin C7 RW ISA LA18 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
154 ISA_C[8] ISA 40 PIN CN6 pin C8 RW ISA LA17 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
155 ISA_C[9] ISA 40 PIN CN6 pin C9 RW ISA MEMR# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
156 ISA_C[10] ISA 40 PIN CN6 pin C10 RW ISA MEMW# / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
157 ISA_C[11] ISA 40 PIN CN6 pin C11 RW ISA SD8 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
158 ISA_C[12] ISA 40 PIN CN6 pin C12 RW ISA SD9 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
159 ISA_C[13] ISA 40 PIN CN6 pin C13 RW ISA SD10 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
160 ISA_C[14] ISA 40 PIN CN6 pin C14 RW ISA SD11 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
161 ISA_C[15] ISA 40 PIN CN6 pin C15 RW ISA SD12 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
162 ISA_C[16] ISA 40 PIN CN6 pin C16 RW ISA SD13 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
163 ISA_C[17] ISA 40 PIN CN6 pin C17 RW ISA SD14 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
164 ISA_C[18] ISA 40 PIN CN6 pin C18 RW ISA SD15 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
165 ISA_D[1] ISA 40 PIN CN6 pin D1 RW ISA MEMCS16 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PU
166 ISA_D[2] ISA 40 PIN CN6 pin D2 RW ISA IOCS16 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 2.2k ohm PU
167 ISA_D[3] ISA 40 PIN CN6 pin D3 RW ISA IRQ10 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
168 ISA_D[4] ISA 40 PIN CN6 pin D4 RO ISA IRQ11 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
169 ISA_D[5] ISA 40 PIN CN6 pin D5 RO ISA IRQ12 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
170 ISA_D[6] ISA 40 PIN CN6 pin D6 RO ISA IRQ15 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
171 ISA_D[7] ISA 40 PIN CN6 pin D7 RO ISA IRQ14 / GPIO 3.3 V @ 2 mA 2 mA (5 V tolerant) 20k-150k ohm PU
172 ISA_D[9] ISA 40 PIN CN6 pin D9 RW ISA DRQ0 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
173 ISA_D[10] ISA 40 PIN CN6 pin D10 RW ISA DACK5 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
174 ISA_D[11] ISA 40 PIN CN6 pin D11 RW ISA DRQ5 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
175 ISA_D[12] ISA 40 PIN CN6 pin D12 RW ISA DACK6 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
176 ISA_D[13] ISA 40 PIN CN6 pin D13 RW ISA DRQ6 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
177 ISA_D[14] ISA 40 PIN CN6 pin D14 RW ISA DACK7 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
178 ISA_D[15] ISA 40 PIN CN6 pin D15 RW ISA DRQ7 / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
179 ISA_D[17] ISA 40 PIN CN6 pin D17 RW ISA MASTER / GPIO 3.3 V @ 2 mA 2 mA (3.3 V tolerant) 20k-150k ohm PU
180 EN_WIFI_PWR NONE NONE WO Peripheral Power Sw. N/A N/A 20k-150k ohm PU
181 WIFI_RESET NONE NONE WO Peripheral Reset Sw. N/A N/A 20k-150k ohm PU
Note: The "20k-150k ohm FPGA PU" signals come from the FPGA, where they are arranged in banks that share the same pull-up. More GPIO drawing current will therefore result in a lighter (larger resistance) pull-up, where fewer GPIO drawing current will result in a "stiffer" (lower resistance) pull-up.

Migration Path

While 100% backwards-compatibility is often an impossible challenge that manufacturers choose not to pursue, Technologic Systems is introducing the TS-7800-V2 with the intent to provide a favorable compromise between backward compatibility and the forward-looking features necessary to meet the demands of today's embedded systems market.

Due to the decade-long reign of the TS-7800, many technologies have sufficiently changed that render a 100% backwards-compatible design completely impossible. With that in mind, the design team has made great efforts to implement features intended to ease any transition from the original TS-7800 into the TS-7800-V2 Industrial SBC platform, such as providing a driver that automatically remaps old memory addresses to their new locations, and providing symbolic links such that the serial port device nodes continue to work without any need to change to the new naming conventions offered by the newer platform.

This chapter is intended to supplement the existing manual, detailing and highlighting specific articles and information needed to speed your migration into the TS-7800-V2 platform.

Linux 4.4 (The Shipping Image)


The TS-7800-V2 makes significant changes to the boot process. The first difference is the replacement of the TS-BOOTROM with the more modern U-Boot bootloader. Next, in keeping with the newer Debian 9 ("Stretch") version, there is no longer an initrd. This is important to note for those designs where operating from the RAMDisk was preferred. If this functionality is necessary for your specific application, please contact Technologic Systems' sales team (sales@embeddedTS.com).

The TS-7800-V2's boot pattern is most easily described by the image below:

Ts7800v2 boot map.jpg

Very important: U-Boot always lives on the eMMC. Once the system has loaded u-boot, the kernel boot media is selected from the u-boot configuration script.

The TS-7800-V2 is binary-compatible with EABI Linux user-space applications that were created for the earlier product, and these should run unchanged on the TS-7800-V2. OABI applications may need to be recompiled using a more modern compiler.

Software Differences

This is where the TS-7800-V2 takes a turn into realms previously unknown to its predecessor. The TS-7800-V2 employs several new software technologies to bring the venerable TS-7800 platform into the current Linux era. Older technologies such as the initrd and init.d are completely deprecated in favor of the u-Boot bootloader and the systemd init system. For those with existing init.d scripts, those scripts must be modified and enabled for compatibility with the systemd scripting system. Pertinent documentation is included in the Starting Automatically section and below under "Systemd versus init.d".

New U-Boot

U-Boot replaces the older TS-BOOTROM bootloader. U-Boot is significantly more powerful and allows the downstream developer more control over the earliest and lowest levels of system boot, including the ability to introduce custom early-boot scripts and conditions without the need to recompile or reinstall the U-Boot binary. More information on the U-Boot system used on the TS-7800-V2 is found in the U-Boot section. Note: While it is possible to replace the U-Boot binary, Technologic Systems does not recommend doing so. Mistakenly installing a non-functional U-Boot binary can "brick" the TS-7800-V2. The only means of recovery would be to return the device for re-imaging via RMA.

New Boot Process

The original TS-7800 had a three stage boot. The BootROM loaded the kernel and jumped into an initial RAMDisk (initrd) running Busybox, which then loaded the downstream developer's application, or started the Debian loader. The TS-7800-V2 no longer uses the initrd, in favor of loading Debian directly.

New Kernel

The TS-7800 shipped with Linux 2.6. The TS-7800-V2 ships with Linux 4.4. If you have written custom drivers for the earlier kernel, you will need to recompile them (and very likely make changes to them) for the newer kernel.

New Partition Scheme

The original TS-7800 used a 3-partition system, one for kernel, one for initrd, and one for the Linux Root Filesystem. The TS-7800-V2 has media with just one primary partition. This removes the initrd completely, and moves the kernel into the primary partition. The U-Boot bootloader occupies a special hardware portion of the eMMC chip, and is seen from Linux as a separate device.

Systemd versus init.d

The init.d system has been a mainstay standard boot methodology for many years in the Linux community. It featured a structured scripting system that ensured software was loaded in the proper order via a staged priority mechanism. This worked well during an era when the computer largely could only complete one task at a time and all software to be loaded needed to be loaded sequentially. The flaw in this strategy is as time has passed and computers have become more capable, there is no longer a need for linear execution. Many software packages can start independently of other software packages by employing multiple system threads. A new startup system was needed.

Enter: systemd. Systemd employs a much faster prerequisite-based startup scripting system that allows for faster boot times by starting software as its prerequisites are fulfilled instead of starting just one service at a time. This makes startup scripts more complicated, but also streamlines the linux startup.

Unfortunately some adjustment must be made for original TS-7800 init.d scripts.

The .service file tells the new system when to start a service, much as the init.d file did previously. Instead of a linear numerical system, it determines what to start based on dependencies. For example, if the old script just needs to make sure the network exists before it can run, simply add "requires=network.service" to the appropriate part of the new myservice.service file. This replaces the older init.d "S99" and "K99" style.

For instructions on starting software automatically, see the Starting Automatically section.

Userspace Interrupts

Userspace interrupts are not currently implemented on the TS-7800-V2. This is significantly different from the TS-7800. Please contact Technologic Systems' sales team (sales@embeddedTS.com) if this functionality is needed in your application.

Hardware Differences


The TS-7800 uses a Marvell Feroceon MV88F5182 single-core CPU running at 500MHz. The TS-7800-V2 uses a Marvell Armada 385 88F6820 dual-core CPU running at 1.3 GHz. Naturally, this should result in a significant performance increase. The 88F6820 also adds 1 MB of L2 cache (shared between the cores). The additional performance of the TS-7800-V2 should not cause any problems for your application, as long as your code doesn't use simple software loops as a timing reference; such loops will run many times faster than they did on the TS-7800. Also, it is important to note that a single task, single thread application will not benefit from the second CPU core.

More RAM

The TS-7800 has 128 MB of DDR1 RAM, while the TS-7800-V2 has 1 GB of DDR3 RAM with optional ECC mode (making 512MB). There are more details on ECC in the Boot Flags section.


The TS-7800 has 512 MB of on-board NAND flash, while the TS-7800-V2 has 4 GB of eMMC.

New SD

Unlike the TS-7800, the SD connectors on the TS-7800-V2 are wired in parallel, meaning that only one may be used at any given time. You must not have a card in both slots.

New Microcontroller

The TS-7800 uses an ATMega48 AVR RISC-based microcontroller to perform various ancillary tasks on the board, such as Analog-to-digital conversion. The TS-7800-V2 uses a SiLabs C8051F381 to do basically the same job. The ts7800ctl utility continues to provide access to the microcontroller functions as it did on the original TS-7800.


The tsuarts of the original TS-7800 have been replaced with full 16550 UARTs in the new FPGA. Symbolic links allow the downstream developer to use the original tsuart naming so ported applications may continue to use the names of the TSUART devices. These links are detailed in the following table:

/dev/ttts0 /dev/ttyS2
/dev/ttts1 /dev/ttyS3
/dev/ttts2 /dev/ttyS4
/dev/ttts3 /dev/ttyS5
/dev/ttts4 /dev/ttyS6
/dev/ttts5 /dev/ttyS7
/dev/ttts6 /dev/ttyS8
/dev/ttts7 /dev/ttyS9
/dev/ttts8 /dev/ttyS10
/dev/ttts9 /dev/ttyS11

Note those applications that used direct register access to tsuarts will need to be refactored as the tsuart register structure was not directly compatible with the standard 16550 register structure.

New Physical Addressing

These have changed significantly, but our team has gone to great lengths to ensure application compatibilty in user space. From user space, no modifications should be necessary as all of the original TS-7800 memory mappings have been cross-mapped in the devmem driver. However, the devmem driver remap only applies to user-space applications. If the downstream application uses kernel drivers that access these addresses, those drivers will need to be modified to use the new addressing scheme. The address mappings are described below.

TS-7800 TS-7800-V2
FPGA 32-bit 0xE8000000 0xFC081000
PC104 8-bit memory 0xEC000000 0xF8000000
PC104 16-bit memory 0xED000000 0xF9000000
PC104 8-bit I/O 0xEE000000 0xFA000000
PC104 16-bit I/O 0xEF000000 0xFB000000
New Temperature Sensor

The TS-7800 used a Texas Instruments TMP124 temperature sense chip, with SPI interface to the CPU. The TS-7800-V2 uses the temperature sensor in the SiLabs microcontroller. If there are applications that interface directly with the TMP124, they will need to be modified to use the new ts7800ctl access method. The ts7800ctl utility supplied on the TS-7800-V2 works the same way as its predecessor.

Alternatively, there is an optional temperature sensor included on the optional accelerometer package.

Linux 5.10 (Long Term Supported)

embeddedTS is working to keep the TS-7800-V2 relevant into the foreseeable future. To that end, a new LTS (Long Term Supported) kernel has been ported to the TS-7800-V2 in order to allow independent kernel maintenance beyond January 1st, 2023. This subchapter seeks to highlight the differences between the standard shipping kernel (Linux 4.4) and the newer Linux 5.10.y kernel.

Memory Mapping and Register Access

The largest difference between Kernel 4.4 and Kernel 5.10.y is the way memory spaces are accessed. With Kernel 5.10.y, memory space is now a truly protected resource, and the memory manager retains tight control over which processes have access to the memory mapped resource, and how much of that resource they may be able to use. This prompted a complete rewrite of the classic "peekpoke" command generally used for FPGA SYSCON access. The new application breaks out a helpful API for memory access use, found in the ts7800-utils repository on Github, in specific, fpga.c, quoted here:

// c. 2022 embeddedTS.com 
// PCI base address is determined at boot-time, and isn't always the same.
// The TS-7800-V2 uses the PCI bus to talk to its FPGA.  

// This library acquires a temporary memory mapped pointer to the PCI
//  resource, either ISA or Syscon, and handles a read or write at that
//  resource address.

#include <stdio.h>
#include <stdint.h>
#include <sys/utsname.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include "fpga.h"

// all the syscon access functions.

uint8_t syscon_peek8(uint32_t *syscon, size_t offs) {
        return *(volatile uint8_t *)(syscon + (offs/4));

uint16_t syscon_peek16(uint32_t *syscon, size_t offs) {
        return *(volatile uint16_t *)(syscon + (offs/4));

uint32_t syscon_peek32(uint32_t *syscon, size_t offs) {
        return *(volatile uint32_t *)(syscon + (offs/4));

uint64_t syscon_peek64(uint32_t *syscon, size_t offs) {
        return *(volatile uint64_t *)(syscon + (offs/4));

void syscon_poke32(uint32_t *syscon, size_t offs, uint32_t val) {
        *(volatile uint32_t *)(syscon + (offs/4)) = val;

void syscon_poke64(uint32_t *syscon, size_t offs, uint64_t val) {
        *(volatile uint64_t *)(syscon + (offs/4)) = val;

void syscon_poke16(uint32_t *syscon, size_t offs, uint16_t val) {
        *(volatile uint16_t *)(syscon + (offs/4)) = val;

void syscon_poke8(uint32_t *syscon, size_t offs, uint8_t val) {
        *(volatile uint8_t *)(syscon + (offs/4)) = val;

// all the ISA access functions:
uint8_t isa_io_peek8(uint32_t *isa, uint8_t offs){
	return *(volatile uint8_t *)(isa + (offs + 0x2000000)/4);
uint8_t isa_io_poke8(uint32_t *isa, uint8_t offs, uint8_t val){
	*(volatile uint8_t *)(isa + (offs + 0x2000000)/4) = val;
uint16_t isa_io_peek16(uint32_t *isa, uint8_t offs){
	return *(volatile uint16_t *)(isa + (offs + 0x3000000)/4);
uint16_t isa_io_poke16(uint32_t *isa, uint8_t offs, uint16_t val){
	*(volatile uint16_t *)(isa + (offs + 0x3000000)/4) = val;

uint8_t isa_mem_peek8(uint32_t *isa, uint8_t offs){
	return *(volatile uint8_t *)(isa + (offs/4));
uint8_t isa_mem_poke8(uint32_t *isa, uint8_t offs, uint8_t val){
	*(volatile uint8_t *)(isa + (offs/4));
uint16_t isa_mem_peek16(uint32_t *isa, uint8_t offs){
	return *(volatile uint16_t *)(isa + (offs + 0x1000000/2));
uint16_t isa_mem_poke16(uint32_t *isa, uint8_t offs, uint16_t val){
	*(volatile uint16_t *)(isa + (offs + 0x1000000/2));

uint32_t* syscon_init(void)
        int fd;
	uint32_t *fpga;
	fd = open("/sys/bus/pci/devices/0000:02:00.0/resource2", O_RDWR|O_SYNC);
        if (fd == -1)
                return NULL;
        fpga = (uint32_t *)mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
		return NULL;
        	return fpga;

uint32_t* fpga_init(void)
	return syscon_init();

uint32_t* isa_init(void)
	int fd;
	uint32_t* addr;
	fd = open("/sys/bus/pci/devices/0000:02:00.0/resource3", O_RDWR|O_SYNC);
	if(fd == -1)
		return NULL;
	addr = (uint32_t *)mmap(0, 0x4000000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if (!addr)
		return NULL;
		return addr;

The two primary functions above are isa_init() for accessing the ISA registers, and syscon_init() for accessing the FPGA Syscon.

IRQ in 5.10.y

IRQ numbering is much simplified under 5.10.y. While IRQ are still only available to kernel drivers, now the IRQ is relative to the IRQ controller as its standard IRQ number (for example PC/104 IRQ 5, 6, or 7 are now simply IRQ 5, 6, or 7). The device tree should reference the IRQ controller before specifying the IRQ number, for example: "interrupt-parent = <&ts7800fpga_irq>;".

GPIO in 5.10.y

The GPIO table remains fairly similar as to its previous iteration in 4.4.y. The most noticeable difference is the libgpiod update which now requires a "chip" and IO number. For simplification, all CPU gpio are chips 0 and 1, and all FPGA gpio are chip 2. TODO: Ensure gpiod package is installed in downloadable image. The following table describes the default IO chips, numbering, and state for the TS-7800-V2 under Linux 5.10.y:

Chip/IO num IO Name IO Alt Name in/out Neutral State [claim]
gpiochip0 ----- ----- ----- -----
0 "UART0_RXD" unused input active-high
1 "UART0_TXD" unused input active-high
2 "I2C_0_CLK" unused input active-high
3 "I2C_0_DAT" unused input active-high
4 "MPP4_GE_MDC" unused input active-high
5 "MPP5_GE_MDIO" unused input active-high
6 "MPP6_GE_TXCLK" unused input active-high
7 "MPP7_GE_TXDO" unused input active-high
8 "MPP8_GE_TXD1" unused input active-high
9 "MPP9_GE_TXD2" unused input active-high
10 "MPP10_GE_TXD3" unused input active-high
11 "MPP11_GE_TXCTL" unused input active-high
12 "MPP12_GE_RXD0" unused input active-high
13 "MPP13_GE_RXD1" unused input active-high
14 "MPP14_GE_RXD2" unused input active-high
15 "MPP15_GE_RXD3" unused input active-high
16 "MPP16_GE_RXCTL" unused input active-high
17 "MPP17_GE_RXCLK" unused input active-high
18 "WIFI_IRQ#" unused input active-high
19 "CPU_IRQ" unused input active-high
20 unnamed unused input active-high
21 unnamed unused input active-high
22 "SPI_0_MOSI" unused input active-high
23 "SPI_0_CLK" unused input active-high
24 "SPI_0_MISO" unused input active-high
25 "SPI_0_BOOT_CS0#" unused input active-high
26 unnamed unused input active-high
27 "SPI_0_WIFI_CS2#" unused input active-high
28 "SPI_0_CS3#" "spi0 CS4" output active-low [used]
29 "GE_PHY_INT#" unused input active-high
30 "CPU_SPEED_1" unused input active-high
31 "CPU_SPEED_2" unused input active-high
gpiochip1 ----- ----- ----- -----
0 unnamed unused input active-high
1 "CPU_SPEED_0" unused input active-high
2 "CPU_SPEED_3" unused input active-high
3 "CPU_SPEED_4" unused input active-high
4 "CPU_TYPE_0" unused input active-high
5 unnamed unused input active-high
6 unnamed unused input active-high
7 unnamed unused input active-high
8 unnamed unused input active-high
9 unnamed unused input active-high
10 "EN_EMMC_PWR" unused input active-high
11 "EN_FAN" unused input active-high
12 "CPU_TYPE_1" unused output active-high
13 "EN_USB_HOST_5V" en-usb-host-5v output active-high [used]
14 "FPGA_FLASH_SELECT" unused input active-high
15 unnamed unused input active-high
16 unnamed unused input active-high
17 "ACCEL_2_INT" unused input active-high
18 "EMMC_CMD" unused input active-high
19 "SPREAD_SPECTRUM#" unused input active-high
20 "DETECT_MSATA" unused input active-high
21 "DETECT_9478" unused input active-high
22 "EMMC_D3" unused input active-high
23 "EMMC_D0" unused input active-high
24 unnamed unused input active-high
25 "EMMC_CLK" unused input active-high
26 "EMMC_D1" unused input active-high
27 "EMMC_D2" unused input active-high
gpiochip2 ----- ----- ----- -----
0 "DIO_1" unused input active-high
1 "DIO_3" unused input active-high
2 "DIO_04" unused input active-high
3 "DIO_5" unused input active-high
4 "SPI_FRAME" unused input active-high
5 "DIO_7" unused input active-high
6 "DIO_8" unused input active-high
7 "DIO_9" unused input active-high
8 "SPI_MISO" unused input active-high
9 "DIO_11" unused input active-high
10 "SPI_MOSI" unused input active-high
11 "DIO_13" unused input active-high
12 "SPI_CLK" unused input active-high
13 "DIO_15" unused input active-high
14 "LCD_03" unused input active-high
15 "LCD_04" unused input active-high
16 "LCD_05" unused input active-high
17 "LCD_06" unused input active-high
18 "LCD_07" unused input active-high
19 "LCD_08" unused input active-high
20 "LCD_09" unused input active-high
21 "LCD_10" unused input active-high
22 "LCD_11" unused input active-high
23 "LCD_12" unused input active-high
24 "LCD_13" unused input active-high
25 "LCD_14" unused input active-high
26 "ISA_A01" unused input active-high
27 "ISA_DATA_07" unused input active-high
28 "ISA_DATA_06" unused input active-high
29 "ISA_DATA_05" unused input active-high
30 "ISA_DATA_04" unused input active-high
31 "ISA_DATA_03" unused input active-high
32 "ISA_DATA_02" unused input active-high
33 "ISA_DATA_01" unused input active-high
34 "ISA_DATA_00" unused input active-high
35 "ISA_A10" unused input active-high
36 "ISA_A11" unused input active-high
37 "ISA_A12" unused input active-high
38 "ISA_A13" unused input active-high
39 "ISA_A14" unused input active-high
40 "ISA_A15" unused input active-high
41 "ISA_A16" unused input active-high
42 "ISA_A17" unused input active-high
43 "ISA_A18" unused input active-high
44 "ISA_A19" unused input active-high
45 "ISA_A20" unused input active-high
46 "ISA_A21" unused input active-high
47 "ISA_A22" unused input active-high
48 "ISA_A23" unused input active-high
49 "ISA_A24" unused input active-high
50 "ISA_A25" unused input active-high
51 "ISA_A26" unused input active-high
52 "ISA_A27" unused input active-high
53 "ISA_A28" unused input active-high
54 "ISA_A29" unused input active-high
55 "ISA_A30" unused input active-high
56 unnamed unused input active-high
57 "ISA_RESET" unused input active-high
58 "ISA_B04" unused input active-high
59 "ISA_B06" unused input active-high
60 unnamed unused input active-high
61 "ISA_B08" unused input active-high
62 "ISA_B11" unused input active-high
63 "ISA_B12" unused input active-high
64 "ISA_B13" unused input active-high
65 "ISA_B14" unused input active-high
66 "ISA_B15" unused input active-high
67 "ISA_B16" unused input active-high
68 "ISA_B17" unused input active-high
69 "ISA_B18" unused input active-high
70 "ISA_B19" unused input active-high
71 "ISA_B20" unused input active-high
72 "IRQ7" unused input active-high
73 "IRQ6" unused input active-high
74 "IRQ5" unused input active-high
75 "ISA_B24" unused input active-high
76 "ISA_B25" unused input active-high
77 "ISA_B26" unused input active-high
78 "ISA_B27" unused input active-high
79 "ISA_B28" unused input active-high
80 "ISA_B29" unused input active-high
81 "ISA_B30" unused input active-high
82 "ISA_B32" unused input active-high
83 "ISA_C01" unused input active-high
84 "ISA_C02" unused input active-high
85 "ISA_C03" unused input active-high
86 "ISA_C04" unused input active-high
87 "ISA_C05" unused input active-high
88 "ISA_C06" unused input active-high
89 "ISA_C07" unused input active-high
90 "ISA_C08" unused input active-high
91 "ISA_C09" unused input active-high
92 "ISA_C10" unused input active-high
93 "ISA_DATA_08" unused input active-high
94 "ISA_DATA_09" unused input active-high
95 "ISA_DATA_10" unused input active-high
96 "ISA_DATA_11" unused input active-high
97 "ISA_DATA_12" unused input active-high
98 "ISA_DATA_13" unused input active-high
99 "ISA_DATA_14" unused input active-high
100 "ISA_DATA_15" unused input active-high
101 "ISA_D01" unused input active-high
102 "ISA_D02" unused input active-high
103 "IRQ10" unused input active-high
104 "IRQ11" unused input active-high
105 "IRQ12" unused input active-high
106 "IRQ15" unused input active-high
107 "IRQ14" unused input active-high
108 "ISA_D09" unused input active-high
109 "ISA_D10" unused input active-high
110 "ISA_D11" unused input active-high
111 "ISA_D12" unused input active-high
112 "ISA_D13" unused input active-high
113 "ISA_D14" unused input active-high
114 "ISA_D15" unused input active-high
115 "ISA_D17" unused input active-high
116 "EN_WIFI_PWR" "CHIP_EN" output active-high [used]
117 "WIFI_RESET" "RESET" output active-high [used]
118 "GREEN_LED" "green-led" output active-high [used]
119 "RED_LED" "red-led" output active-high [used]
120 "CPU_ACCESS_FPGA_FLASH#" mux output active-high [used]

PC/104 in 5.10.y

Most peripherals in the embeddedTS PC/104 space rely on the developer having unrestricted access to the memory map. The Linux 5.10.y kernel introduces a much more protective memory manager. This changes the inherent method(s) which the developer may access the peripheral hardware. While most hardware still does not technically require a Linux driver to access the peripheral hardware, all software must have a PCI address discovery and mapping function. An example of this is found in the isa_peekpoke.c software included in the software image. Source code found on Github.

Known Incompatabilities

The TS-7800-V2 is intended to be the most complete hardware drop-in possible. There are however a small number of known incompatibilities that should be mentioned:

Peripheral Note
TS-ETH2, TS-ETH10, TS-ETH100, TS-POE100 Driver incompatibility.
TS-RF2-* Software incompatibility.
TS-BAT3 Software incompatibility.
TS-5620 Unsupported: Multiple RTCs not supported on the TS-7800-V2.

Customer satisfaction is very important to Technologic Systems. If any of the above incompatibilities are a hindrance to migration efforts from the original TS-7800, please contact the Technologic Systems sales or support teams to explore alternative options.


Power Specifications

The stock TS-7800-V2 expects 5V DC.

Input Min voltage Max voltage
5V input 4.5 5.25
TS-781 8 30

Power Consumption

All tests are performed at 5V, with Ethernet, USB, mSATA, SD, disconnected unless otherwise specified. The different CPU frequencies are only tested when loaded and have the same power consumption at idle. Savings were not found by disabling CPU cores. See the Speed Scale section for how to modify the CPU clock rate.

Test Average Max
Idle at 1.3GHz with Ethernet off 0.821A/4.11W 1.013A/5.07W
Idle at 1.3GHz, Ethernet connected 0.902A/4.51W 1.210A/6.05W
Busy both cores 666MHz (openssl speed) 0.984A/4.92W 1.111A/5.55W
Busy both cores 1066MHz (openssl speed) 1.252A/6.26W 1.308A/6.54W
Busy both cores 1333MHz (openssl speed) 1.355A/6.78W 1.572A/7.86W
Busy single core 1333MHz (openssl speed) 1.039A/5.20W 1.240A/6.20W
mSATA writing [1] 1.481A/7.41W 1.787A/8.94W
Sleep Mode 572uA/2.86mW 583uA/2.92mW
Test Average Max
Idle (no changes) 0.81A/4.05W 1.15A/5.75W
Busy both cores at 1.333MHz (openssl speed) 1.39A/6.95W 1.55A/7.75W
  1. Tested with Mushkin MKNSSDAT30GB, cpu at 1.3GHz and otherwise idle

Temperature Specification

All TS-7800-V2 are rated for -40 to +85 degrees C ambient with the CPU set to run at 666 MHz (with provided heatsink). Temperature tolerance is lower when operating at the full 1.334 GHz speed.

In temperature testing at maximum CPU usage, at 667 MHz, the CPU's core temperature performed per the graph below:

TS-7800-V2 HotTempTestGraph.jpg

In typical use, the TS-7800-V2 is not anticipated to run at full CPU saturation 100% of the time. The graph below shows temperature chamber testing using the standard shipping configuration of the TS-7800-V2 (with standard heatsink) where a high-intensity process was launched every 900 seconds. The exact process used in this test was launched in a loop using this command: watch -t -n 900 openssl speed aes sha512 md5 rmd160 des camellia rc4 cast seed rc2 rc4 bf md4 Ts7800v2 coretemp over load.png

See the Speed Scale section for how to modify the CPU clock rate.

Temperature-based throttling

In the event the TS-7800-V2 finds itself in thermal distress, an idler daemon will begin forcibly injecting idle time on the CPU in an attempt to maintain an operational junction (internal CPU) temperature less than 115 degrees celsius. Under normal operation this is not expected to occur, however if the device is running at 1.3 GHz and ambient temperatures rise beyond the rated maximum temperature for the processor speed, this idle injection can save the CPU from failure. It is expected if ambient temperatures become so high that the CPU temperature cannot be controlled by forcing idle time, the CPU will be slowed sufficiently to cause a watchdog reset.

Note: Technologic systems does not recommend or support operating the TS-7800-V2 without a heatsink under any circumstance.

Revisions and Changes


There are currently no errata for this product.

PCB Revisions

PCB Revision Description of changes
Rev A. Initial Release / Engineering Sampling

U-Boot Revisions

Version Description of changes
U-Boot SPL 2017.09-g2113ce6a21 (Mar 06 2018 - 16:20:06)
  • Engineering Sample Program release.
U-Boot 2017.09-g970b04e89c (Apr 30 2018 - 08:19:08 -0700)
  • Added support for new SPI flash vendor, fixes network boot issue for production
  • Fixed USB to only reset the USB 5V once on a reboot.
  • Added support for the TSSDCORE. Booting to SD card now loads the kernel and device tree from the SD card rather than the emmc.
  • Corrected ethaddr to eth1addr variable name. This will cause Linux to get the mac address from the device tree in earlier boot rather than when userspace sets it.
  • Correct variable name reporting in conjunction with updated kernel.

FPGA Revisions

Version Description of changes
0x22: Revision 34. Engineering Sampling release version.
0x27: Revision 39. Engineering Sampling Update. Fixed bugs. Added CAN and PWM.
0x29: Revision 41. Engineering Sampling Update. Fixed bugs. FPGA UARTs and CAN now stable.
0x2C: Revision 44. Engineering Sampling Update. Fixed bug. LCD_04 now comes up in a predefined state and software control is enabled.
0x2D: Revision 45. Engineering Sampling Update. New Feature. TS-7800-V2 RNG. New FPGA-Based entropy engine passes NIST entropy tests.
0x2E: Revision 46. Minor timing improvements, changed UARTs to use blockram.
0x2F: Revision 47. Improved arbitrary baud rate. See Arbitrary Baud Rates for details.
0x30: Revision 48. Fixed default signal PC104 D[03] to have power-on state as documented with 20k ohm pull-up.

Microcontroller Revisions

Version Description of changes
7 Release to Engineering Sampling.
8 Internal release.
  • Ported from C8051F381-GM to EFM8UB20F32G-QFN32
  • Updated SiLabs USB-UART library

Kernel Revisions

Version Description of changes
6 Feb 2018: Pre-Release Version New Product Introduction / Initial candidate for Engineering Sampling Program
27 Feb 2018: Pre-release Configuration 2 Replaced RTC driver for compatibility with Rev. A01 SBC.
07 Mar 2018: Engineering Sample Release Linux ts7800-v2 4.4.8-armada-17.02.2-g5e5adf1 #0 SMP PREEMPT Wed Mar 7 10:46:07 MST 2018 armv7l GNU/Linux
02 Jul 2018: Engineering Sample Update: Boot no longer pauses to wait for absent SD media time-out, fixed CAN driver race condition.

Linux ts7800-v2 4.4.8-armada-17.02.2-g381d098 #2 SMP PREEMPT Mon Jul 2 12:39:40 MST 2018 armv7l GNU/Linux

* Aug 2019: Pre-production release Update: TS-7800-V2 FGPA RNG now supported in kernel. Patchlevel increased to 4.4.186 to comply with Linux 4.4.* LTS version.
* Dec 2020: Pre-production release update: Updated wireless networking driver to improve performance and fix a number of bugs.

Linux ts7800-v2 4.4.186-armada-17.02.2-ge44cae351 #2 SMP PREEMPT Mon Nov 23 15:10:59 MST 2020 armv7l GNU/Linux

Software Image Revisions

Version Description of changes
7 Feb 2018: Engineering Sampling Release Candidate New Product Introduction Candidate using a default "debootstrap" Debian. Added packages build-essential, watchdog, hexedit, vim, ftp, and joe.
27 Feb 2018: Engineering Sampling Release Candidate 2. Added new ts7800ctl binary to enable on-board temp sensor. Updated /sbin/tshwinit. Installed Picocom. Updated Aptitude databases. Ran distribution-upgrade.
07 Mar 2018: Engineering Sampling Release. Installed Git, added load_fpga_flash command to /sbin/.
23 Apr 2018: Engineering Sampling Update 1 New version of ts7800ctl adding access to the optional accelerometer. Installed wireless_tools, can-utils, and lrzsz packages. Updated kernel with wifi driver firmware. Updated /etc/hosts. Updated /etc/fstab. Updated /sbin/tshwinit. Updated /sbin/dhclient-script.
2 Jul 2018: Engineering Sampling Update 2 Missing SD media non-SD boot will no longer cause boot delays. Added packages gdb, curl, Ruby, screen, and command-not-found. Removed package linux-image-4.9.0-6-armmp. Installed all Debian updates and updated apt repositories. Fixed permission errors in /var/cache/man/*.
5 Feb 2019: Engineering Sampling Update 3 Add packages i2c-tools, autoconf, automake, autotools-dev, bridge-utils, device-tree-compiler, dialog, dosfstools, haveged, iproute, libhavege1, libsigsegv2, m4, ssh, u-boot-tools, and pkg-config. Non-wifi models no longer attempt to load wifi driver. Added TS utility "idleinject". Cleaned up ts7800ctl (removed unimplemented functions). Added num-samples to ADC functionality of ts7800ctl.
4 Jun 2019: Engineering Sample Update 4 Add package rustc. Bugfixes in FPGA startup, MAC address configuration, and WiFi detection. Removed fpga and u-boot folders from image (availability moved to ftp site).
Aug 2019: Production Candidate Image * Update Kernel to 4.4.186 LTS. Add package rng-tools. Update WiFi configuration to facilitate connecting to network at startup. Enable TS-7800-V2 FPGA RNG driver.
February 2021: Stretch Production and Buster Downloadable Updated WiFi driver for better connectivity and stability. Removed extraneous user account. Changed image production method for better maintainability. Created optional downloadable image for Debian Buster. Shipping image will remain Debian Stretch.
March 2021: Pre-production Bugfix update Added missing setserial package and serial.conf for TS-7800-V2 FPGA-based 16550 uarts.
 Debian 9 :  ts7800v2-debian-stretch-20210316.tar.xz (md5)
 Debian 10:  ts7800v2-debian-buster-20210310.tar.xz (md5)  
September 2021: Combined pre-production bugfix and optional downloads update to include Debian Bullseye. Pre-production cleanup and unification with forward-looking standard for Technologic Systems image production.
 Debian 9:  https://ftp.embeddedTS.com/ftp/ts-arm-sbc/ts-7800-v2-linux/distributions/ts7800v2-debian-stretch-20210707.tar.xz
 Debian 10:  https://ftp.embeddedTS.com/ftp/ts-arm-sbc/ts-7800-v2-linux/distributions/ts7800v2-debian-buster-20210707.tar.xz
 Debian 11:  https://ftp.embeddedTS.com/ftp/ts-arm-sbc/ts-7800-v2-linux/distributions/ts7800v2-debian-bullseye-20210826.tar.xz
January 2022: Bugfix update to fix downloadable Bullseye image md5sum mismatch. Debian 11: https://files.embeddedTS.com/ts-arm-sbc/ts-7800-v2-linux/distributions/ts7800v2-debian-bullseye-20220113.tar.xz (md5)
  • *Current shipping image is August 2019.

Model Numbers

The production TS part numbers for the TS-7800-V2 are TS-7800-V2-DMN1I, TS-7800-V2-DMW2I, and TS-7800-V2-DMW3I. These codes disambiguate as follows:

Family Cores Memory Radio Option Set Temperature
TS-7800-V2 D = Dual M = 1GB DDR3 N = None 1 = Base Model I = Industrial (-40 to +85 C)
W=Wifi/Bluetooth 2 = Base model plus Wifi only.
3 = Base plus wifi, change SATA to mSATA, add accelerometer.

There are three standard versions available for purchase from Technologic Systems:

Model Description Notes
DMN1I Base mdoel, no WiFi, -40 to +85 C operating temperature range, 2x SATA
DMW2I 802.11a/b/g/n 2.4 + 5 GHz WiFi + Bluetooth w/ short range chip antenna, 2x SATA
DMW3I 802.11a/b/g/n 2.4 + 5 GHz WiFi + Bluetooth w/ u.fl antenna connector, 1x SATA, 1x mSATA/minicard connector, 3 axis accelerometer. Incompatible with TS-781 PDB.

Please contact Technologic Systems Sales Team here for custom product requirements.

Product Notes


Arm and Cortex are registered trademarks of Arm Limited (or its subsidiaries) in the US and/or elsewhere.