From Technologic Systems Manuals
Jump to: navigation, search
TS-7970
ts-7970.gif
Product Page
Product Images
Specifications
Documentation
Schematic
Mechanical Drawing
FTP Path
Processor
Freescale i.MX6 Quad core, or Solo
i.MX6 Quad Product Page
i.MX6 Solo Product Page
IMX6Q Reference Manual
IMX6S Reference Manual

Contents


1 Getting Started

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

Virtualization

Suggested Linux Distributions

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

1.1 Getting Console and Powering up

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

Get console input by setting the "CON EN" jumper (located near the HDMI connector) and plug a USB type B cable into P2. Connect the host side to a workstation for development. Console can be viewed before or after power is applied. Boot messages will only be printed once the device is powered on.

The cp210x (USB Serial) driver is included in most popular distributions. This will show up as /dev/ttyUSB0. For other operating systems:

The serial console is provided through this port at 115200 baud, 8n1, with no flow control. Picocom is the recommended linux client to use which can be run with the following command:

sudo picocom -b 115200 /dev/ttyUSB0

This will output some serial setting information and then "Terminal ready". Any messages after this point will be from the device via the serial output. The terminal is now ready and power can be applied in order to boot up the device. Power is applied through the removable terminal block. This accepts 5 VDC, or 8-28 VDC input, only a single power input can be connected at any time.

A power supply should be prepared to provide 15 W for most uses. The devices's power consumption will average around 3 W on an idle quad core. See the #Specifications section for further details on power requirements.

TS-7970 terminal block connectors.png TS-7970 Terminal Blocks.png

P1-A, the top row of headers, are used in the following pin designations. For 5 V in, connect pin 7 to a 5 VDC source, and pin 8 to ground. For 8-28 V in, connect pin 6 to the voltage source and pin 8 to ground. See the terminal blocks section for more information on this header.

Once power is applied to either the 5 VDC, or 8-28 VDC the device will output information via the console. The first output is from U-Boot:

U-Boot 2015.04-07892-g9a2f707 (Jan 11 2017 - 16:14:53)

CPU:   Freescale i.MX6Q rev1.2 at 792 MHz
CPU:   Temperature 52 C
Reset cause: WDOG
Board: TS-7970 REV D
I2C:   ready
DRAM:  2 GiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
SF: Detected N25Q64 with page size 256 Bytes, erase size 4 KiB, total 8 MiB
In:    serial
Out:   serial
Err:   serial
FPGA Rev: 7
SilabRev: 2
Net:   using phy at 1
FEC [PRIME]

Boot will continue immediately unless SW1 is depressed before power is applied and is held down. This will stop boot in U-Boot allowing access to the U-Boot console. This will also cause the U-Boot to check for USB production.

Jumpers on the header near HDMI influence where the system boots. The "SD Boot" jumper, when set, will cause U-Boot to boot to SD, and when unset, U-Boot will boot to eMMC. If SW1 is not depressed, then U-Boot will boot to the selected media immediately.

TS-7970 Jumpers.jpeg


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.

1.2 First Linux Boot

U-Boot is always loaded from the onboard SPI flash. U-Boot has the ability to boot Linux, Android, QNX, or other operating systems on the SD or eMMC. The eMMC and SD cards shipped with the unit are pre-programmed with our Debian Jessie image. See other OS sections for information on the various OS options that we provide: Yocto, Ubuntu, Android, QNX.

 [  OK  ] Started Serial Getty on ttymxc0.
 [  OK  ] Reached target Login Prompts.
 [  OK  ] Started SLiM Simple Login Manager.
 [  OK  ] Created slice user-0.slice.
          Starting LSB: RPC portmapper replacement...
          Starting User Manager for UID 0...
 [  OK  ] Started User Manager for UID 0.
 [  OK  ] Started LSB: RPC portmapper replacement.
 [  OK  ] Reached target RPC Port Mapper.
          Starting Authenticate and Authorize Users to Run Privileged Tasks...
 
 Debian GNU/Linux 8 ts-imx6 ttymxc0
 
 ts-imx6 login: 

By default, the startup output is verbose and includes kernel messages and systemd output. The display, if connected, will boot to a minimalistic XFCE desktop. This is provided as a demo and is not intended for use in development or a shipping application. See the Debian automatic startup section for information on booting to a single application.

Note: During development it is recommended to leave on verbose messages for debugging. The non-error output can be disabled by modifying the kernel cmdline.

Once booted up, the serial port will display a login prompt which asks for a username/password. Under Debian this is "root" with no password which will allow the initial login. From here see the Debian section to continue on with Debian application development.

1.3 Comparison of Distributions

We currently offer Debian, Ubuntu, Yocto, QNX, and Android OSs for the TS-7970. Each of these have advantages and disadvantages, the major points are outlined below. We recommend Debian if the user does not need GPU support. Yocto is recommended for QT Creator, Eclipse support, or significant distribution customization.

Distribution Advantages Disadvantages
Debian
  • Cross compilation requires running the same Debian release on a host
  • Not patched for hardware support
    • No OpenGL or 2D acceleration from GPU. 2D applications through the framebuffer are still supported.
Ubuntu
  • Cross compilation requires running the same Ubuntu release on a host
  • Not patched for hardware support
    • No OpenGL or 2D acceleration from GPU. 2D applications through the framebuffer are still supported.
Yocto
  • Large focus on up to date packages
  • Allows rebuilding all packages with changes
  • Supports portable toolchain packages that integrate with QT Creator and Eclipse
  • Includes all patches needed for graphics support.
  • Distribution can be rebuilt to include specific needs.
  • Short life cycles
  • Does not support any online repository of prebuilt applications. Adding packages requires rebuilding Yocto or building the required package.
  • Less examples and documentation available online
Android
  • Simple well defined API using well documented tools
  • Allows existing apps to be run without huge customization
  • Under Android it is difficult to access hardware that is not found on an Android tablet/phone. This includes interfaces such as UARTs, GPIO, or ADC
    • A common method is to write a C application which communicates over a localhost socket to an Andoird application in order to interface with hardware
  • Slow boot time
  • Poor documentation for OS customization
QNX Neutrino RTOS
  • Real time OS allowing determinitic response times in an application
  • Commercial application support available through QNX
  • Eclipse support
  • License fee required through QNX
  • Not as much driver support as Linux

2 U-Boot

The TS-7970 includes U-Boot as the bootloader to launch the full operating system. When the i.MX6 processor starts it loads U-Boot from the onboard 8MB SPI flash. This allows you to include your boot image on either the SD, eMMC, SATA, NFS, or USB. The U-Boot bootloader is capable of booting Linux, Android, or other operating systems.

On a normal boot you should see output resembling this:

U-Boot 2014.10-gee73348 (Oct 07 2015 - 11:12:20)

I2C:   ready
DRAM:  1 GiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
SF: Detected N25Q64 with page size 256 Bytes, erase size 4 KiB, total 8 MiB
In:    serial
Out:   serial
Err:   serial
Net:   using phy at 7
FEC [PRIME]

By default the device will boot to SD or eMMC depending on the status of "SD Boot" on startup.

To break into the U-Boot console, press and hold the SW1 button while the unit is being powered up. This mode will also check for a USB mass storage device to use for production purposes.

2.1 U-Boot Environment

The SPI flash contains both the U-Boot executable binary and U-Boot environment. Our default build has 8KB of environment space which can be used for variables and boot scripts. The following commands are relevant to manipulating the environment:

# Print all environment variables
env print -a
 
# Sets the variable bootdelay to 5 seconds
env set bootdelay 5;
 
# Variables can also contain commands
env set hellocmd 'led red on; echo Hello world; led green on;'
 
# Execute commands saved in a variable
env run hellocmd;
 
# Commit env changes to the spi flash
# Otherwise changes are lost
env save
 
# Restore env to default
env default -a
 
# Remove a variable
env delete emmcboot

2.2 U-Boot Commands

# The most important command is 
help
# This can also be used to see more information on a specific command
help i2c
 
# This is a command added to u-boot by TS to read the baseboard id
bbdetect
echo ${baseboard} ${baseboardid} 
# The echos willreturn:
# TS-8390 2
 
# Boots into the binary at $loadaddr.  This file needs to have
# the uboot header from mkimage.  A uImage already contains this.
bootm
# Boots into the binary at $loadaddr, skips the initrd, specifies
# the fdtaddr so Linux knows where to find the board support
bootm ${loadaddr} - ${fdtaddr}
 
# Get a DHCP address
dhcp
# 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
fuse
 
# GPIO can be manipulated from u-boot.  Keep in mind that the IOMUX 
# in u-boot is only setup enough to boot the board, so not all pins will
# be set to GPIO mode out of the box.  Boot to the full operating system
# for more GPIO support.
# GPIO are specified in bank, IO in the imx6 manual.  U-boot uses a flat numberspace,
# so for CN2_83/EIM_OE this is bank 2 dio 25, or (32*2)+25=89
# Set CN1_83 low
gpio clear 83
# Set CN1_83 high
gpio set 83
# Read CN1_83
gpio input 83
 
# Control LEDs
led red on
led green on
led all off
led red toggle
 
# This command is used to copy a file from most devices
# Load kernel from SD
load mmc 0:1 ${loadaddr} /boot/uImage
# Load Kernel from eMMC
load mmc 1:1 ${loadaddr} /boot/uImage
# Load kernel from USB
usb start
load usb 0:1 ${loadaddr} /boot/uImage
# Load kernel from SATA
sata init
load sata 0:1 ${loadaddr} /boot/uImage
 
# You can view the fdt from u-boot with fdt
load mmc 0:1 ${fdtaddr} /boot/imx6q-ts4900.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
load mmc 0:1 ${loadaddr} /boot/custombinary
go ${loadaddr}
 
# Browse fat,ext2,ext3,or ext4 filesystems:
ls 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.
mtest
 
# Check for new SD card
mmc rescan
# Read SD card size
mmc dev 0
mmcinfo
# Read eMMC Size
mmc dev 1
mmcinfo
 
# The NFS command is like 'load', but used over the network
dhcp
env set serverip 192.168.0.11
nfs ${loadaddr} 192.168.0.11:/path/to/somefile
 
# Test ICMP
dhcp
ping 192.168.0.11
 
# Reboot
reset
 
# SPI access is through the SF command
# Be careful with sf commands since
# this is where u-boot and the FPGA bitstream exist
# Improper use can render the board unbootable
sf probe
 
# Delay in seconds
sleep 10
 
# You can load HUSH scripts that have been created with mkimage
load 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
else
	echo Could not find kernel
fi
 
# Commands can be timed with "time"
time sf probe
 
# Print U-boot version/build information
version

2.3 Modify Linux Kernel cmdline

The Linux kernel cmdline can be customized by modifying the cmdline_append variable. If new arguments are added, the existing value should also be included with the new arguments.

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

The kernel command line can also be modified from from the onboard Linux. From the linux shell prompt run the following commands to install the necessary tools and create the script:

apt-get update && apt-get install u-boot-tools -y
echo "env set cmdline_append console=ttymxc0,115200 init=/sbin/init quiet" > /boot/boot.scr
mkimage -A arm -T script -C none -n 'tsimx6 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.

2.4 U-boot Recovery

U-Boot itself handles CPU and RAM setup/configuration that needs to be run every boot. Therefore separate binaries are maintained for each CPU grade, RAM part, and RAM size; and the proper binary must be used for the device configuration. On a functional unit, run 'env print imx_type' in U-Boot and it will return the correct device variant.

On startup, the TS-7970 checks the SPI flash for a valid boot header in SPI flash. If it is unable to locate a valid boot header, the CPU falls back to the "serial downloader" which allows the CPU to execute code sent via USB. If the board has a valid boot header, but a damaged or invalid U-Boot binary located in SPI; an RMA return or a TS-9468 development board will be required in order to properly recover the unit. Please contact us for assistance with this.

1) Download u-boot for the correct imx_type variant from the list here: ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7970-linux/u-boot/. See the U-Boot Changelog for information on the changes between released versions.

2) Download and build/install the "imx_usb" loader: https://community.freescale.com/docs/DOC-94117

3) Disconnect power from the device.

4) Remove the "CON EN" jumper.

5) Apply power to the device.

6) Plug a USB type B cable into the P2 connector on the device and connect it to a host PC.

7) Check 'dmesg' or 'lsusb' on the host PC for a new USB connection. This should show a HID device listing NXP or Freescale as the manufacturer. For example:

hid-generic 0003:15A2:0054.0006: hiddev0,hidraw3: USB HID v1.10 Device [Freescale SemiConductor Inc  SE Blank ARIK] on usb-0000:00:14.0-6.4.2/input0

If it does not show the above output, an RMA return or TS-9468 development board will be required in order to properly recover the unit. Please contact us for assistance with this.

8) Hold down SW1.

9) Run 'imx_usb path/to/u-boot.imx' on the host PC while still holding down SW1. Continue holding SW1 for a few seconds after the command is run.

10) Disconnect the USB cable on P2.

11) Set the "CON EN" jumper.

12) Re-insert the USB cable into P2.

At this point, the USB serial device should show up on the host, opening it will reveal that the unit is stopped at the U-Boot prompt. Follow the steps in Update U-Boot to reinstall U-Boot on the SPI flash.

2.5 Linux NFS Boot

U-Boot's NFS support can be used to load a kernel, device tree binary, and root filesystem over the network. The default scripts include an example NFS boot script.

# Set this to your NFS root path.  The server root should be accessible at this path.
env set nfsroot 192.168.0.36:/mnt/storage/imx6/
env save

To boot to an NFS root:

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

2.6 Update U-Boot

WARNING: Installing a custom U-Boot is not recommended and may cause the device to fail to boot.

U-Boot requires a different build for Quad/Dual and Solo/Duallite. When booted to the U-Boot shell, run 'env print imx_type' and it will return the correct U-Boot build that should be used. Copy the built u-boot.imx file or the pre-built binary from our FTP site to the SD card as "/u-boot.imx", and run the following U-Boot commands:

mmc dev 0
load mmc 0:1 ${loadaddr} /u-boot.imx
sf probe
sf erase 0 0x80000
sf write ${loadaddr} 0x400 $filesize

2.7 U-boot Development

While we do provide our u-boot sources, we typically do not recommend rebuilding a custom uboot if it can be avoided. This CPU has a long lifetime which will outlast most RAM chips. If we have to update the RAM timing later in the boards life due to an EOL, die change, or any other change that may require new RAM configuration/timing changes, we will update this in our shipping u-boot. If this happens in the future our shipping u-boot will include these fixes and not require user intervention. If you are using a custom u-boot you may need to pull down our new changes and rebuild to get the updated configuration.

Our u-boot includes a variable "imx_type". With a custom u-boot, make sure to check the value of this before writing. If we are forced to update the RAM configuration we will change this variable. We will also send out a product change to anyone who is subscribed to our PCS system.

If you still want to proceed with building a custom u-boot, use the imx_v2015.04_3.14.52_1.1.0_ga branch from the github here: https://github.com/embeddedarm/u-boot-imx

Boot up a TS-7970 into u-boot and run "echo ${imx_type}". This will show you the u-boot config to use for the correct RAM timing. We use the same GCC 6.2 used from Yocto Morty to compile the u-boot binary.

export ARCH=arm
export CROSS_COMPILE=/opt/poky/2.2.1/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-
 
git clone https://github.com/embeddedarm/u-boot-imx.git -b imx_v2015.04_3.14.52_1.1.0_ga
cd u-boot-imx
 
# For example, one of the quad core variants.  Replace this with your imx_type
make ts7970-s-1g-800mhz-i_defconfig
make -j4

This will output a u-boot.imx that can be written to the board using the steps in #Update u-boot.

2.8 Access U-boot Environment from Linux

U-Boot includes a utility fw_printenv which set set/read environment variables from Linux. This must be built and provided with a config file before it will work.

On the board first boot to u-boot by holding SW1 pressed on startup. At the prompt run:

U-Boot > env print imx_type
imx_type=ts7970-s-1g-800mhz-i

Save this output then boot to Linux to build the fw_printenv tool.

cd /usr/src/
git clone --depth 1 https://github.com/embeddedarm/u-boot-imx.git -b imx_v2015.04_3.14.52_1.1.0_ga
cd u-boot-imx

Since u-boot gave us "imx_type=ts7970-s-1g-800mhz-i", the example defconfig is ts4900-s-1g-800mhz-i_defconfig. Your board's defconfig may be different and this build should match.

make ts7970-s-1g-800mhz-i_defconfig
make -j4 env
cp tools/env/fw_printenv /usr/bin/
# The same utility sets environment variables when
# called as fw_setenv
ln -s /usr/bin/fw_printenv /usr/bin/fw_setenv

The board will also need a config file to know where to load the environment. Create a file /etc/fw_env.config

# SPI flash on the TS-7970/TS-7990
# MTD device name	Device offset	Env. size	Flash sector size	Number of sectors
/dev/mtdblock0		0x100000	0x2000		0x1000			2
/dev/mtdblock0		0x180000	0x2000		0x1000			2

From here you can run "fw_printenv" and read the environment variables. If first line of output is:

Warning: Bad CRC, using default environment

Then the environment is blank, and u-boot is loading the environment compiled into the u-boot binary. This is normal and is how boards are shipped.

You can modify variables with this command as well:

# Set cmdline_append to include "quiet"
fw_setenv cmdline_append console=ttymxc0,115200 ro init=/sbin/init quiet

3 Debian

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. This distribution does not include the same support as Yocto for the GPU. OpenGL ES, Gstreamer, or OpenCL are not supported in Debian. The framebuffer is supported so 2D applications will still run well. Debian is also very well suited for headless applications.

3.1 Getting Started with Debian

Once installed the default user is "root" with no password.

Note: This is a shared image that supports the TS-4900, TS-7970, and TS-TPC-7990.


To prepare an SD card, use partitioning tools such as 'fdisk' 'cfdisk' or 'gparted' in linux to create a single linux partition on the SD card. See the guide here for more information. Once it is formatted, extract the above tarball with:

# Assuming your SD card is /dev/sdc with one partition
mkfs.ext3 /dev/sdc1
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar xjf debian-armhf-jessie-latest.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync
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. Older versions of e2fsprogs do not need these options passed.

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

mkfs.ext3 /dev/mmcblk2p1
mkdir /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
wget -qO- ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/ts-4900-linux/distributions/debian/debian-armhf-jessie-latest.tar.bz2 | tar xj -C /mnt/emmc/
umount /mnt/emmc
sync


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

3.2 Debian Networking

From almost any Linux system you can use 'ip' command or the 'ifconfig' and 'route' commands to initially set up the network.

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

Most networks will offer a DHCP server, an IP address can be obtained from a server with a single command in linux:

Configure DHCP in Debian:

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


Systemd provides a networking configuration option to allow for automatic configuration on startup. Systemd-networkd has a number of different configuration files, some of the default examples and setup steps are outlined below.

/etc/systemd/network/eth.network

[Match]
Name=eth*
 
[Network]
DHCP=yes

To use DHCP to configure DNS via systemd, start and enable the network name resolver service, systemd-resolved:

systemctl start systemd-resolved.service 
systemctl enable systemd-resolved.service
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf


For a static config create a network configuration for that specific interface.

/etc/systemd/network/eth0.network

[Match]
Name=eth0
 
[Network]
Address=192.168.0.50/24
Gateway=192.168.0.1
DNS=192.168.0.1

For more information on networking, see Debian and systemd's documentation:

3.2.1 Debian WIFI Client

If connecting to a WPA/WPA2 network, a wpa_supplicant config file must first be created:

wpa_passphrase yournetwork yournetworkpassphrase > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf


Create the file /lib/systemd/system/wpa_supplicant@.service with these contents

[Unit]
Description=WPA supplicant daemon (interface-specific version)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
 
[Service]
Type=simple
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I
 
[Install]
Alias=multi-user.target.wants/wpa_supplicant@%i.service


Next, enable the service to start up on boot:

systemctl enable wpa_supplicant@wlan0


Create the file /etc/systemd/network/wlan0.network with:

[Match]
Name=wlan0
 
[Network]
DHCP=yes


See the systemctl-networkd example for setting a static IP for a network interface. The wlan0.network can be configured the same way as an eth.network. To enable all of the changes that have been made, run the following commands:

systemctl enable wpa_supplicant@wlan0
systemctl start wpa_supplicant@wlan0
systemctl restart systemd-networkd

3.2.2 Debian WIFI Access Point

First, hostapd needs to be installed in order to manage the access point on the device:

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

Note: The install process will start an unconfigured hostapd process. This process must be killed and restarted before a new hostapd.conf will take effect.

Edit /etc/hostapd/hostapd.conf to include the following lines:

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


To start the access point launch hostapd:

hostapd /etc/hostapd/hostapd.conf &

This will start up an access point that can be detected by WIFI clients. A DHCP server will likely be desired to assign IP addresses. Refer to Debian's documentation for more details on DHCP configuration.

3.3 Debian Application Development

3.3.1 Debian Jessie Cross Compiling

Debian Jessie provides cross compilers from its distribution. An install on a workstation can build for the same release on other architectures. A PC, virtual machine, or chroot will need to be used for this. Install Debian Jessie for your workstation here.

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

# Run "lsb_release -a" and verify Debian 8.X is returned.  These instructions are not
# expected to work on any other version or distribution.
 
apt-get install curl build-essential
 
su root
echo "deb http://emdebian.org/tools/debian jessie main" > /etc/apt/sources.list.d/emdebian.list
curl http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | apt-key add -
dpkg --add-architecture armhf
apt-get update
apt-get install crossbuild-essential-armhf

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 Jessie 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 .so. 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:
./hello-world
# Returns Exec format error
apt-get install qemu-user-static
./hello-world

3.4 Debian Installing New Software

Debian provides the apt-get system which allows management of pre-built applications. First apt will need a network connection to the internet. The update command will download a list of prebuilt packages and the current version.

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

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.

3.5 Debian Setting up SSH

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

apt-get install openssh-server

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

passwd root

SSH in Debian Jessie also now either requires a key, or requires editing /etc/ssh/sshd_config. Comment out the line that says:

PermitRootLogin without-password

After this configuration it is now possible to connect from a remote pc supporting SSH. On Linux/osx 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 can save login time to add "UseDNS no" in /etc/ssh/sshd_config.

3.6 Debian Starting Automatically

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

[Unit]
Description=Run an application on startup
 
[Service]
Type=simple
ExecStart=/usr/local/bin/your_app_or_script
 
[Install]
WantedBy=multi-user.target

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.

To start an application on bootup with X11 instead change the x-session-manager. By default the system starts xfce:

root@ts:~# ls -lah /usr/bin/x-session-manager 
lrwxrwxrwx 1 root root 35 May 26  2015 /usr/bin/x-session-manager -> /etc/alternatives/x-session-manager
root@ts:~# ls -lah /etc/alternatives/x-session-manager
lrwxrwxrwx 1 root root 19 May 26  2015 /etc/alternatives/x-session-manager -> /usr/bin/startxfce4

The x-session can be modified to only start specified processes. Create the file /usr/bin/mini-x-session with these contents:

#!/bin/bash
matchbox-window-manager -use_titlebar no &
 
exec xfce4-terminal

You may need to "apt-get install matchbox-window-manager." first. This is a tiny window manager which also has a few flags that simplify embedded use. Now enable this session manager and restart slim to restart x11 and show it now.

chmod a+x /usr/bin/mini-x-session
rm /etc/alternatives/x-session-manager
ln -s /usr/bin/mini-x-session /etc/alternatives/x-session-manager
service slim restart

If the x-session-manager process ever closes x11 will restart. The exec command allows a new process to take over the existing PID. In the above example xfce4-terminal takes over the PID of x-session-manager. If the terminal is closed with commands like exit the slim/x11 processes will restart.

4 Ubuntu

Ubuntu is a distribution provided by Canonical which is based on Debian. Ubuntu often has more recent packages but follows a shorter release cycle. The image we provide is based on Ubuntu. We use the root filesystem, but the kernel is not provided by Ubuntu or in any way associated with Canonical. Our Kernel is based on the imx_4.1.15_1.0.0_ga release from git.freescale.com. This is patched to provide support for our boards and peripherals.

This image includes support for the TS-4900, TS-7970, and TS-TPC-7990.

4.1 Getting Started with Ubuntu

The latest release is available here:

The login is either "root" with no password, or username "ubuntu" with the password "ubuntu". The ubuntu user is allowed to run sudo.

To write this to an SD card, first partition the SD card to have one large ext4 partition. See the guide here for more information. Once it is formatted, extract this tar with:

# Assuming your SD card is /dev/sdc with one partition
mkfs.ext3 /dev/sdc1
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar xjf ubuntu-armhf-16.04-latest.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync

To rewrite the eMMC, boot to the SD card. You cannot rewrite the emmc while it is mounted elsewhere, or used to currently boot the system. Once booted to the SD, run:

mkfs.ext3 /dev/mmcblk2p1
mkdir /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
wget -qO- ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/ts-4900-linux/distributions/ubuntu/ubuntu-armhf-16.04-latest.tar.bz2 | tar xj -C /mnt/emmc/
umount /mnt/emmc
sync


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. Older versions of e2fsprogs do not need these options passed.

4.2 Ubuntu Networking

From almost any Linux system you can use "ip" or the ifconfig/route commands to set up the network.

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

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

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

To make DHCP run on startup systemd's networking will need to be configured.

In /etc/systemd/network/eth.network

[Match]
Name=eth*
 
[Network]
DHCP=yes

Then, if you intend to use DHCP to configure your DNS, start and enable the network name resolver service:

systemctl start systemd-resolved.service 
systemctl enable systemd-resolved.service
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf

For a static configuration create a config file for that specific interface. /etc/systemd/network/eth0.network

[Match]
Name=eth0
 
[Network]
Address=192.168.0.50/24
Gateway=192.168.0.1
DNS=192.168.0.1

For more information on networking, see Ubuntu and systemd's documentation:

4.2.1 Ubuntu WIFI Client

If connecting to a WPA/WPA2 network, a wpa_supplicant config file must first be created:

wpa_passphrase yournetwork yournetworkpassphrase > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf


Create the file /lib/systemd/system/wpa_supplicant@.service with these contents

[Unit]
Description=WPA supplicant daemon (interface-specific version)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
 
[Service]
Type=simple
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I
 
[Install]
Alias=multi-user.target.wants/wpa_supplicant@%i.service


Next, enable the service to start up on boot:

systemctl enable wpa_supplicant@wlan0


Create the file /etc/systemd/network/wlan0.network with:

[Match]
Name=wlan0
 
[Network]
DHCP=yes


See the systemctl-networkd example for setting a static IP for a network interface. The wlan0.network can be configured the same way as an eth.network. To enable all of the changes that have been made, run the following commands:

systemctl enable wpa_supplicant@wlan0
systemctl start wpa_supplicant@wlan0
systemctl restart systemd-networkd

4.2.2 Ubuntu WIFI Access Point

First, hostapd needs to be installed in order to manage the access point on the device:

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

Note: The install process will start an unconfigured hostapd process. This process must be killed and restarted before a new hostapd.conf will take effect.

Edit /etc/hostapd/hostapd.conf to include the following lines:

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


To start the access point launch hostapd:

hostapd /etc/hostapd/hostapd.conf &

This will start up an access point that can be detected by WIFI clients. A DHCP server will likely be desired to assign IP addresses. Refer to Debian's documentation for more details on DHCP configuration.

4.3 Ubuntu Application Development

4.3.1 Ubuntu Cross Compiling

Ubuntu armhf Cross Compile

4.4 Ubuntu Installing New Software

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

apt-get update

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

root@ts-imx6:~# 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 likely want openjdk-7-jre to provide a runtime environment, and possibly openjdk-7-jdk to provide a development environment.

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

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

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

4.5 Ubuntu Setting up SSH

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

apt-get install openssh-server

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

passwd root

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

4.6 Ubuntu Starting Automatically

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

[Unit]
Description=Run an application on startup
 
[Service]
Type=simple
ExecStart=/usr/local/bin/your_app_or_script
 
[Install]
WantedBy=multi-user.target

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.

To start an application on bootup with X11 instead change the x-session-manager. By default the system starts xfce:

root@ts:~# ls -lah /usr/bin/x-session-manager 
lrwxrwxrwx 1 root root 35 May 26  2015 /usr/bin/x-session-manager -> /etc/alternatives/x-session-manager
root@ts:~# ls -lah /etc/alternatives/x-session-manager
lrwxrwxrwx 1 root root 19 May 26  2015 /etc/alternatives/x-session-manager -> /usr/bin/startxfce4

The x-session can be modified to only start specified processes. Create the file /usr/bin/mini-x-session with these contents:

#!/bin/bash
matchbox-window-manager -use_titlebar no &
 
exec xfce4-terminal

You may need to "apt-get install matchbox-window-manager." first. This is a tiny window manager which also has a few flags that simplify embedded use. Now enable this session manager and restart slim to restart x11 and show it now.

chmod a+x /usr/bin/mini-x-session
rm /etc/alternatives/x-session-manager
ln -s /usr/bin/mini-x-session /etc/alternatives/x-session-manager
service slim restart

If the x-session-manager process ever closes x11 will restart. The exec command allows a new process to take over the existing PID. In the above example xfce4-terminal takes over the PID of x-session-manager. If the terminal is closed with commands like exit the slim/x11 processes will restart.

5 Ubuntu Core

Ubuntu Core is a new distribution provided by Canonical targetted towards embedded/IoT projects. This requires users to generate "snap" packages for their application, but provides a mechanism for save remote updates to the OS and packages. Our kernel is based on Ubuntu 16's 4.4 based kernel to provide the best compatibility and support. Bug fixes to units using our kernel snap are provided through the ubuntu core app store.

Read more about Ubuntu Core here.

5.1 Getting Started with Ubuntu Core

Download our latest image here.

Write this to an SD card with:

wget ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/ts-4900-linux/distributions\
/ubuntu-core/ubuntu-core-16-latest.img.bz2
bzip2 -d ubuntu-core-16-latest.img.bz2
# Assuming /dev/sdd is your SD card.  Check dmesg after inserting for yoru device.
# Make sure this is the block device (/dev/sdd) and not a partition (/dev/sdd1).
dd if=/path/to/ubuntu-core-16-latest.img bs=4M of=/dev/sdd conv=fsync && sync

This can be written to emmc using the #TS-4900_Production USB production mechanism.

Next make an Ubuntu SSO account. Generate SSH keys and upload your SSH keys to your account.

Once written to either boot media start up the board. After boot has completed it will leave you at a screen:

Press Enter to Configure

Ubuntu core has no default username/password and must be configured with their single sign on service to fetch your SSH keys.

Press enter and it will have you confirm DHCP, or use a static network configuration. Once configured it will ask for your Ubuntu SSO username. This will create an account on the Ubuntu Core image and allow access only with your SSH keys present on the store. After it has fetched your keys it will print out the ssh commands to connect to your unit which will now allow access just with your SSH keys.

Connect to the board with:

ssh <ubuntu SSO username>@<IP of board>
Note: This must be run on a system that has your SSH keys installed.

Once connected you have access to a shell prompt and can install any needed snaps. See http://snapcraft.io/ for more information on developing your own snaps for your application which can be uploaded to the store.

5.2 Ubuntu Core Reference Links

6 Yocto

Yocto is our recommended distribution for graphics packages. It includes patches to support the GPU. X11 includes drivers for providing 2d support. OpenGLES 1&2, as well as GStreamer acceleration are included standalone or with QT. Yocto also provides cross toolchains that include the rootfs. This toolchain allows integration with the QT Creator IDE and Eclipse.

Yocto does not provide binary security updates. This distribution also does not have any remote repository of prebuild applications. For either of these we features we recommend Debian.

Our current Yocto support is based off of Yocto 2.2 "Morty".

6.1 Getting Started with Yocto

Yocto itself is a set of scripts and tools used to build a custom Distribution. In our default images we try to include all the common utilities requested by users. Rebuilding Yocto should not be necessary for many users, but is possible if needed. Once installed the default user is "root" with no password.

Our Yocto rootfs is available here:

Yocto Download Links
Yocto Image Download Link
ts-x11-image Download

To write this to an SD card, first partition the SD card to have one large ext4 partition. See the guide here for more information. Once it is formatted, extract this tar with:

# Assuming your SD card is /dev/sdc with one partition
mkfs.ext3 /dev/sdc1
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar -jxf ts-x11-image-tsimx6-latest.rootfs.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync
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. Older versions of e2fsprogs do not need these options passed.

To rewrite the eMMC, boot to the SD card. You cannot rewrite the emmc while it is mounted elsewhere, or used to currently boot the system. Once booted to the SD, run:

mkfs.ext3 /dev/mmcblk2p1
mkdir /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
wget -qO- ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/\
ts-4900-linux/distributions/yocto/morty/ts-x11-image-tsimx6-\
latest.rootfs.tar.bz2 | tar xj -C /mnt/emmc/
umount /mnt/emmc
sync

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

6.2 Yocto Networking

Our Yocto image uses systemd which stores its network files in "/etc/systemd/network/". The simplest network config for a DHCP configuration would look like this:

In /etc/systemd/network/eth.network

[Match]
Name=eth*
 
[Network]
DHCP=yes

For a static configuration create a config file for that specific interface. /etc/systemd/network/eth0.network

[Match]
Name=eth0
 
[Network]
Address=192.168.0.50/24
Gateway=192.168.0.1
DNS=192.168.0.1

For more information on what options are available to configure the network, see the systemd network documentation.

6.2.1 Yocto Wireless

Yocto uses systemd to start wpa_supplicant, and networkd to get a dhcp or static IP on that network.

Scan for a network

ifconfig wlan0 up
 
# Scan for available networks
iwlist wlan0 scan

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

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

To connect to this open network manually for just this boot:

iwconfig wlan0 essid "default"

Use the iwconfig command to determine authentication to an access point. Before connecting it will show something like this:

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

If connecting using WEP, also specify a network key:

iwconfig wlan0 essid "default" key "yourpassword"

If connecting to a WPA network use wpa_passphrase and wpa_supplicant:

mkdir /etc/wpa_supplicant/
wpa_passphrase the_essid the_password >> /etc/wpa_supplicant/wpa_supplicant-wlan0.conf

After generating the configuration file the wpa_supplicant daemon can be started.

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

This will come back with:

 root@ts-imx6-q:~# wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -B
 Successfully initialized wpa_supplicant
 root@ts-imx6-q:~# [  306.924691] wlan0: authenticate with 28:cf:da:b0:f5:bb
 [  306.959415] wlan0: send auth to 28:cf:da:b0:f5:bb (try 1/3)
 [  306.968137] wlan0: authenticated
 [  306.978477] wlan0: associate with 28:cf:da:b0:f5:bb (try 1/3)
 [  306.988577] wlan0: RX AssocResp from 28:cf:da:b0:f5:bb (capab=0x1431 status=0 aid=9)
 [  307.009751] wlan0: associated
 [  307.012768] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
 [  307.047989] wlcore: Association completed.

Use "iwconfig wlan0" to verify an "Access Point" is specified to verify a connection. This will also report the link quality to the AP.

Wireless may be associated, but this does not get an IP on the network. To connect to the internet or talk to the internal network first configure the interface. See the #Configuring the Network, but on many networks only a DHCP client is needed:

udhcpc -i wlan0

Systemd can also be configured to start wpa_supplicant on boot up.

# Assuming the same path for the wpa conf file as shown above
systemctl enable wpa_supplicant@wlan0
systemctl start wpa_supplicant@wlan0

Once this service is started it will bring up the wlan0 link and associate it to the specified access point. Configure the IP settings the same way as a wired network.

In /etc/systemd/network/wlan0.network

[Match]
Name=wlan0
 
[Network]
DHCP=yes

For a static configuration create a config file for that specific interface. /etc/systemd/network/wlan0.network

[Match]
Name=wlan0
 
[Network]
Address=192.168.0.50/24
Gateway=192.168.0.1
DNS=192.168.0.1

For more information on what options are available to configure the network, see the systemd network documentation.

6.3 Yocto Application Development

Yocto provides cross toolchains including the native tools and required arm files. First get the toolchain by right clicking and "Save as":

In the case of either toolchain you would run these commands to install them:

chmod a+x poky-*.sh
sudo ./poky-*.sh

To build an application first source the environment for the toolchain:

source /opt/poky/2.2.1/environment-setup-cortexa9hf-neon-poky-linux-gnueabi
 
# Assuming you have a hello.c:
$CC hello.c -o hello
 
#If you cat the environment file you can see all the paths this sets up.
$ echo $CC
arm-poky-linux-gnueabi-gcc -march=armv7-a -marm -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/opt/poky/2.0.2/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi

It is also possible to develop over the serial console or ssh on the board itself. Yocto includes development tools such as vim, gcc, g++, gdb, make, autoconf, binutils, and more. See the next sections for using the cross toolchain with IDEs.

6.3.1 Configure QT Creator IDE

Note: This guide is intended for our stock image using systemd. On custom images the directions should apply if a toolchain is compiled. bitbake meta-toolchain-qt5, and update the paths if you are using a different distribution.

Install qtcreator. The version from a recent Linux distribution should be fine. In a debian/Ubuntu desktop, run:

sudo apt-get update && sudo apt-get install qtcreator -y

You will also need to download the SDK which includes the QT support (Right click and save as):

You can install these with:

sudo bash ./poky-*.sh

These instructions assume the path will be default at "/opt/poky/2.2.1/".

An environment script has to be sourced ***every time*** before launching qtcreator. Without this builds will fail.

source /opt/poky/2.2.1/environment-setup-cortexa9hf-neon-poky-linux-gnueabi
qtcreator

Next we need to configure QT Creator to build using this toolchain. When QT creator launches and go to Tools->Options, and select Devices. Click "Add" and select "Generic Linux Device" and click "Start Wizard".

QT Device Configuration

On the next page specify the ip address or hostname to the system. In this example, the board has a dhcp address of 192.168.2.45. The default Yocto image will use "root" with no password to connect. Set the name to TSIMX6.

QT Device Configuration

It will then verify connectivity. Click close and continue.

QT Device Test
Note: If this returns an error: "SSH connection failure: SSH Protocol error: Server and client capabilities don't match. Client list was: aes128-cbc,3des-cbc.

Server list was chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com.". If this happens connect to the board's console and edit /etc/ssh/sshd_config and append the line "Ciphers +aes128-cbc". Reset sshd, or reboot the board and try again. Upgrading Qt Creator may also resolve this issue.

Note: The paths given in the images may not match the latest toolchain, but are meant to show where these values would go. Follow the text appropriate to the architecture of your host pc for the correct values

Next, in the left column of the Options menu, select "Build & Run". Start with the "QT Versions" tab, and click "Add" in the upper right to configure the TS Kit. QT creator may see the "qmake" binary added to your path from the sourced environment script. Either use this, or add it in, but change the version string to include "TSIMX6". This will allow it to be recognized when setting the right binary for the kit.

i686
/opt/poky/2.2.1/sysroots/x86-pokysdk-linux/usr/bin/qt5/qmake
x86_64
/opt/poky/2.2.1/sysroots/x86_64-pokysdk-linux/usr/bin/qt5/qmake
QT Versions tab

Next go to the "Compilers" tab, and click "Add", and select "GCC". Set the Name to "TSIMX6 GCC". For the "Compiler Path":

i686
/opt/poky/2.2.1/sysroots/i686-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++
x86_64
/opt/poky/2.2.1/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++
QT Compiler tab

Next, go to the Debuggers tab, and click "Add". For name, specify "TSIMX6 GDB". For the paths, specify the location of gdb:

i686
/opt/poky/2.2.1/sysroots/i686-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gdb
x86_64
/opt/poky/2.2.1/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gdb
QT Debugger tab

Next, go to the "Kits" tab and click add. For Name, enter "TSIMX6". Set device type to "Generic Linux Device". Set the device to "TSIMX6 (default for Generic Linux)". Set the sysroot to:

/opt/poky/2.2.1/sysroots/cortexa9hf-neon-poky-linux-gnueabi/

Set QT mkspec to:

/opt/poky/2.2.1/sysroots/cortexa9hf-neon-poky-linux-gnueabi/usr/lib/qt5/mkspecs/linux-oe-g++

Set the compiler to "TSIMX6 GCC". Set Debugger to "TSIMX6 GDB". Set the QT version to "TSIMX6 QT 5.7.1". Finally, click Apply.

QT Kit tab

At this point QT Creator is set up to begin a hello world project.

6.3.1.1 QT Creator Hello World

Open the QT Creator IDE and click "New Project".

QT New Project

QT provides multiple templates for application development. For this example select the default "QT Widgets Application".

QT Widgets App

Specify the location for your project. Keep in mind that the compile process will create more build paths in the "Create In:" path.

QT Location

Next, select the kit. The TSIMX6 is the kit we set up in the last section, but you may have other kits preinstalled on your system. These can be used for testing graphical development on your PC. Keep in mind distribution versions may contain different functionality.

QT Select Kit

Next select the class and filename information. This example will use the defaults.

QT Select Classes

Select any version control for the project. The example will use none and finish the wizard. This will generate the new project.

QT Project Management

Click the button under "Help" on the left column, and select "TSIMX6" debug. If you only have one kit selected this will be default.

QT Select build

Now return to edit, and open the QT project file (qt5-helloworld.pro). Add in these lines anywhere after the target is specified:

linux-* {
    target.path = /home/root/
    INSTALLS += target
}
QT pro file

At this point click the green allow in the bottom left to run the application. This can also be launched from the menu at Build->Run.

QT Build and Deploy

From here, you can begin customizing your application. Refer to the official QT documentation for more information

6.3.2 Yocto Hide Cursor

The default image includes the xcursor-transparent icon theme. This can hide the mouse pointer. To enable this, run these commands:

mkdir -p ~/.icons/default/
 
echo "[Icon Theme]" > ~/.icons/default/index.theme
echo "Inherits=xcursor-transparent" >> ~/.icons/default/index.theme
 
# Now reset x, or reset the unit and the cursor will be invisible.

6.4 Yocto Startup Scripts

To have your headless application start up on poweron you need to create a service. Create a file in /etc/systemd/system/yourapp.service

[Unit]
Description=Run an application on the i.MX6
 
[Service]
Type=simple
ExecStart=/usr/local/bin/your_app_or_script
 
[Install]
WantedBy=multi-user.target

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

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

To have a graphical application startup change the file: /usr/bin/mini-x-session

At the end of the script replace matchbox-terminal with your application:

matchbox-terminal&
exec matchbox-window-manager

Keep the exec statement before your application. If your process ends then X11 will stop with it.

6.5 Custom Build Yocto

If you are familiar with Yocto you can rebuild the distribution with your own custom set of features including very few files to make a tiny image, or add some package onto our image to include something we missed.

While we may provide guidance, our free support does not include every situation that can cause a build failure in generating custom images.

7 QNX

QNX is an RTOS that supports the i.MX6 CPU. We provide a BSP for the TS-4900 and TS-7970 quad core or solo based on QNX Neutrino 6.6.0. The supporting files are available here:

We provide support for booting QNX on our platforms, but further support is provided by QNX

Known Working:

  • UARTs 1-5
  • Ethernet
  • I2C 1, I2C 2
  • SD (/dev/hd0)
  • eMMC (/dev/emmc0)
  • USB Host
  • SPI NOR (/dev/fs0)
  • HDMI (TS-7970 only)
  • LCD Interface (TS-TPC-8390 with TS-4900 only)
  • RS485

Known not working:

  • WIFI
  • FPGA based UARTs

Not yet tested:

  • I210 (Second gig eth)

7.1 QNX BSP

Before compiling QNX be sure to edit the file: src/hardware/startup/boards/imx6x/ts7970/board.h Set either BOARD_TS7970 or BOARD_TS4900 depending on the target board.

We have also included a port of tshwctl which is used to access the FPGA. This allows you to read/write FPGA registers and to change the crossbar. For example, to set up auto TXEN on the TS-7970 RS-485 port (/dev/ser4):

export MB_TXD=TTYSER4_TXD
export TTYMAX1_RXD=GPIO
export TTYSER4_RXD=MB_RXD_485
export TXD_232_COM=GPIO
export MB_TX_EN_485=TTYSER4_TXEN
tshwctl -b 0x7970 -s
 
tshwctl -b 0x7970 -c

This will print out the modified state of the crossbar. The relevant pins are now:

  TTYSER4_RXD ( in) (  0) MB_RXD_485  
       MB_TXD ( in) (  0) TTYSER4_TXD
 MB_TX_EN_485 ( in) (  0) TTYSER4_TXEN                                          
  TTYMAX1_RXD ( in) (  0) GPIO                                                  
  TXD_232_COM ( in) (  0) GPIO   

Use tshwctl to specify the baud rate and mode of the uart so the TX enable pin will be automatically toggled.

tshwctl -b 0x7970 -a 4 -x 115200 -i 8n1

/dev/ser4 is now configured for RS485 traffic.

7.2 QNX Booting

Write the example image to a disk.

bzip2 -d ts7970-qnx-6.6.0-20150707.dd.bz2
 
#Replace sdx with your device.  Try lsblk to find your SD card.
sudo dd if=ts7970-qnx-6.6.0-20150707.dd bs=4M of=/dev/sdx
sync

Reinsert or partprobe the disk, and there will be a single partition present. The partition includes the QNX IFS, and a u-boot script. On startup the imx6 is configured to launch the hush script. If present, at /boot/boot.ub on either the SD or eMMC depending on if the SD boot jumper is present. The script loads the FPGA, then copies the QNX ifs into memory and jumps into it to begin execution.

8 Backup / Restore

8.1 MicroSD Card

These instructions assume you have an SD card with one partition. Most SD cards ship this way by default. If the card has had its partition table modified this can be corrected with a tool like 'gparted' or 'fdisk'.

Plug the SD card into a USB reader and connect it to a linux workstation PC. Newer distributions include a utility called 'lsblk' which lists all block devices like a USB SD card reader:

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

In this case the SD card is 4GB, so sdX is the target device. Note that on your system, sdX will not be a real device, it could be sda, sdb, mmcblk0, etc. Technologic Systems is not responsible for any damages cause by using the improper device node for imaging an SD card.

After plugging in the device after Linux has booted you can use dmesg to print out the kernel log. When the USB drive is added it will append to the end of that file. Try running:

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

In this case, sdXc is shown as a 3.97GB card. Note that on your system, sdX will not be a real device, it could be sda, sdb, mmcblk0, etc. Technologic Systems is not responsible for any damages cause by using the improper device node for imaging an SD card.

The following commands will reformat the first partition of the SD card, and unpack the latest filesystem on there:

# Verify nothing else has this mounted
sudo umount /dev/sdX1
 
sudo mkfs.ext3 /dev/sdX1
sudo mkdir /mnt/sd
sudo mount /dev/sdX1 /mnt/sd/
wget ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/ts-4900-linux/distributions/yocto/fido/ts-x11-image-tsimx6-latest.tar.bz2
 
sudo tar -xf ts-x11-image-tsimx6-latest.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync
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. Older versions of e2fsprogs do not need these options passed.

Once written, the files on disk can be verified to ensure they are the same as the source files in the archive. Reinsert the disk to flush the block cache completely, then run the following commands:

mount /dev/sdX1 /mnt/sd
cd /mnt/sd/
sudo md5sum --quiet -c md5sums.txt
cd -
umount /mnt/sd
sync

The md5sum command will report what differences there are, if any, and return if it passed or failed.

8.2 eMMC

Write the image:

These commands assume you are booted to the SD card, and

# Verify nothing else has this mounted
umount /dev/mmcblk2p1
 
mkfs.ext3 /dev/mmcblk2p1
mkdir /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
wget ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/ts-4900-linux/distributions/yocto/fido/ts-x11-image-tsimx6-latest.tar.bz2
tar -xf ts-x11-image-tsimx6-latest.tar.bz2 -C /mnt/emmc
umount /mnt/emmc
sync
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. Older versions of e2fsprogs do not need these options passed.

After it is written you can verify the data was written correctly.

# Drop any block cache
echo 3 > /proc/sys/vm/drop_caches
mount /dev/mmcblk2p1 /mnt/emmc
cd /mnt/emmc/
sudo md5sum -c md5sums.txt
umount /mnt/emmc
sync

The md5sum command will report what differences there are, if any, and return if it passed or failed.

Backup the image:

First boot the board to any SD image. The SD should have enough space for the compressed image of your eMMC. From our default image this is ~500MB. To create an image to your SD card:

mkdir /mnt/sd/
mount /dev/mmcblk1p1 /mnt/sd/
cd /mnt/sd/
tar -cjf /root/backup.tar.bz2 *
cd -
umount /mnt/sd/

9 Compile the Kernel

This board uses a 4.1.15 kernel on most all images. Our kernels are based on NXP's which are changed from upstream for their board support. We change them to support the various hardware we use with this processor.

  • embeddedarm/linux-3.10.17-imx6
  • The "imx_4.1.15_1.0.0_ga" branch includes support for our TS-4900, TS-7970, TS-7990, and TS-4100.
    • This kernel works with all our Debian releases, Ubuntu, Yocto Jethro, and Yocto Krogoth.

You can pick the branch below. The kernel can be rebuilt by cross compiling from an X86/X86_64 Linux. Our default kernels are rebuilt using the toolchains built by Yocto. You can download the appropriate cross toolchain for your Linux system here:

chmod a+x poky-*toolchain-*.sh
sudo ./poky-*toolchain-*.sh

This will ask for the install directory for the toolchain. Our instructions will assume the default path is used.

This also requires several tools from your distribution. For Ubuntu/Debian:

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

Once those are installed:

# This will pull our shared kernel, using the 4.1.15 branch, use a folder linux-tsimx, and only
# download the latest changes.
git clone https://github.com/embeddedarm/linux-3.10.17-imx6.git -b imx_4.1.15_1.0.0_ga linux-tsimx --depth 1
cd linux-tsimx
 
# These two must be run each time you open a terminal to build the kernel.
source /opt/poky/2.0.2/environment-setup-cortexa9hf-vfp-neon-poky-linux-gnueabi
export LOADADDR=0x10008000
 
make ts4900_defconfig
 
## Make any changes in "make menuconfig" or driver modifications, then compile
make && make uImage

To install this to a board you would use a USB SD reader and plug in the card. Assuming your Linux rootfs is all on "sdc1":

export DEV=/dev/sdc1
sudo mount "$DEV" /mnt/sd
sudo rm /mnt/sd/boot/uImage
sudo cp arch/arm/boot/uImage  /mnt/sd/boot/uImage
sudo cp arch/arm/boot/dts/imx6*ts*.dtb /mnt/sd/boot/
INSTALL_MOD_PATH="/mnt/sd" sudo -E make modules_install 
INSTALL_HDR_PATH="/mnt/sd" sudo -E make headers_install
sudo umount /mnt/sd/
sync

9.1 Change Kernel Splash Screen

The kernel splashscreen allows 224 colors. It also allows up to the full screen resolution, but for fastest boot speed it should be kept as small as possible. The image will be centered around a black background.

To convert your image, for example, "mylogo.png":

convert mylogo.png mylogo.ppm
ppmquant 224 mylogo.ppm > mylogo-224.ppm
pnmnoraw mylogo-224.ppm > logo_user_clut224.ppm
cp logo_user_clut224.ppm <kernel build sources>/drivers/video/logo/

Now recompile the kernel following the guide in the previous section.

Add the kernel cmdline "logo.nologo" in u-boot to completely disable the splash screen.

10 Features

10.1 ADC

The TS-7970 includes 3 channels of ADC that can sample a 4-20mA current loop at about 2/3 samples per second. These are accessed using the tsmicroctl utility:

root@ts-imx6:# tsmicroctl --info
VDD_ARM_CAP=1216
VDD_HIGH_CAP=2618
VDD_SOC_CAP=1246
VDD_ARM=1456
SILAB_P10=0x39B
SILAB_P11=0x0
SILAB_P12=0x0
VIN=12241
V5_A=5207
V3P1=3276
DDR_1P5V=1571
V1P8=1894
V1P2=1262
RAM_VREF=783
V3P3=3543
SILABREV=1
SILAB_P10_UA=21472
SILAB_P11_UA=0
SILAB_P12_UA=0

The other samples are the various voltages on the board. The terminal block ADC values are returned with SILAB_Pnn and SILAB_Pnn_UA. These include both raw and microamp values.

10.2 Bluetooth

The WIFI option on the board also includes a bluetooth 4.0 LE module. To connect this to bluez first pulse the BT_EN pin, and then call hciattach:

# Install bluez if it is not already present
apt-get update
apt-get install bluez bluez-tools
 
echo 237 > /sys/class/gpio/export
echo low > /sys/class/gpio/gpio237/direction
echo high > /sys/class/gpio/gpio237/direction
sleep .1
hciattach /dev/ttymxc1 texas 3000000
hciconfig hci0 up

Once this is loaded you can scan for devices with:

hcitool scan

This will return a list of devices such as:

	14:74:11:A1:1E:C9	BlackBerry 8530

Bluez has support for many different profiles for HID, A2DP, and many more. Refer to the Bluez documentation for more information.

10.3 CAN

The TS-7970 CAN ports are located on the #COM2 Header and the #Terminal_Blocks.

The i.MX6 includes 2 CAN controllers which support the SocketCAN interface. Before proceeding with the examples, see the Kernel's CAN documentation here.

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

## First, set the baud rate and bring up the device:
ip link set can0 type can bitrate 250000
ip link set can0 up
 
## Dump data & errors:
candump 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) {
		perror("socket");
		return -2;
	}
 
 	/* For the ozen myOByDic 1610 this requests the RPM guage */
	frame.can_id  = 0x7df;
	frame.can_dlc = 3;
	frame.data[0] = 3;
	frame.data[1] = 1;
	frame.data[2] = 0x0c;
 
	nbytes = write(s, &frame, sizeof(struct can_frame));
	if(nbytes < 0) {
		perror("write");
		return -3;
	}
 
	iov.iov_base = &frame;
	msg.msg_name = &addr;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = &ctrlmsg;
	iov.iov_len = sizeof(frame);
	msg.msg_namelen = sizeof(struct sockaddr_can);
	msg.msg_controllen = sizeof(ctrlmsg);  
	msg.msg_flags = 0;
 
	do {
		nbytes = recvmsg(s, &msg, 0);
		if (nbytes < 0) {
			perror("read");
			return -4;
		}
 
		if (nbytes < (int)sizeof(struct can_frame)) {
			fprintf(stderr, "read: incomplete CAN frame\n");
		}
	} while(nbytes == 0);
 
	if(frame.data[0] == 0x4)
		printf("RPM at %d of 255\n", frame.data[3]);
 
	return 0;
}

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

10.4 COM Ports

This board uses UARTs from both the CPU and the FPGA. The CPU uart 0 (/dev/ttymxc0) is dedicated to console for Linux and U-boot and not suggested to be repurposed. The other CPU UARTs for ttymxc1-4 are usable for end applications. These support up to 5Mb/s UART data. The CPU UARTs are routed through the onboard FPGA. This allows these UARTs to support direction control for RS-485 with tshwctl.

The FPGA also includes 3 extra SPI UARTs like the MAX3100 UART. It is possible to use the standard max3100 driver with the FPGA UARTs, but only one UART will be accessible. The FPGA includes one significant difference from the MAX3100 chipset. A byte should precede other SPI traffic to select which "max3100" core is being addressed. This is handled automatically by the driver shipped in our BSP. The MAX3100s also support transmit enable for automatic RS485 half duplex direction control.

None of the RS232/TTL ports need special setup, but the RS485 ttymxc3, or ttymxc1 if used for 485 requires some set up. RS485 half duplex requires toggling a pin to switch between transmit and receive. The ttyMAX uarts include this as part of the FPGA hardware so no setup is required. The CPU UARTs do not do this automatically. The CPU's UARTs are passed through the FPGA to create an automatic transmit enable. This requires the FPGA to know the bit rate and symbol size.

For example:

# Configure mxc1 and mxc3 as 115200, 8n1
 
stty -F /dev/ttymxc1 115200 cs8 -cstopb
tshwctl --autotxen 1
 
stty -F /dev/ttymxc3 115200 cs8 -cstopb
tshwctl --autotxen 3

The tshwctl tool will read the UART settings when it is run and it sets up the FPGA's timing for TXEN. Your baud rate and mode settings should be set before running this.

For 8n1, this will include 8 data bits, no parity, 1 stop bit, as well as one start bit adding up to 10 bits per symbol. 9n1 or parity modes may have more or less bits per symbol.

The ttyMAX ports will work for most situations, but these ports have a couple limitations. It can support about two 115200 links saturated with data, but not a third. This limitation only applies when data is actively being transmitted, not idle UARTs. The FPGA crossbar allows changing UART mappings so bandwidth can be prioritized. For example, to switch around ttymxc1 / ttyMAX0, and ttymxc3 / ttyMAX1:

# Replace ttyMAX0 with ttymxc1 for RS485 which is BT uart by default
# leave bt uart disconnected since it cannot run with SPI uart
export CN1_67=TTYMXC1_TXEN
export TTYMXC1_RXD=CN2_80
export CN2_78=TTYMXC1_TXD
 
# Replace ttyMAX1 for second RS485 port
export CN1_63=TTYMXC3_TXEN
export TTYMXC3_RXD=CN2_96
export CN2_94=TTYMXC3_TXD
 
# Put ttyMAX1 on CN2_86/88 (replace ttymxc3)
export TTYMAX1_RXD=CN2_88
export CN2_86=TTYMAX1_TXD
 
# Apply all these changes
tshwctl --set

All of these UARTs are accessed using the standard /dev/ interfaces. See these resources for information on programming with UARTs in Linux.

The #FPGA includes a crossbar to select where UARTs are routed so these can be changed, but these are the default mappings:

UART Type TX (or +) RX (or -)
ttymxc0 USB USB Device USB Device
ttymxc1 1.8V TTL (onboard only) Onboard Bluetooth RX Onboard Bluetooth TX
ttymxc2 TTL (5V Tolerant) HD1 Header pin 12 HD1 Header pin 10
ttymxc3 RS232 COM2 Header pin 3 COM2 Header pin 2
ttymxc4 RS232 P1-B Terminal Block pin 7 P1-B Terminal Block pin 8
ttyMAX0 RS485 P1-A Terminal Block pin 2, COM2 Header pin 1 P1-A Terminal Block pin 3, COM2 Header pin 6
ttyMAX1 RS485 RJ45 2W-Modbus pin 4 RJ45 2W-Modbus pin 5
ttyMAX2 RS232 COM2 Header pin 7 COM2 Header pin 8

10.5 CPU

The i.MX6 is an armv7a Cortex-A9 by NXP. The CPU itself is available in 792MHz, 996MHz, and 1.2GHz with a solo, dual, or quad core processor.

Refer to NXP's documentation for in depth documentation on these CPU cores:

10.6 eMMC

This board includes a Micron eMMC module with builds that have "4096F" in the part number. 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/mmcblk2. Our default programming will include one partition programmed with our Yocto image.

The eMMC are like SD cards in that they should not be powered down during a write/erase cycle. This eMMC module includes support for setting a fuse for a "Write Reliability" mode, and a "psuedo SLC" mode. With both of these enabled then any writes will be atomic to 512B. If a sector is being written during a power loss, a block is guaranteed to have either the old or new data. This scheme is far more resilient to power loss than more traditional flash media. In cases of old 512B data fsck will still be able to recover a mountable filesystem. In cases where the corrupted file is a database it can still need a mechanism for recovery.

When this pSLC mode is turned on it will reduce the available space to under half, and reduce the write speed.

See our post on preventing filesystem corruption.

The mmc-utils package is used to enable these modes. First determine the exact size of the flash you're using:

mmc extcsd read /dev/mmcblk2 | grep MAX_ENH_SIZE_MULT -A 1
Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x0001cd
 i.e. 1888256 KiB

So in this case, 1888256 KiB is the max size of the enhanced partition. This number should be used for the enh_area command:

mmc write_reliability set -n 0 /dev/mmcblk2
mmc enh_area set -y 0 1888256 /dev/mmcblk2
WARNING: Setting either of those modes is permanent. Using the wrong value it is possible to brick eMMC which will not be covered by the warranty. Evaluation units with fuses set will not be accepted through returns.

After this is run, reboot the board. On all future boots the eMMC will be detected at the smaller size. Changing the enhanced area will erase the drive. After these mmc commands the disk will need to be rewritten.

10.7 Enclosures

Every enclosure includes a front label which exposes 1 button, and 4 status LEDs.

TS-ENC797

The TS-7970 is available with 3 enclosures matching the various build options:

Enclosure Model Images Supported Boards
TS-ENC797
TS-ENC797 Front
TS-ENC797 Back
  • TS-7970-1G-4GF-S8S-RTC-I
  • TS-7970-2G-4GF-Q10S-RTC-E
TS-ENC797-CP
TS-ENC797-CP Front
TS-ENC797-CP Back
  • TS-7970-1G-4GF-S8S-RTC-CP-WIFI-I
  • TS-7970-2G-4GF-Q10S-RTC-CP-WIFI-E
TS-ENC797-CP-WIFI

This enclosure includes WIFI Antenna and UFL to SMA cable.

TS-ENC797-CP-WIFI Front
TS-ENC797-CP-WIFI Back
  • TS-7970-1G-4GF-S8S-RTC-CP-WIFI-I with WIFI antenna
  • TS-7970-2G-4GF-Q10S-RTC-CP-WIFI-E with WIFI antenna

These 3 enclosures can also be ordered with a DIN clip as TS-ENC797-DIN, TS-ENC797-CP-DIN, and TS-ENC797-CP-WIFI-DIN.

TS-ENC797-DIN

10.8 FPGA

The Lattice MachXO2 FPGA provides several features used by default on the TS-7970:

  • auto TX enable for RS-485 half duplex
  • DIO expander
  • UART/DIO crossbar
  • Clock generator

It is also software reloadable and can be customized for specific purposes. The registers are accessed over I2C using the "tshwctl" utility in the ts4900-utils repository. The DIO can be accessed using the sysfs GPIOs 224 to 288 using the "tsgpio" driver. See the #GPIO section for more information on the recommended GPIO access.

Usage: tshwctl [OPTIONS] ...
Technologic Systems i.mx6 FPGA Utility
     -m, --addr <address>   Sets up the address for a peek/poke
     -v, --poke <value>     Writes the value to the specified address
     -t, --peek             Reads from the specified address
     -i, --mode <8n1>       Used with -a, sets mode like '8n1', '7e2', etc
     -x, --baud <speed>     Used with -a, sets baud rate for auto485
     -a, --autotxen <uart>  Enables autotxen for supported CPU UARTs
                              Uses baud/mode if set or reads the current
                              configuration of that uart
     -c, --dump             Prints out the crossbar configuration
     -g, --get              Print crossbar for use in eval
     -s, --set              Read environment for crossbar changes
     -q, --showall          Print all possible FPGA inputs and outputs.
     -h, --help             This message
Addr Bits Function
00 7:2 TTYMXC2_RXD Crossbar
1 Reserved
0 TTYMXC2_RXD Output Enable
01 7:2 TTYMXC4_RXD Crossbar
1 Reserved
0 TTYMXC4_RXD Output Enable
02 7:2 TTYMXC2_CTS Crossbar
1 TTYMXC2_CTS Data
0 TTYMXC2_CTS Output Enable
03 7:2 TTYMXC3_RXD Crossbar
1 Reserved
0 TTYMXC3_RXD Output Enable
04 7:2 TTYMXC1_CTS Crossbar
1 Reserved
0 TTYMXC1_CTS Output Enable
05 7:2 TTYMXC2_RTS Crossbar
1 TTYMXC2_RTS Output Data
0 TTYMXC2_RTS Output Enable
06 7:2 MB_TXD Crossbar
1 Reserved
0 MB_TXD Output Enable
07 7:2 MB_TX_EN_485 Crossbar
1 Reserved
0 MB_TX_EN_485 Output Enable
08 7:2 STC_TXD_485 Crossbar
1 Reserved
0 STC_TXD_485 Output Enable
09 7:2 STC_TX_EN_485 Crossbar
1 Reserved
0 STC_TX_EN_485 Output Enable
10 7:2 TXD_232_COM Crossbar
1 Reserved
0 TXD_232_COM Output Enable
11 7:2 RTS_232_COM Crossbar
1 Reserved
0 RTS_232_COM Output Enable
12 7:2 HD1_TXD Crossbar
1 HD1_TXD Data
0 HD1_TXD Output Enable
13 7:2 Reserved
1 BT_EN Data
0 BT_EN Output Enable
14 7:2 Reserved
1 WL_EN Data
0 WL_EN Output Enable
15 7:3 Reserved
2 BT_RTS Input Data
1:0 Reserved
16 7:2 BT_CTS Crossbar
1 BT_CTS Data
0 BT_CTS Output Enable
17 7:2 BT_RXD Crossbar
1:0 Reserved
18 7:2 TTYMXC1_RXD Crossbar
1:0 Reserved
19 7:2 HD1_DIO_1 Crossbar
1 HD1_DIO_1 Data
0 HD1_DIO_1 Output Enable
20 7:2 HD1_DIO_2 Crossbar
1 HD1_DIO_2 Data
0 HD1_DIO_2 Output Enable
21 7:2 HD1_DIO_3 Crossbar
1 HD1_DIO_3 Data
0 HD1_DIO_3 Output Enable
22 7:2 HD1_DIO_4 Crossbar
1 HD1_DIO_4 Data
0 HD1_DIO_4 Output Enable
23 7:2 HD1_DIO_5 Crossbar
1 HD1_DIO_5 Data
0 HD1_DIO_5 Output Enable
24 7:2 HD1_DIO_6 Crossbar
1 HD1_DIO_6 Data
0 HD1_DIO_6 Output Enable
25 7:2 EN_OUT_1 Crossbar
1 EN_OUT_1 Data
0 EN_OUT_1 Output Enable
26 7:2 EN_OUT_2 Crossbar
1 EN_OUT_2 Data
0 EN_OUT_2 Output Enable
27 7:2 FPGA_IRQ_1 Crossbar
1 Input Data
0 Reserved
28 7:2 STC_TXD_232 Crossbar
1:0 Reserved
29 7:2 Reserved
1 push_sw reset [1]
0 Reserved
30 7:2 Reserved
1 Reboot (on 1) [2]
0 Reserved
31 7:2 Reserved
1 Push SW Input Data
0 Reserved
32 7:0 RS485_CNT0 [23:16]
33 7:0 RS485_CNT0 [15:8]
34 7:0 RS485_CNT0 [7:0]
35 7:0 RS485_CNT1 [23:16]
36 7:0 RS485_CNT1 [15:8]
37 7:0 RS485_CNT1 [7:0]
38 7:0 RS485_CNT2 [23:16]
39 7:0 RS485_CNT2 [15:8]
40 7:0 RS485_CNT2 [7:0]
41 7:0 RS485_CNT3 [23:16]
42 7:0 RS485_CNT3 [15:8]
43 7:0 RS485_CNT3 [7:0]
44 7:2 TTYMAX0_RXD Crossbar
1 Reserved
0 TTYMAX0_RXD Output Enable
45 7:2 TTYMAX1_RXD Crossbar
1 Reserved
0 TTYMAX1_RXD Output Enable
46 7:2 TTYMAX2_RXD Crossbar
1 Reserved
0 TTYMAX2_RXD Output Enable
51 7:4 FPGA Revision
3 R39 Option Resistor (1 = not present)
2 R34 Option Resistor (1 = not present)
1 R36 Option Resistor (1 = not present)
0 R37 Option Resistor (1 = not present)
53 7:2 TTYMAX0_CTS Crossbar
1 Reserved
0 TTYMAX0_CTS Output Enable
54 7:2 TTYMAX1_CTS Crossbar
1 Reserved
0 TTYMAX1_CTS Output Enable
55 7:2 TTYMAX2_CTS Crossbar
1 Reserved
0 TTYMAX2_CTS Output Enable
56 7:6 DIO2 and DIO 1 input data
5:0 HD1_DIO input data
57 7:2 Reserved
1 LCD_D10
0 CN_99_BOOT_SEL Input Data
58 7:2 HD1_SPI_CLK Crossbar
1 HD1_SPI_CLK Data
0 HD1_SPI_CLK Output Enable
59 7:2 HD1_SPI_MOSI Crossbar
1 HD1_SPI_MOSI Data
0 HD1_SPI_MOSI Output Enable
60 7:2 HD1_SPI_MISO Crossbar
1 HD1_SPI_MISO Data
0 HD1_SPI_MISO Output Enable
61 7:2 Reserved
1 1 = Always pass through SPI rather than on OFF_BD_CS# assert only
0 Reserved
  1. If this is set to 1, then when SW1 is pressed a hardware reboot will happen
  2. This power cycles all rails rather than a software reboot

10.8.1 FPGA Crossbar

The FPGA crossbar allows almost any of the FPGA pins to be rerouted. All the FPGA addresses that have a crossbar mux register can be written with these output values.

Crossbar Value Selected Function
0 Do not change
1 BT_RTS
2 BT_TXD
3 TTYMXC4_TXD
4 TTYMXC2_TXD
5 TTYMXC2_CTS
6 TTYMXC1_RTS
7 TTYMXC2_RTS
8 MB_RXD_485
9 STC_RXD_485_3V
10 RXD_232_COM
11 CTS_232_COM
12 STC_RXD
13 HD1_RXD
14 TTYMXC3_TXD
15 TTYMXC1_TXD
16 TTYMAX0_TXD
17 TTYMAX0_TXEN
18 TTYMAX0_RTS
19 TTYMAX1_TXD
20 TTYMAX1_TXEN
21 TTYMAX1_RTS
22 TTYMAX2_TXD
23 TTYMAX2_TXEN
24 TTYMAX2_RTS
25 TTYMXC1_TXEN
26 TTYMXC3_TXEN
27 CLK_12MHZ
28 CLK_14MHZ
29 FPGA_24MHZ_CLK
30 CLK_28MHZ
31 GPIO
32 HD1_DIO_1
33 HD1_DIO_2
34 HD1_DIO_3
35 HD1_DIO_4
36 HD1_DIO_5
37 HD1_DIO_6
38 DIO_1_IN
39 DIO_2_IN
40 LCD_D10
41 PUSH_SW_CPU
42 HD1_SPI_CLK
43 HD1_SPI_MOSI
44 HD1_SPI_MISO


For example, we can remap three ttyMAX ports to the HD1 GPIO.

Pin Function
HD1_DIO_1 ttyMAX0 txd
HD1_DIO_2 ttyMAX0 rxd
HD1_DIO_3 ttyMAX1 txd
HD1_DIO_4 ttyMAX1 rxd
HD1_DIO_5 ttyMAX2 txd
HD1_DIO_6 ttyMAX2 rxd
tshwctl --dump

This will return the mapping of all of the pins as they are currently set. These are the relevant pins:

     FPGA Pad (DIR) (VAL) FPGA Output
       MB_TXD ( in) (  0) TTYMAX1_TXD
  STC_TXD_485 ( in) (  0) TTYMAX0_TXD
  RTS_232_COM ( in) (  0) TTYMAX2_TXD
    HD1_DIO_1 ( in) (  0) GPIO
    HD1_DIO_2 ( in) (  0) GPIO
    HD1_DIO_3 ( in) (  0) GPIO
    HD1_DIO_4 ( in) (  0) GPIO
    HD1_DIO_5 ( in) (  0) GPIO
    HD1_DIO_6 ( in) (  0) GPIO
  TTYMAX0_RXD ( in) (  0) STC_RXD_485_3V
  TTYMAX1_RXD ( in) (  0) MB_RXD_485
  TTYMAX2_RXD ( in) (  0) CTS_232_COM

...

The tshwctl tool uses the bash environment to set/get pin status. To remap these pins:

eval $(tshwctl --get)
export HD1_DIO_1=TTYMAX0_TXD
export HD1_DIO_3=TTYMAX1_TXD
export HD1_DIO_5=TTYMAX2_TXD
export TTYMAX0_RXD=HD1_DIO_2
export TTYMAX1_RXD=HD1_DIO_4
export TTYMAX2_RXD=HD1_DIO_6
 
# These last 3 aren't required, but this will disable ttyMAX pins on
# their default locations.  Without this, writes to /dev/ttyMAX0 
# would go to both STC_TXD_485 and to HD1_DIO_1.
export MB_TXD=GPIO
export STC_TXD_485=GPIO
export RTS_232_COM=GPIO
 
# This will read the environment and look for the PAD names 
# for any changes and apply them.
tshwctl --set

10.9 GPIO

The i.MX6 GPIO are available using the kernel's sysfs. See the kernel's documentation here for more detail. This interface provides a set of files and directories for interacting with GPIO. This allows GPIO to be accessed from any language that can write files. For example to toggle CN1_89/EIM_A22 the kernel maps this to GPIO 48. See the table below for the full IO listing.

Note: It is possible to use GPIO registers as documented in the CPU reference manual to control GPIO. If this is needed keep in mind the kernel may attempt to access the same GPIO banks for various drivers. Be aware of the other IO in the same bank or use a read/modify/write.

To interact with this pin, first export it to userspace:

echo "48" > /sys/class/gpio/export

If you receive a permission denied on a pin that means it is claimed by another kernel driver. If it succeeds you will have a /sys/class/gpio/gpio48/ directory. The relevant files in this directory are:

 direction - "out" or "in"
 value - write "1" or "0", or read "1" or "0" if direction is in
 edge - write with "rising", "falling", or "none"
# Set GPIO 48 high
echo "out" > /sys/class/gpio/gpio48/direction
echo "1" > /sys/class/gpio/gpio48/value
# Set GPIO 48 low
echo "0" > /sys/class/gpio/gpio48/value
 
# Read the value of GPIO 48
echo "in" > /sys/class/gpio/gpio48/direction
cat /sys/class/gpio/gpio48/value

As an output, the in can be written to 0 for low (GND), or 1 for high (3.3V). As an input the GPIO will have a 100k pullup. The GPIO pins off of the i.MX6 processor support an absolute maximum of -0.5 to 3.6V. It possible to use any processor GPIO as an interrupt. This is done by writing the edge value, and using select() or poll() on the value file for changes. See the #Interrupts section for more details.

The GPIO numbers in the table below are relevant to how the Linux references these numbers. The CPU documentation refers to bank and IO while Linux flattens this out to one number space.

Pins #224 and above are from the perspective of the FPGA rather than the CPU. For example, toggling the IO #224 is ttymxc2_rxd which does not toggle the cpu's uart pin, but the FPGA IO directed at that pin in the CPU. Many of these UART pins are not set as GPIO by default, and the FPGA includes its own crossbar. The UART pins will be mapped to cpu or fpga uarts.

Pad Name [1] GPIO Number Common Functions [2] Location
SD4_DAT3 43 USB HUB Reset# Onboard
DISP0_DAT23 145 SEL_DC_USB# Onboard
EIM_A16 54 EN_USB_5V Onboard
EIM_D27 91 Green LED Onboard
GPIO_2 2 Red LED Onboard
GPIO_9 9 Yellow LED Onboard
DISP0_DAT4 121 Blue LED Onboard
CSI0_DATA_EN 148 FPGA_IRQ_0 (FPGA UART irq) Onboard
GPIO_4 4 FPGA_IRQ_1 (unused) Onboard
DISP0_DAT14 136 JTAG_FPGA_TMS Onboard
DISP0_DAT17 139 JTAG_FPGA_TCK Onboard
DISP0_DAT18 140 JTAG_FPGA_TDO Onboard
DISP0_DAT22 144 JTAG_FPGA_TDI Onboard
DISP0_DAT20 142 Gyro IRQ Onboard
EIM_LBA 59 GPIO HD2 pin 3
EIM_OE 57 Modbus fault Onboard
EIM_RW 58 SD Boot Jumper Onboard
EIM_A19 51 EN_MODBUS_24V# Onboard
DISP0_DAT5 122 EN_MODBUS_3V# Onboard
EIM_D23 87 EN_RTC_PWR Onboard
DISP0_DAT0 117 EN_CAN_1# Onboard
EIM_BCLK 191 EN_CAN_2# Onboard
DISP0_DAT7 124 GPIO HD1 pin 7
DISP0_DAT9 126 GPIO HD1 pin 21
DISP0_DAT10 127 GPIO HD1 pin 9
DISP0_DAT11 133 GPIO HD1 pin 14
EIM_CS0 55 GPIO HD2 pin 5
EIM_A24 132 GPIO HD2 pin 12
EIM_WAIT 128 GPIO HD2 pin 11
EIM_EB1 61 GPIO HD2 pin 10
EIM_DA0 64 GPIO HD2 pin 2
EIM_DA1 65 GPIO HD2 pin 4
EIM_DA2 66 GPIO HD2 pin 6
EIM_DA3 67 GPIO HD2 pin 8
EIM_DA4 68 GPIO HD2 pin 7
EIM_DA5 69 GPIO HD2 pin 9
EIM_DA6 70 GPIO HD2 pin 13
EIM_DA7 71 GPIO HD2 pin 15
EIM_DA8 72 GPIO HD2 pin 16
EIM_DA9 73 GPIO HD2 pin 17
EIM_DA10 74 GPIO HD2 pin 14
EIM_DA11 75 GPIO HD2 pin 24
EIM_DA12 76 GPIO HD2 pin 21
EIM_DA13 77 GPIO HD2 pin 19
EIM_DA14 78 GPIO HD2 pin 20
EIM_DA15 79 GPIO HD2 pin 18
SD4_DAT5 45 TTYMXC1_RTS FPGA Crossbar
SD4_DAT6 46 TTYMXC1_CTS FPGA Crossbar
  1. The pad name does not often correspond with the functionality of the IO we use, but can be used to reference the pad in the CPU manual.
  2. This does not contain all of the functions possible for a pin, but the common functions as they are used on our off the shelf basebords. Consult the i.MX6 CPU Reference manual, and FPGA crossbar section for a complete list.

10.9.1 FPGA GPIO

The FPGA is used as a GPIO expander, and a crossbar. In most cases the FPGA IO are usable for low speed IO. The crossbar allows passing through some spare CPU GPIO which are interruptible.

Note: If any IO are used from the kernel, keep in mind these IO cannot be called from an interrupt context. These IO "can sleep". Instead of gpio_set_value use gpio_set_value_cansleep().

Some pins will need to be changed into GPIO before they can be used. For example, to toggle HD1 pin 12 (HD1_TXD):

tshwctl --dump
 root@ts-imx6:~# tshwctl --dump
   FPGA Pad    (DIR) (VAL) FPGA Output
   TTYMXC2_RXD ( in) (  0) HD1_RXD
   TTYMXC4_RXD ( in) (  0) STC_RXD
   TTYMXC2_CTS ( in) (  0) GPIO
   TTYMXC3_RXD ( in) (  0) RXD_232_COM
   TTYMXC1_CTS ( in) (  0) BT_RTS
   TTYMXC2_RTS ( in) (  1) GPIO
        MB_TXD ( in) (  0) TTYMAX1_TXD
  MB_TX_EN_485 ( in) (  0) TTYMAX1_TXEN
   STC_TXD_485 ( in) (  0) TTYMAX0_TXD
 STC_TX_EN_485 ( in) (  0) TTYMAX0_TXEN
   TXD_232_COM ( in) (  0) TTYMXC3_TXD
   RTS_232_COM ( in) (  0) TTYMAX2_TXD
       HD1_TXD ( in) (  0) TTYMXC2_TXD
        BT_CTS ( in) (  1) TTYMXC1_RTS
 ...

In this case HD1_TXD is the signal we want to toggle. The HD1_TXD signal is passing through TTYMXC2_TXD. It is possible to toggle ttymxc2_txd from the CPU as a GPIO, but the CPU IOMUXC would first need to be configured. On the CPU IOMUXC this is a UART, not a GPIO by default. On the FPGA as well this is configured to pass through the CPU pin, but it can be configured to be a GPIO:

export HD1_TXD=GPIO
tshwctl --set

Now running "tshwctl --dump" will show this HD1_TXD signal is now a GPIO. Refer to the below table to see the FPGA pin to toggle. In this case, 236.

echo 236 > /sys/class/gpio/export
echo high > /sys/class/gpio/gpio236/direction
echo low > /sys/class/gpio/gpio236/direction
Pad Name [1] GPIO Number Default Function Location
TTYMXC2_RXD 224 ttymxc2 rxd HD1 pin 12
TTYMXC4_RXD 225 ttymxc4 rxd P1-B pin 16
TTYMXC2_RTS 226 NC NC
TTYMXC3_RXD 227 ttymxc3 rxd COM Header pin 2
TTYMXC1_CTS 228 ttymxc1 cts Onboard (Bluetooth RTS)
TTYMXC2_CTS 229 NC NC
MB_TXD 230 ttyMAX1 txd Modbus RJ45 Data pins 4/5 +/-
MB_TX_EN_485 231 ttyMAX1 txen Onboard
STC_TXD_485 232 ttyMAX0 TXD P1-A Terminal Block pin 2, COM2 Header pin 1
STC_TX_EN_485 233 ttyMAX0 TXEN Onboard [2]
TXD_232_COM 234 ttymxc3 TXD COM2 Header pin 3
RTS_232_COM 235 ttyMAX2 TXD COM2 Header pin 7
HD1_TXD 236 ttymxc2 RXD HD1 pin 10
BT_EN 237 GPIO Onboard
WL_EN 238 GPIO Onboard
BT_RTS 239 ttymxc1 CTS Onboard
BT_CTS 240 ttymxc1 RTS Onboard
BT_RXD 241 ttymxc1 TXD Onboard
TTYMXC1_RXD 242 ttymxc1 TXD Onboard
HD1_DIO_1 243 GPIO HD1 pin 8
HD1_DIO_2 244 GPIO HD1 pin 6
HD1_DIO_3 245 GPIO HD1 pin 4
HD1_DIO_4 246 GPIO HD1 pin 2
HD1_DIO_5 247 GPIO HD1 pin 24
HD1_DIO_6 248 GPIO HD1 pin 22
EN_OUT_1 249 GPIO Onboard/Terminal Block P1-B pin 5
EN_OUT_2 250 GPIO Onboard/Terminal Block P1-B pin 6
STC_TXD_232 252 ttymxc4 TXD P1-B Terminal Block pin 7
FPGA Register 253 1 = Reboot on push_sw Register
FPGA Register 254 1 = Reboot Register
TTYMAX0_RXD 268 ttyMAX0 RXD P1-A Terminal Block pin 3, COM2 Header pin 6
TTYMAX1_RXD 269 ttyMAX1 RXD RJ45 2W-Modbus pin 5
TTYMAX2_RXD 270 ttyMAX2 RXD COM2 Header pin 8
HD1_SPI_CLK 282 #SPI, GPIO HD1 pin 17
HD1_SPI_MOSI 283 #SPI, GPIO HD1 pin 20
HD1_SPI_MISO 284 #SPI, GPIO HD1 pin 18
  1. The pad name rarely corresponds with the functionality of the IO we use. This name can be used to reference the pad in the CPU manual.
  2. This pin is set up to automatically toggle with TX data in the FPGA. You do not need to manually toggle this to transmit/recieve.

10.10 Interrupts

The i.MX6 CPU GPIO are also able to function as interrupts on rising and falling edges. This is accessible from the kernel as well as userspace. Userspace IRQs are exposed through the sysfs gpio mechanism. This example will trigger on a falling edge for GPIO 48:

echo "48" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio48/direction
echo "falling" > /sys/class/gpio/gpio48/edge

From here, you would need to use a lower level language to poll() or select() on /sys/class/gpio/gpio48/value.

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
 
int main(int argc, char **argv)
{
	char gpio_irq[64];
	int ret, irqfd = 0, i = 0;
	fd_set fds;
	FD_ZERO(&fds);
	int buf;
 
	if(argc < 2) {
		printf("Usage: %s <gpio number>\n", argv[0]);
		return 1;
	}
 
	snprintf(gpio_irq, sizeof(gpio_irq), "/sys/class/gpio/gpio%d/value", atoi(argv[1]));
	irqfd = open(gpio_irq, O_RDONLY, S_IREAD);
 
	if(irqfd == -1) {
		printf("Could not open IRQ %s\n", argv[1]);
		printf("Make sure the GPIO is already exported", argv[1]);
		return 1;
	}
 
	// Read first since there is always an initial status
	ret = read(irqfd, &buf, sizeof(buf));
 
	while(1) {
		FD_SET(irqfd, &fds);
		// See if the IRQ has any data available to read
		ret = select(irqfd + 1, NULL, NULL, &fds, NULL);
 
		if(FD_ISSET(irqfd, &fds))
		{
			FD_CLR(irqfd, &fds);  //Remove the filedes from set
			printf("IRQ detected %d\n", i);
			fflush(stdout);
			i++;
 
			/* The return value includes the actual GPIO register value */
			read(irqfd, &buf, sizeof(buf));
			lseek(irqfd, 0, SEEK_SET);
		}
 
		//Sleep, or do any other processing here
		usleep(100000);
	}
 
	return 0;
}

This example can be run as "./irqtest 48" which will echo every time the pin changes, but will otherwise take no cpu time.

10.11 LEDs

The kernel provides access to control the LEDs using the sysfs:

# Set Red led on
echo 1 > /sys/class/leds/red-led/brightness
# Set Red led off
echo 0 > /sys/class/leds/red-led/brightness
 
# Set Green led on
echo 1 > /sys/class/leds/green-led/brightness
# Set Green led off
echo 0 > /sys/class/leds/green-led/brightness

The kernel provides various triggers that can be useful for debugging purposes. The trigger for a given LED is in its directory:

echo "heartbeat" > /sys/class/leds/red-led/trigger
Trigger value LED toggles on
none Default, no action
mmc0 MicroSD card activity
mmc1 eMMC activity
mmc2 WIFI SDIO activity
timer 2hz blink
oneshot Blinks after delay. [1]
heartbeat Similar to timer, but varies the period based on system load
backlight Toggles on FB_BLANK
gpio Toggle based on a specified gpio. [2]
cpu0 Blink on CPU core 0 activity
cpu1 Blink on CPU core 1 activity
cpu2 Blink on CPU core 2 activity
cpu3 Blink on CPU core 3 activity
default-on Only turns on by default. Only useful for device tree.
transient Specify on/off with time to turn off. [3]
flash/torch Toggle on Camera activation. Not currently used.
  1. See the Kernel documentation for more details
  2. When this trigger is set, a "gpio" file appears in the same directory which can be used to specify what GPIO to follow when it blinks
  3. See the Kernel documentation for more details

10.12 MicroSD Card Interface

The i.MX6 SDHCI driver supports MicroSD (0-2GB), MicroSDHC (4-32GB), and MicroSDXC(64GB-2TB). The cards available on our website on average support up to 16MB/s read, and 22MB/s write using this interface. The linux driver provides access to this socket at /dev/mmcblk1 as a standard Linux block device.

This graph shows our SD write endurance test for 40x TS-7553 boards. These boards are running a doublestore stress test on 4GB Sandisk MicroSD cards. A failure is marked on the graph for a card once a single bit of corruption is found.

See chapter 67 of the IMX6 reference manual for more information on this mmc controller.

We have performed compatibility testing on the Sandisk MicroSD cards we provide. We do not suggest switching brands/models without your own qualification testing. While SD cards specifications are standardized, in practice cards behave very differently. We do not recommend ATP or Transcend MicroSD cards due to known compatibility issues.

Our testing has shown that on average microSD cards will last between 6-12TB. After this cards can begin to experience corruption, or stop being recognized by the host pc. This may be enough storage for many applications to write for years without problems. For more reliable storage consider using the eMMC. Our endurance testing showed a write lifetime on average of about 123TiB.

MicroSD cards should not have power removed during a write or they will have disk corruption. Keep the filesystem mounted read only if this is a possibility. It is not always possible for fsck to recover from the types of failures that will be seen with SD power loss. Consider using the eMMC for storage instead which is far more resilient to power loss.

10.13 NVRAM

The RTC includes 128 bytes of NVRAM which can be used for custom applications. There is a utility, nvramctl which can be used to read/write the NVRAM.

ts4900-utils github.

The utility reads/writes a byte at a time, and returns the value in hex.

nvramctl --addr 10 --set 0x40
nvramctl --addr 10 --get
# Returns "nvram10=0x40".
# This can also be used with eval
eval $(nvramctl --addr 10 --get)
echo $nvram10
# Returns "0x40"

The NVRAM code can be included in your application by using these two files:

10.14 Onboard SPI Flash

This board includes 8MiB of SPI flash using a Micron N25Q064A13ESE40F. The CPU uses this for the initial boot to load u-boot, as well as the u-boot environment. In Linux this is accessed with the /dev/mtdblock devices.

Bytes Size Description
0-0x3ff 1KB Unused
0x400-0xfffff 0.999MiB U-boot
0x100000-0x101fff 8KiB U-boot environment #1
0x102000-0x17ffff 504KiB Unused
0x180000-0x181fff 8KiB U-boot environment #2
0x182000-0x1fffff 504KiB Unused
0x200000-0x700000 5MiB Unused

10.15 RTC

We include the Intersil ISL12020 RTC onboard. This provides a long RTC battery life, as well as a built in temperature sensor to provide +- 5ppm across -40 to 85C. This is /dev/rtc0 in our images, and is accessed using the standard hwclock command.

10.16 USB

10.16.1 USB OTG

This SBC includes support to act as a USB peripheral to another system. Remove the "CON EN" jumper to disable the onboard usb serial, and connect the P1 header to the CPU's OTG port. This port is strapped to only act as a USB device. Several devices are compiled into the default kernel. Other devices can be compiled into the kernel by following the section here.

USB Serial

modprobe g_serial use_acm=1

This will create a /dev/ttyGS0. See the kernel documentation for more information:

USB Ethernet

modprobe g_ether

This provides a usb0 network interface. This driver simulates an Ethernet network connection between the host pc and the i.MX6.

10.16.2 USB Host

The i.MX6 provides 1 USB Host with supporting USB 2.0 (480Mbit/s). The TS-7970 includes a USB Hub expanding this to 4 USB host ports.

Typically USB is interfaced with by using standard Linux drivers, but low level USB communication is possible using libusb.

The TS-7970 USB 5V rail can be toggled on/off through a GPIO. This can be used to save power, or to reset USB devices that get stuck in a bad state.

# Power disabled
echo 1 > /sys/class/leds/en-usb-5v/brightness
sleep 2 # let any devices reset
# Enable power
echo 0 > /sys/class/leds/en-usb-5v/brightness
Note: The USB OTG which can act as a host does not always use the same controllable 5V supply. Refer to the schematic's EN_USB_5V/USB_5V for more information on this control.

The TS-7970 also has a USB port on the HD1 header (11 data-, 13 data+). This is used for some off the shelf daughter cards like the DC767-MT which supports Multitech cellular modems. To use this USB port you must toggle a GPIO which switches a USB mux onboard. This switches one of the USB hosts from the top port next to the Ethernet connector to HD1.

# Set USB4 to HD1
echo 1 > /sys/class/leds/sel_dc_usb/brightness
 
# Set USB4 to J1 (default)
echo 0 > /sys/class/leds/sel_dc_usb/brightness

10.17 SATA

The i.MX6 Quad and Dual include integrated SATA II support. This interface has been tested to provide 135MiB/s write, and 170MiB/s read through block access. In linux this is accessed through the /dev/sda device:

[    1.768036] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
[    1.785377] ata1.00: ATA-8: MKNSSDAT30GB-DX, 507ABBF0, max UDMA/133
[    1.791716] ata1.00: 58626288 sectors, multi 16: LBA48 NCQ (depth 31/32)
[    1.805380] ata1.00: configured for UDMA/133
[    1.810320] scsi 0:0:0:0: Direct-Access     ATA      MKNSSDAT30GB-DX  507A PQ: 0 ANSI: 5
[    1.819459] sd 0:0:0:0: [sda] 58626288 512-byte logical blocks: (30.0 GB/27.9 GiB)
[    1.827427] sd 0:0:0:0: [sda] Write Protect is off
[    1.832812] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[    1.843621]  sda: sda1
[    1.847381] sd 0:0:0:0: [sda] Attached SCSI dis

10.18 Silabs Microcontroller

The onboard silabs microcontroller includes 3 primary functions:

  • ADC channels
  • Sleep Mode
  • USB Console

The USB console passes through the CPU's ttymxc0 port using a CP201x driver. This is present on most Linux distributions. On Windows this is available with a WHQL signed driver from Silabs.

The Silabs exists at 0x10 on the i2c bus 0 using 8-bit address and data. It can be read for up to 32 bytes to get the ADC values, and Silabs revision. Our example code "tsmicroctl -i" includes reading all the ADCs in millivolts. This also includes a variable for the revision. For example:

 # tsmicroctl -i
 VDD_ARM_CAP=1026
 VDD_HIGH_CAP=2603
 VDD_SOC_CAP=1239
 VDD_ARM=1451
 SILAB_P10=0x0
 SILAB_P11=0x0
 SILAB_P12=0x0
 VIN=4779
 V5_A=5189
 V3P1=3230
 DDR_1P5V=1559
 V1P8=1904
 V1P2=1259
 RAM_VREF=778
 V3P3=3522
 SILABREV=1

In u-boot you can use the "tsmicroctl" command with no arguments to read the same values.

The sleep mode is accessible in u-boot with "tsmicroctl <seconds>", and in Linux with "tsmicroctl -s <seconds>". This will power off everything on the board except the silabs microcontroller. The blue LED will blink while it is in this mode.

The silabs sample all ADC channels in a scale of 0-2.5V. The schematic shows the voltage dividers to bring the higher voltages it samples into this range.

Silabs Read Registers
Register Description
0 VDD_ARM_CAP MSB
1 VDD_ARM_CAP LSB
2 VDD_HIGH_CAP MSB
3 VDD_HIGH_CAP LSB
4 VDD_SOC_CAP MSB
5 VDD_SOC_CAP LSB
6 VDD_ARM MSB
7 VDD_ARM LSB
8 SILAB_P10 MSB
9 SILAB_P10 LSB
10 SILAB_P11 MSB
11 SILAB_P11 LSB
12 SILAB_P12 MSB
13 SILAB_P12 LSB
14 VIN MSB
15 VIN LSB
16 V5_A MSB
17 V5_A LSB
18 V3P1 MSB
19 V3P1 LSB
20 DDR_1P5V MSB
21 DDR_1P5V LSB
22 V1P8 MSB
23 V1P8 LSB
24 V1P2 MSB
25 V1P2 LSB
26 RAM_VREF MSB
27 RAM_VREF LSB
28 V3P3 MSB
29 V3P3 LSB
30 Silabs Revision

10.18.1 Silabs Sleep Mode

The TS-7970 implements a very low power sleep mode using the onboard supervisory microcontroller. This allows powering off the i.MX6 CPU entirely. While in this mode the entire board will use about 26mW.

The board can be woken 3 ways:

  • Timer - sleep mode requires specifying an amount of seconds to sleep (up to 16777215).
  • SW1 - Pressing the button on the side of the board.
  • PUSH_SW# goes low on HD1. The SW1 signal is brought to the header so connected cards can wake the TS-7970.

The sleep mode can be entered at a low level calling "tshwctl --sleep 60" to sleep for 60 seconds, but this typically should not be called directly. This would be equivalent to disconnecting power while booted which can cause data loss.

The Yocto, Debian, or Ubuntu distributions use systemd to manage shutdown. When systemd shuts down it will call all executables in /lib/systemd/system-shutdown/. Create a script silabs-sleep in this directory with these contents:

#!/bin/bash
 
tsmicroctl --sleep 60

And make it executable:

chmod a+x /lib/systemd/system-shutdown/silabs-sleep

Now the board will sleep immediately following a shutdown. It is safe during the sleep mode to disconnect power.

10.19 SPI

The CPU has 1 SPI controller which is accessible offboard through either specific kernel drivers, or userspace using the /dev/spidev interface. On the TS-7970 these are exposed as /dev/spidev1.1 (FPGA) and /dev/spidev1.2 (HD1) in userspace.

The /dev/spidevX.Y are created where X is the controller and Y is the chip select used. See the compiling the kernel section to get a build environment up. Any GPIO can be used as another SPI chip select by modifying the device tree. For example arch/arm/boot/dts/imx6qdl-ts7970.dtsi:

&ecspi2 {
	fsl,spi-num-chipselects = <3>;
	cs-gpios = <&gpio5 31 0>, <&gpio7 12 0>, <&gpio5 18 0>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_ecspi2>;
	status = "okay";
 
	serial1: max3100-1@0 {
		compatible = "max3100-ts";
		reg = <0>;
		interrupt-parent = <&gpio1>;
		interrupts = <4 2>;
		spi-max-frequency = <1000000>;
		loopback = <0>;
		crystal = <1>;
		poll-time = <100>;
		fifo-size = <16>;
	};
 
	spidevfpga: spi@1 {
		compatible = "spidev";
		reg = <1>;
		spi-max-frequency = <1000000>;
	};
 
	spidevhd1: spi@2 {
		compatible = "spidev";
		reg = <2>;
		spi-max-frequency = <1000000>;
	};
};

This bus is shared with the onboard fpga uarts (/dev/ttyMAX*). The spidevfpga node is intended for customized FPGA communication. The HD1 node is for general use.

10.20 TWI

The i.MX6 supports standard I2C at 100khz, or using fast mode for 400khz operation. The CPU has 2 I2C buses used on the TS-7970

/dev/i2c-0 is internal to the board and connects to the RTC and FPGA.

Address Device
0x10 #Silabs Microcontroller
0x28-0x2f #FPGA
0x57 #NVRAM
0x6b Onboard PCIe Clock Generator
0x6f #RTC

The second I2C bus (/dev/i2c-1) is brought out on HD3 pin 15 (SCL) and HD3 pin 16 (SDA). This bus has no onboard devices.

Note: It is also possible to request the kernel to bitbang additional I2C buses as needed. See an example here.

The kernel makes the I2C available at /dev/i2c-#. You can use the i2c-tools (i2cdetect, i2cgetm, i2cset), or you can write your own client.

10.21 Watchdog

The kernel provides an interface to the watchdog driver at /dev/watchdog. Refer to the kernel documentation for more information:

10.22 WIFI

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

Summary Features:

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

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

11 External Interfaces

11.1 Audio

The TS-7970 includes two 3.5mm jacks. The top port is a mono microphone input, and the bottom port is a headphone port with left and right channels. Use "alsamixer" or "amixer" to adjust the volume.

In Linux select between the HDMI and 3.5mm ports with an alsa variable. By default all audio comes out of the sgtl5000 for the 3.5mm ports.

# list the sound cards
aplay -l
 
export ALSA_CARD=imxhdmisoc
espeak "this is playing from the HDMI monitor"
 
export ALSA_CARD=imx6qts7970sgtl
espeak "this is playing from the onboard sgtl5000"

11.2 COM2 Header

The COM2 header is a 2x5 0.1" pitch header with RS485, CAN, and RS232.

TS-7970 COM Header.png
Pin # Description
1 STC_485+ (/dev/ttyMAX0)
2 RS232 RXD (/dev/ttymxc3)
3 RS232 TXD (/dev/ttymxc3)
4 CAN_1_H (can0 interface)
5 GND
6 STC_485- (/dev/ttyMAX0)
7 RS232 TXD (/dev/ttyMAX2)
8 RS232 RXD (/dev/ttyMAX2)
9 CAN_1_L (can0 interface)
10 NC

11.3 Ethernet

The TS-7970 includes two 10/100/1000 Ethernet ports. The port with the larger connector uses the FEC MAC from the CPU with a Marvell PHY. The other smaller optional port is a PCIe Intel I210 chipset.

Under Linux the CPU ethernet is typically eth0, and depending on the distribution the second ethernet is either eth1 or enp0s1.

The CPU and I210 both receive unique sequential mac addresses. These are pulled from the Technologic Systems OUI "00:D0:69". Both chipsets support downshifting if some of the twisted pairs are missing connection.

On both Ethernet ports the right LED indicates speed. It is on for gigabit, and off for 10/100. The left LED will blink on activity.

See the #Debian_Networking for configuring the network on the default distribution.

11.4 HDMI

The TS-7970 includes an HDMI 1.4 port which supports EDID for automatically configuring the video modes on your monitor, and HDMI audio. In Linux this will be /dev/fb0. The HDMI is capable of outputting up to 4XGA (2048x1536).

Under either distribution the mode will default to the largest and highest refresh rate compatible with both the monitor and the i.MX6. You can override this in yocto with xrandr, or under debian/ubuntu/yocto with a kernel cmdline change. Hold SW1 when power is applied and the board will stop at u-boot. Run these commands to override the EDID settings and use 1024x768M@60.

env set cmdline_append "console=ttymxc0,115200 rootwait ro init=/sbin/init video=mxcfb0:dev=hdmi,1024x768M@60,if=RGB24" 
env save

HDMI to VGA/DVI-A adapters are possible to use with the TS-7970, but the port protection chip strictly follows the HDMI standard. Some adapters are known to violate the standard and try to pull too much power off of the HDMI port. For an adapter to work it should accept a separate power input such as a microUSB port. The TS-7970 can still power the adapter through USB, but the HDMI header should not be used for sourcing current.


TS-7970 HDMI.png

11.5 HD1

HD1 is a 2x12 0.10" pitch header including DIO, USB, SPI, an IRQ, 3.3V, and 5V. All GPIO are 3.3V tolerant unless otherwise specified.

TS-7970 HD1 Header.png
Pin # GPIO Number Description
1 N/A NC
2 246 HD1_DIO_4
3 N/A GND
4 245 HD1_DIO_3
5 N/A GND
6 244 HD1_DIO_2
7 124 DISP0_DAT7
8 243 HD1_DIO_1
9 127 DISP0_DAT10
10 236 ttymxc2 RXD
11 N/A USB host data-
12 224 ttymxc2 TXD
13 N/A USB host data+
14 133 DISP0_DAT11
15 N/A 5V
16 N/A 5V
17 282 SPI_2_CLK
18 284 SPI_2_MISO
19 146 HD1_SPI_CS#
20 283 SPI_2_MOSI
21 126 HD1_IRQ
22 248 HD1_DIO_6
23 N/A 3.3V
24 247 HD1_DIO_5


11.6 HD2

HD2 is a 0.10" pitch header.

TS-7970 HD2 Header.png
Pin # Description
1 GND
2 EIM_DA0 (GPIO #64)
3 EIM_LBA (GPIO #59)
4 EIM_DA1 (GPIO #65)
5 EIM_CS0 (GPIO #55)
6 EIM_DA2 (GPIO #66)
7 EIM_DA4 (GPIO #68)
8 EIM_DA3 (GPIO #67)
9 EIM_DA5 (GPIO #69)
10 EIM_EB1 (GPIO #61)
11 EIM_WAIT (GPIO #128)
12 EIM_A24 (GPIO #132)
13 EIM_DA6 (GPIO #70)
14 EIM_DA10 (GPIO #74)
15 EIM_DA7 (GPIO #71)
16 EIM_DA8 (GPIO #72)
17 EIM_DA9 (GPIO #73)
18 EIM_DA15 (GPIO #79)
19 EIM_DA13 (GPIO #77)
20 EIM_DA14 (GPIO #78)
21 EIM_DA12 (GPIO #76)
22 EIM_RW (GPIO #58)
23 3.3V supply
24 EIM_DA11 (GPIO #75)


11.7 HD3

HD3 is a 2x8 0.10" pitch header including LVDS, I2C, 3.3V and 5V which can be used to connect up a third party display.

TS-7970 HD3 Header.png
Pin # Description
1 LVDS0_TX1_N
2 LVDS0_TX1_P
3 3.3V supply
4 LVDS0_TX0_N
5 LVDS0_TX0_P
6 5V Supply
7 LVDS0_CLK_N
8 LVDS0_CLK_P
9 GND
10 LVDS0_TX2_N
11 LVDS0_TX2_P
12 GND
13 LVDS0_TX3_N
14 LVDS0_TX3_P
15 I2C 1 CLK
16 I2C 1 DAT


11.8 Mini Card Connector

The TS-7970 includes a mini card header which includes USB and power like a mini pcie header. It does not include a PCIe bus. Many peripherals do not actually need the PCIe bus and instead use the USB host which is present on this header.

This port also supports mSATA which can be used for higher capacity drives.

Note: SATA is not available on the i.MX6 solo or duallite processors.

11.8.1 SIM Socket

The TS-7970 accepts Micro SIM cards for use with a compatible mini card modem.

TS-7970 SIM.jpg

11.8.2 Cell Modem Example

This example uses Debian, a T-Mobile SIM card and the Huawei MU609 HSPA modem which uses the USB interface on the mini pcie, and the SIM socket on the TS-7970.

The Mu609 needs a more recent ModemManager than Debian Jessie provides, so we need to rebuild this with the latest.

apt-get build-dep modemmanager -y
apt-get remove modemmanager # in case you had a previous version installed
 
cd /usr/src/
wget http://www.freedesktop.org/software/ModemManager/ModemManager-1.4.10.tar.xz
tar -xf ModemManager-1.4.10.tar.xz
cd ModemManager-1.4.10/
./configure --without-qmi --with-polkit=none
make -j4
make install

Once updated you can use this script to start the modem connection:

#!/bin/bash
 
ModemManager &
 
until mmcli -L | grep "Found [0-9] modems"; do
	sleep 1
done
mmcli -m 0 -e
 
# Change to match your provider's APN
mmcli -m 0 --simple-connect="apn=ecp.tmobile.com"
 
# Depending on the build of your board this may be a different
# interface, but when the modem is enabled it will add a new eth* 
# interface.  In this case, it is eth1.
dhclient eth1

Other useful commands:

# Check signal quality & provider info
# you will not be able to get a dhcp address until state is 'registered'.
mmcli --simple-status -m 0
 
# Turn on GPS:
mmcli -m 0 --location-enable-gps-raw --location-enable-gps-nmea
# After you acquire a lock (usually a few minutes)
mmcli -m 0 --location-get

11.9 Push Button

The push switch is accessed by reading FPGA registers:

tshwctl --addr 31 --peek

With no press bit 2 will be set so it will return "addr31=0x4". If there is a press it will be cleared, so "addr31=0x0".

This pin is sampled in u-boot to detect if it should stop in u-boot and look for usb updates. If this interferes with your intended usage you can boot to u-boot and disable this by running:

env delete preboot;
env set bootdelay 1;
env save;

After this change u-boot will wait 1 second on every boot for the user to press ctrl+c to break into u-boot on startup.

11.10 RJ45 2W-Modbus

The 2W MODBUS ports both follow a standard pinout:

ModbusRJ45.png

The RS485 port on pins 4 and 5 is accessed with /dev/ttyMAX1.

# en_24v 51
# en_3v 122
echo 51 > /sys/class/gpio/export
echo 122 > /sys/class/gpio/export
 
# Switch VIN to pins 6 and 7:
echo high > /sys/class/gpio/gpio51/direction
 
# Switch 3V to pins 6 and 7:
echo low > /sys/class/gpio/gpio122/direction

11.11 Terminal Blocks

The TS-7970 includes two removable terminal blocks (OSTTJ0811030) for power, UARTs, CAN, and other general purpose IO.

TS-7970 terminal block connectors.png


TS-7970 Terminal Blocks.png
P1-A
Pin # Description
1 Ground
2 STC_485+ (/dev/ttyMAX0)
3 STC_485- (/dev/ttyMAX0)
4 STC_CAN_2_H (can1 interface)
5 STC_CAN_2_L (can1 interface)
6 Power Input (8-28VDC)
7 Power Input (5VDC)
8 Ground [1]
P1-B
Pin # Description
1 Ground
2 AD_P10 (4-20mA analog input)
3 AD_P11 (4-20mA analog input)
4 AD_P12 (4-20mA analog input)
5 DIO_1 (30VDC IO)
6 DIO_2 (30VDC IO)
7 RS-232_STC_TXD (/dev/ttymxc4)
8 RS-232_STC_RXD (/dev/ttymxc4)
  1. This ground should be used for the power supply since it includes a ferrite bead to help suppress noise.

The DIO_1 and DIO_2 IO can be outputs, or inputs. As inputs the digital threshold is 1.2V. To guarantee low it must be < 0.5V, or for high > 2.0V. When the IO is low the external device needs to sink up to 3.5mA. When the IO is high the external device needs to source 10 uA max. There is an internal 1.5k pullup to 5V that will bias the input high. As outputs these IO can sink up to 500mA.

11.12 USB Device

The USB type B device port is connected to the onboard Silabs for USB to serial console, or to the CPU's #USB OTG. The USB functionality is picked from the "CON EN" jumper.

TS-7970 USB B.jpg
Note: Previous to REV C TS-7970, the USB device port can prevent the CPU from booting up if "CON_EN" is removed, and USB is plugged in before CPU power is connected. As a workaround on earlier revs you can cut the red wire from your USB cable.

11.13 USB Hosts

The TS-7970 includes 4x USB 2.0 ports. The top port on the USB Type A connector near the Ethernet connectors is brought through a MUX chip. This USB port can be toggled to switch to the Mini-PCIE connector for use with a cell modem or other peripheral.

12 Specifications

12.1 Power Specifications

The TS-7970 includes 2 methods for powering the board. There is a 5V input, and a 8-28V input. Only one of these should be provided to the board.

Input Min voltage Max voltage
5V input 4.75 5.25
8-28V Input 8.00 28.00

12.2 Power Consumption

The i.MX6 power consumption can vary a lot depending on the build and activity of the board. Most of the power savings happens automatically when the CPU and GPU are idle. It is also possible to disable the Ethernet PHY for extra savings.

# Put ETH PHY in reset
echo 116 > /sys/class/gpio/export
echo high > /sys/class/gpio/gpio116/direction
 
# Put USB HUB in reset
echo 43 > /sys/class/gpio/export
echo low > /sys/class/gpio/gpio43/direction
 
# Lower backlight to 50%
echo 4 > /sys/class/backlight/backlight_local_lcd/brightness
 
# Disable backlight
echo 0 > /sys/class/backlight/backlight_local_lcd/brightness

Ethernet is not connected unless otherwise specified. Serial is disconnected during the measurement. The CPU test is 5x processes of "openssl speed". The GPU test is Qt5CinematicExperience in the Yocto image.

These tests are performed powering the board through 5V.

TS-7970 solo without WIFI or I210
Test Max (W) Average (W)
CPU 100% + GPU loaded (LCD 100%) + IO + Ethernet + HDMI 4.50 (0.90 A) 3.40 (0.68 A)
CPU 100% 2.80 (0.56 A) 2.35 (0.47 A)
CPU Idle + HDMI 2.75 (0.55 A) 2.05 (0.41 A)
CPU Idle + CPU Ethernet 2.75 (0.55 A) 2.20 (0.44 A)
CPU Idle 2.50 (0.50 A) 1.95 (0.39 A)
CPU Idle USB HUB off 2.75 (0.55 A) 1.95 (0.39 A)
CPU Idle USB HUB off, Ethernet PHY in reset 2.15 (0.43 A) 1.60 (0.32 A)
Using onboard uC to sleep CPU 0.025 (125 mA) 0.015 (3 mA)
TS-7970 quad core with WIFI and I210
Test Max (W) Average (W)
CPU 100% + GPU loaded (LCD 100%) + IO + Ethernet + HDMI 10.80 (2.16 A) 7.75 (1.55 A)
CPU 100% 6.15 (1.23 A) 5.40 (1.08 A)
CPU Idle + HDMI 4.55 (0.91 A) 2.90 (0.58 A)
CPU Idle + WIFI on wpa2 running iperf 6.85 (1.37 A) 3.95 (0.79 a)
CPU Idle + CPU Ethernet 5.00 (1.00 A) 3.10 (0.62 A)
CPU Idle + PCIe Ethernet 3.60 (0.72 A) 2.85 (0.57 A)
CPU Idle 4.85 (0.97 A) 2.80 (0.56 A)
CPU Idle USB HUB off 3.50 (0.70 A) 2.75 (0.55 A)
CPU Idle USB HUB off, Ethernet PHY in reset 3.30 (0.66 A) 2.40 (0.48 A)
Using onboard uC to sleep CPU 0.025 (125 mA) 0.015 (3 mA)

12.3 Temperature Specifications

There are a few different models which will have different operating temperatures:

Model Number Operating Min Cooling Temp Passive Temp Critical Temp
TS-7970-*S8S* -40C 75C 85C 105C
TS-7970-*Q10S* -20C 75C 85C 100C

These are also exposed in /sys/:

# Passive
cat /sys/devices/virtual/thermal/thermal_zone0/trip_point_0_temp
# Critical
cat /sys/devices/virtual/thermal/thermal_zone0/trip_point_1_temp

You can view the CPU die temp with:

cat /sys/devices/virtual/thermal/thermal_zone0/temp

When the CPU heats up past the cooling temp on a first boot, it will take no action. Heating up past the passive temperature the kernel will cool down the CPU by reducing clocks. This will show a kernel message:

[  158.454693] System is too hot. GPU3D will work at 1/64 clock.

If it cools back down below the cooling temperature it will spin back up the clocks.

[  394.082161] Hot alarm is canceled. GPU3D clock will return to 64/64

If it continues heating to the critical temperature it will overheat and reboot. Booting back up u-boot will block the boot until the temperature has been reduced to the Cooling Temp+5C. This will be shown on boot with:

U-Boot 2015.04-07857-g486fa69 (Jun 03 2016 - 12:04:30)

CPU:   Freescale i.MX6SOLO rev1.1 at 792 MHz
CPU Temperature is 105 C, too hot to boot, waiting...
CPU Temperature is 102 C, too hot to boot, waiting...
CPU Temperature is 99 C, too hot to boot, waiting...
CPU Temperature is 90 C, too hot to boot, waiting...
CPU Temperature is 86 C, too hot to boot, waiting...
CPU Temperature is 84 C, too hot to boot, waiting...
CPU Temperature is 80 C, too hot to boot, waiting...
CPU Temperature is 80 C, too hot to boot, waiting...
CPU Temperature is 80 C, too hot to boot, waiting...
CPU:   Temperature 78 C
Reset cause: WDOG
Board: TS-7970

These temperature tests show the TS-7970 with/without both the heatsink and enclosure. The HS-15x15x5 test data is provided as an example of a smaller heatsink, but this heatsink is not recommended for the TS-7970.

Temp Testing without enclosure

Temp Testing with enclosure

Our testing has also shown an estimate how how high a board will be over ambient in open air.

Configuration Temp range over ambient
Solo No Heatsink 21-27C
Solo with Heatsink 18C
Quad No Heatsink 16-50C
Quad with Heatsink 10-23C

12.4 IO Specifications

The GPIO external to the board are all nominally 3.3V, but will vary depending on if they are CPU/FPGA pins.

The CPU pins can be adjusted in software and will have initial values in the device tree. This lets you adjust the drive strength, and pull strength of the IO. See the device tree for your kernel for further details on a specific IO.

The FPGA IO cannot be adjusted further in software.

IO Typical Range Absolute Range Logic Low Logic high Drive strength
External CPU GPIO 0-3.3V -0.5V to 3.3V Rail + 0.3V 0.3 * 3.3V Rail 0.7 * 3.3V Rail 27.5mA
External FPGA GPIO 0.3.3V -0.5-3.75V 0.8 2.0 12mA


Refer to the MachXO Family Datasheet for more detail on the FPGA IO. Refer to the CPU quad or solo datasheet for further details on the CPU IO.

WARNING: Do not drive any IO from an external supply until 3.3V is up on the board. Doing so can violate the power sequencing of the board causing failures.

12.5 Rail Specifications

The TS-7970 generates all rails from either the 8-28VDC input, or the 5V input. This table does not document every rail. This will only cover those that can provide power to an external header for use in an application.

Direct 5V input will bypass our regulator, but the absolute max a supply can provide 5A to the board.

Rail Current Available Location
3.3V 200mA [1] HD1 pin 23, HD2 pin 23, mPCIe, HD3 pin 3
5V Quad core 2A, Solo 3A [2] HD1 pins 15/16, HD3 pin 6, USB, mPCIe
  1. Contact us if you need more on this rail
  2. These limitations are only relevant if 8-28V is supplied into the board.

13 Revisions and Changes

13.1 TS-7970 PCB Revisions

Revision Changes
A
  • Initial Release
B
  • Changed U17 to support the MPU-9250 9 axis accelerometer
  • Changes TVS1 to use 4.7V_A
  • Fix I210 ethernet LED polarity
  • Use 153-ball eMMC to support bigger eMMCs on custom builds
  • Added PU from 5V_A to SW_5V. This prevents a negative leakage on the the SW_5V rail. If the rail has a negative voltage it will otherwise not switch on.
  • CPU pin U4 tied to ground. Used to detect REV B boards.
C
  • Not released
D
  • Changed PHY to Marvell 88E1512 due to published Microchip errata #9-10 which affects link reliability with some link partners.
Note: This change should be transparent in Linux from older kernels, but if link problems are seen from older images make sure the Marvell PHY driver is actually disabled as it does not configure this PHY correctly. The genphy driver will communicate correctly with this PHY. Earlier shipping images had this enabled, but current images keep this driver disabled
  • Changed to a larger Ethernet Magjack with separate centertaps as required by the PHY manufacturer.
  • CPU pin C13 tied to ground. Used to detect REV D boards.
  • Added two lane MIPI connector (CN1)
  • Changed to smaller battery holder
  • Pull USB_5V_DETECT on silabs low when CON_EN jumper is off. This fixes the bug on previous revisions which would cause the board to fail to boot when CON_EN is off and USB is connected on the P2 port before the TS-7970 is powered on.
  • Added PUSH_SW# to HD1 which allows a pin to wake the board out of sleep.
  • Changed pin 28 to Enable 2.5V REF to reduce power in silabs sleep mode
  • Improvements for our internal production
E
  • Minor changes for internal production.
  • H6 biased low to detect new rev

13.2 U-Boot Changelog

Jun-17-2015
  • Added TS-7970 support
Jul-27-2015
  • Added fix for PCIe hang in Linux. Some of the GPR1 regs were not being reset after a reboot. U-boot will now reset these before going into Linux. This hang was not present on all CPUs, usually solo, and only if PCIe is enabled in the kernel.
Oct-07-2015
  • TS-7970 now has a POR on every reboot
  • TS-7970 can reload the FPGA from a /boot/ts7970.vme file
  • PUSH_SW is now read through i2c to free up FPGA_IRQ_1
May-09-2016
  • Updated to imx_v2015.04_3.14.52_1.1.0_ga branch
  • Updated DDR config to latest NXP recommendations
  • Includes new thermal driver. If the CPU has overheated and rebooted it will wait in u-boot until the system cools down to the temperature specified in the thermal fuses. These are adjustable one time in software.
  • Disabled NFS umountall
May-27-2016
  • Added tsmicroctl command to read adc values, or start the sleep mode for the board. Requires a silabs from May 27th 2016 or later to include the sleep mode.
  • Added FPGA_RESET# through a signal rather than a FPGA POR. Requires FPGA REV 5 for FPGA reset to work correctly.
WARNING: Do not update past this u-boot without having REV 5 of the FPGA or the FPGA will not be reset on startup.
Jun-03-2016
  • Added suggested fixes for Micrel PHY errata.
  • Added FPGA and Silabs revision to startup output.
Jan-11-2017
  • Added REV D support
  • Added Marvell PHY support
  • Allow solo to boot at 85C instead of 80C, quad is still 80C.
Feb-17-2017
  • Added check for 64bit ext4 filesystem.
Mar-27-2017
  • Changed string to indicate REV D/E for new boards.
  • Added I2C recovery improvements for fixing stuck bus

13.3 FPGA Changelog

Check the FPGA rev with:

echo $(($(tshwctl --peek --addr 51)>>4))
Rev Changes
0
  • Initial Release
1
  • Switched max3100 to use FPGA_IRQ_1 to leave FPGA_IRQ_0 to the silabs.
2
  • Corrected CTS/RTS polarity on MAX3100
  • Corrected flipped CPU UART CTS/RTS for bluetooth
  • Corrected HD1 SPI bus
3
  • Disabled pulldown on HD1 SPI CS.
4
  • Fixed the FPGA ttyMAX* uarts
5
  • The signal FPGA_IRQ_0 is now FPGA_RESET which needs to be pulsed on reset by u-boot. This is implemented in the May-27-2016 release.
  • Register 61, bit 1 is now used to force SPI at all times on the HD1 SPI pins rather than just on chip select assert. This should allow any GPIO to be used as chip selects.
6
  • Disables USB HUB 24mhz while in reset
7
  • Includes support for REV D pin changes.

Using the u-boot from Oct-07-2015 or later you can reload the FPGA during startup for custom FPGAs. During startup you will see u-boot reload this file:

Bytes transferred = 56341 (dc15 hex)
VME file checked: starting downloading to FPGA
Diamond Deployment Tool 3.5
CREATION DATE: Wed Oct 07 11:38:24 2015


Downloading FPGA 53248/56341 completed
FPGA downloaded successfully

13.4 Silabs Changelog

Revision Changes
0
  • Initial Release
1
  • Added Sleep mode
  • Blinks blue LED in low power modes. Sleep mode does this, as well as USB device connected with no power on the main VIN.
2
  • Added support for REV D boards. Earlier boards will continue to use REV 1 only.

13.5 Software Images

13.5.1 Yocto Changelog

Quad/Dual Image Solo/Duallite Image Changes
ts-x11-image-ts4900-quad-20140905235640.rootfs.tar.bz2 ts-x11-image-ts4900-solo-20140908160116.rootfs.tar.bz2
  • Initial Release
ts-x11-image-ts4900-quad-20141119190447.rootfs.tar.bz2 ts-x11-image-ts4900-solo-20141119204157.rootfs.tar.bz2
  • Systemd default
  • Added /usr/lib/openssh/sftp-server (Fixes QtCreator/Eclipse deploy)
  • Added QtQuick
  • Added Sqlite to QT
  • Added early TS-7970 support.
  • Updated kernel with significant fixes, see github for more information.
ts-x11-image-ts4900-quad-20141224171440.rootfs.tar.bz2 ts-x11-image-ts4900-solo-20141224175107.rootfs.tar.bz2
  • Updated Kernel
    • Fixed ISL RTC errors hardware builds that omit the RTC
    • Fixed I2C bus for 8390 ADC
    • Added small pop fix for sgtl5000 on the 8390
  • Updated ts4900-utils
    • New util 8390adc for reading the low speed MCP ADC
    • Fixed tshwctl to support auto TX-EN RS485 on ttymxc1
ts-x11-image-ts4900-quad-20150331224909.rootfs.tar.bz2 ts-x11-image-ts4900-solo-20150401003538.rootfs.tar.bz2
  • Updated to 3.10.53 kernel
    • Significant fixes to GPU, UARTs, CAN and more.
    • Added TS-TPC-8950 support
    • Fixed 7" twinkling pixels on TS-8390 w/solo
    • Included splash screen
  • Updated to Yocto Dizzy for new freescale GPU support
  • Added Chromium to default image (google-chrome)
  • Updated toolchain to match dizzy image
  • Included gstreamer in the image
  • Updated FPGA with crossbar, max3100 based spi uart, bluetooth fixes (REV C only)
ts-x11-image-ts4900-quad-20150527173205.rootfs.tar.bz2 ts-x11-image-ts4900-solo-20150528210615.rootfs.tar.bz2
  • Fixed networkd
  • Enabled PCIe in default kernel
    • Added I210 support for TS-7970
ts-x11-image-ts4900-quad-20150620060219.rootfs.tar.bz2 ts-x11-image-ts4900-solo-20150622150127.rootfs.tar.bz2
  • Added TS-7970 support
ts-x11-image-tsimx6-20150821190815.rootfs.tar.bz2
  • Updated to Yocto Fido
    • Removed GTK3 packages to reduce image size (GTK2 still available)
    • Removed distcc from default environment
    • Includes QT 5.4.3
    • Included qtmultimedia, xcursor-transparent theme
  • Updated Kernel
    • Includes fix for rare screen flip issues
ts-x11-image-tsimx6-20150821190815.rootfs.tar.bz2
  • Included significantly fixed support for the TS-7970
    • I210 support is fixed, but some prototype boards will need to be RMA'd to get MACs assigned.
    • All UARTs are now working
    • Included tsmicroctl for reading the silabs ADC (p10-12 4-20mA included)
    • Included load_fpga for software reloading fpgas later after boot
  • Updated TS-4900 FPGA to have CTS/RTS fixed for bluetooth, and corrected CTS/RTS polarity on the max3100s
ts-x11-image-tsimx6-20151014183028.rootfs.tar.bz2
  • Corrected defconfig used in kernel
    • Fixed WIFI and other modules
  • If used with the u-boot release from 10-14-2015 this fixes the mac address for the smsc95xx
ts-x11-image-tsimx6-20151221232637.rootfs.tar.bz2
  • Fixed MAC address to use device tree as well as parameter for the latest u-boot support.
  • Fixed tsgpio driver which was causing some incorrect DIO sets.
    • The WIFI driver uses tsgpio for toggling the enable which also corrects the behavior of ifdown/ifup wlan0.
  • Added rsync and lighttpd-cgi support
ts-x11-image-tsimx6-20160512161729.rootfs.tar.bz2
  • Added 100kohm pullups to the onboard/offboard SPI chip selects.
ts-x11-image-tsimx6-20161116215413.rootfs.tar.bz2
  • Updated to Yocto Jethro
  • Updates to QT 5.5
  • Updated to 4.1.15 based on Freescale/NXP's imx_4.1.15_1.0.0_ga.
  • Added improved support for TS-TPC-7990
  • New tshwctl with crossbar support.
ts-x11-image-tsimx6-20170301225516.rootfs.tar.bz2
  • Updated to Yocto Morty with the same imx_4.1.15_1.0.0_ga kernel
  • Includes QT 5.7.1
  • Included additional alsa utilities

13.5.2 Debian Changelog

Image Changes
debian-armhf-wheezy-20140929.tar.bz2
  • Initial Release
debian-armhf-wheezy-20141125.tar.bz2
  • Updated kernel with significant fixes, see github for more information.
  • Included first TS-7970 FPGA
debian-armhf-jessie-20160825.tar.bz2
  • New kernel - 3.10.53 (from freescale's 3.10.53_1.1.0_ga) instead of 3.10.17.
    • Fixed CAN dropped frames (just under 1% of frames were dropped on 3.10.17)
    • Fixed reported UART RX fifo overflows
    • GPU fixes
    • Kernel includes compiled in splash screen for quick graphical response on boot
  • TS-TPC-8950 support added
  • New FPGA (crossbar added, bluetooth fixed, and max3100 implemented)
  • Added bluez, wireless-tools, usbutils, nfs-common, and pciutils into the image.
  • Added Openssh server (generates on first boot)
debian-armhf-jessie-20150526.tar.bz2
  • First update to Debian Jessie
debian-armhf-jessie-20151008.tar.bz2
  • Included kernel support for TS-7970 REV A
  • Updated to latest TS-4900 FPGA (20150603)
  • Included openssh, generates keys on first boot. Remove /etc/ssh/*key* to regenerate.
  • Included latest ts4900-utils with TS-7970 support.
debian-armhf-jessie-20160512.tar.bz2
  • Fixed TS-7970 ttyMAX uarts (requires FPGA update)
  • Fixed resolv.conf symlink to use resolvd
  • Updated to 3.14.52 kernel
  • Corrected TS-TPC-8950 calibration
debian-armhf-jessie-20160512.tar.bz2
  • Moved to 4.1.15 kernel
  • Updated Debian to latest Jessie changes
  • Added latest ts4900-utils with improved TS-TPC-7990 support.
debian-armhf-jessie-20170123.tar.bz2
  • Added support for TS-7970 REV D hardware
  • Added support for TS-7990 REV B hardware
debian-armhf-jessie-20170306.tar.bz2
  • Fixed resolv.conf symlink
  • Added nfs-common
  • Cleaned up old temporary files
debian-armhf-jessie-20170327.tar.bz2
  • Fixed regression in TS-TPC-8950 support
  • Adds root.version to list image date
debian-armhf-jessie-20170419.tar.bz2
  • Fixed issue of missing U-boot splash screen disabling the backlight on REV B boards.
  • Fixed potential issue with WIFI not being recognized.
  • Added support for #TS-DC799-SILO board.

13.5.3 Arch Linux Changelog

Image Changes
arch-armhf-20140929.tar.gz Initial Release

13.5.4 Ubuntu Linux Changelog

Image Changes
ubuntu-armhf-16.04-20160407.tar.bz2
  • Initial Release
ubuntu-armhf-16.04-20160818.tar.bz2
  • Bumped from 3.14.52 to 4.1.15 kernel. This adds support for the TS-TPC-7990.
  • Added more common packages, mmc, can-utils, etc.
ubuntu-armhf-16.04-20170306.tar.bz2
  • Updated ts4900-utils for final TS-7970/TS-TPC-7990
  • Added TS-TPC-7990 REV B support

13.5.5 Ubuntu Core Linux Changelog

Image Changes
ubuntu-core-16-2016-12-22.img.bz2
  • Initial Release
ubuntu-core-16-2017-04-21.img.bz2
  • Fixed boot scripts to work with core updates
  • Added support for the TS-4900 carrier board specific device trees.
  • Added support for the TS-7970
  • Added support for the TS-TPC-7990
  • Updated Kernel
    • Added ttyMAX* uart support
    • Added fixes from our main Linux kernel to the RTC driver
    • Fixed ethernet timing

13.6 TS-7970 Errata

Issue Status Description
RS232 prevents booting on REV A Workarounds available, fixed in REV B

Early TS-7970 REV A boards may fail to boot if RS232 is connected before the board is powered. A small amount of RS232 idle negative voltage leaks from the transceiver to the FET controlling the switched 5V. The FET will not toggle while the output has a negative voltage, so the 5V rail never comes up. If this is a concern or if the issue is seen, we can rework the board to have a 2.5ohm resistor from SW_5V to 5V_A on U47 pins 4 and 5. REV A boards shipped after 01/13/2016 include this fix.

Boot is prevented if the USB Device port (not host) is plugged in without the console enable jumper. Fixed in REV C

If the console jumper is not installed the silabs has USB VBUS, but no data signals. This puts the USB device into a locked up state while it waits to communicate on this bus. Due to this lockup it is unable to monitor voltages and turn on the SW_5V to the reset of the board. The fix is to disconnect VBUS from the silabs which is done on the REV C PCB. A cable without VCC can be made to work around the issue, or submit an RMA.

14 Product Notes

14.1 FCC Advisory

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

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

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

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

14.2 Limited Warranty

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

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

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

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