From Technologic Systems Manuals
Jump to: navigation, search
TS-4100
ts-4100.gif
Product Page
Product Images
Specifications
Documentation
REV A Schematic
Mechanical Drawing
FTP Path
Processor
Freescale i.MX6ul 528MHz or 696MHz
i.MX6ul Product Page
CPU Documentation

Contents

1 Overview

The TS-4100 is a TS-Socket Macrocontroller Computer on Module designed for extremely low power applications.

2 Getting Started

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

Virtualization

Suggested Linux Distributions

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

2.1 Booting up the board

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

If you are using one of our off the shelf baseboards, please refer to that baseboard's manual here. Different baseboards use different power connectors, voltage ranges, and may have different power requirements.

The macrocontroller only requires a 5 V rail from the baseboard which may be regulated from other voltage ranges. Refer to the TS-Socket Connector section for the POWER pins.

Once power is applied to the whole device, there will be output on the debug console port. The next section of the manual provides information on getting the console connected. The first output is from U-Boot:

U-Boot 2016.03-14526-g436b9bf (May 16 2017 - 10:29:56 -0700)

CPU:   Freescale i.MX6UL rev1.1 at 396 MHz
Reset cause: WDOG
Board: Technologic Systems TS-4100
FPGA:  Rev 6
I2C:   ready
DRAM:  512 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
*** Warning - bad CRC, using default environment

Baseboard ID: 0x9
Baseboard Rev: 0
Net:   FEC0 [PRIME]
Press Ctrl+C to abort autoboot in 1 second(s)

The default U-Boot boot process will check for USB updates, and then will check the "SD Boot" jumper. If the SD boot jumper is set, it will boot to the Linux on the SD card. If it is not set, it will boot to the eMMC.

Note: The "*** Warning - bad CRC, using default environment" can be safely ignored when the unit is first booted. This means that no environment variables have been saved to disk, and U-Boot is falling back to the default. If "env save" is run, this will save the environment to disk, and this message will go away unless there is a further issue.

2.2 Get a Console

The console UART (ttymxc0) is a TTL UART at 115200 baud, 8n1 (8 data bits, no parity, 1 stop bit), and no flow control. On the macrocontroller this is CN2_93 (TX), CN2_95 (RX). Various baseboards bring this out using different methods. For example, the TS-8550 baseboard brings out a DB-9 connector with the console as RS-232. Other baseboards have a jumper to switch between the console port and another serial port. Some baseboards require an adapter board like the TS-9449. Refer to the baseboard model you are using here for more information on any specific jumpers or ports to connect to for console. Additionally, the TS-4100 console can be accessed via the USB micro connector, P2, on the TS-4100. Note that due to the location of the port and the height of the TS-4100 above a baseboard, this may not be a viable option for all applications.


Console from Linux

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

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

Picocom is a very small and simple client.

picocom -b 115200 /dev/ttyUSB0

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

screen /dev/ttyUSB0 115200

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

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


Console from Windows

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

Device Manager Putty Configuration

3 U-Boot

3.1 U-Boot Environment

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

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

3.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
 
# Boots into the binary at $loadaddr.  The file is expected to
# to be a compressed kernel image, zImage.
bootz
# Boots into the binary at $loadaddr, skips the initrd, and specifies
# the fdtaddr so Linux knows where to find the board support
bootz ${loadaddr} - ${fdtaddr}
 
# Get a DHCP address
dhcp
# This sets ${ipaddr}, ${dnsip}, ${gatewayip}, and ${netmask}
# 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
 
# 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/zImage
# Load Kernel from eMMC
load mmc 1:1 ${loadaddr} /boot/zImage
 
 
# View the fdt from U-Boot with fdt
load mmc 0:1 ${fdtaddr} /boot/imx6ul-ts7180.dtb
fdt addr ${fdtaddr}
fdt print
 
# It is possible to blindly jump into any memory
# This is similar to bootz but does not expect a compressed
# kernel binary
load mmc 0:1 ${loadaddr} /boot/custombinary
go ${loadaddr}
 
# Browse fat,ext2, ext3, or ext4 filesystems:
ls mmc 0:1 /
 
# Access memory like devmem or peekpoke in Linux, allows 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
 
# Delay in seconds
sleep 10
 
# 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 bdinfo
 
# Print U-boot version/build information
version

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

4.1 Getting Started with Debian

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


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-4100-linux/distributions/debian/debian-armhf-jessie-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.


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

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

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

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

4.3 Debian Application Development

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

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

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

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

5 Backup / Restore

5.1 MicroSD Card

These instructions assume an SD card with one partition. Most SD cards ship this way by default, but if there are modified partitions a utility such as gparted or fdisk may be needed to remove partitions and recreate it with a single partition.

Plug the SD card into a USB reader and connect it to your Linux PC. These instructions assume the SD appears to the system as /dev/sdc. Be sure to verify the correct device node when the SD card is inserted in your system!

Running these commands will reflash the SD card to our default latest image.

# Verify nothing else has this mounted
sudo umount /dev/sdc1
 
sudo mkfs.ext4 /dev/sdc1
sudo mkdir /mnt/sd
sudo mount /dev/sdc1 /mnt/sd/
wget ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/ts-4100-linux/distributions/debian/debian-armhf-jessie-latest.tar.bz2
 
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.


After the image is written, the files can all be verified on disk against the original files created in the tarball. Reinsert the disk to verify any block cache is gone, then run the following:

mount /dev/sdc1 /mnt/sd
cd /mnt/sd/
sudo md5sums -c md5sums.txt
umount /mnt/sd
sync

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

5.2 eMMC

The simplest way to backup/restore the eMMC is through U-Boot. Boot to U-Boot and run the following command:

ums 0 mmc 1

This will make the device act as a USB mass storage device with direct access to the emmc disk. On a linux workstation, to backup the image:

dmesg | tail -n 30
# Look for the last /dev/sd* device connected.  This should also match the eMMC
# size of around 3.78GiB.  On my system, this is /dev/sdd.
sudo mkdir /mnt/emmc/
sudo mount /dev/mmcblk1p1 /mnt/emmc/
cd /mnt/emmc/
tar -cjf /path/to/ts4100-backup-image.tar.bz2
cd ../
umount /mnt/emmc/
sync


To write a new filesystem to the TS-4100:

dmesg | tail -n 30
# Look for the last /dev/sd* device connected.  This should also match the eMMC
# size of around 3.78GiB.  On my system, this is /dev/sdd.
sudo mkdir /mnt/emmc/
sudo mkfs.ext4 /dev/mmcblk1p1
# If the above command fails, use fdisk or gparted to repartition the emmc
# to have one large partition.
sudo mount /dev/mmcblk1p1 /mnt/emmc/
tar -xjf /path/to/ts4100-new-image.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.

6 Compile the Kernel

Compiling the kernel requires an armhf toolchain. We recommend development under Debian which includes an armhf compiler in the repositories.

On a Debian host PC:

su root
 
apt-get install curl git build-essential lzop u-boot-tools libncursesw5-dev
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

For Ubuntu:

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

Once those are installed:

git clone https://github.com/embeddedarm/linux-tsimx
cd linux-tsimx
git checkout ts-imx_4.1.15_2.0.0_ga
 
# These next commands set up some necessary environment variables
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
export LOADADDR=0x80800000
 
# This sets up the default configuration that we ship with
make ts4100_defconfig
 
## Make any changes in "make menuconfig" or driver modifications, then compile
make && make zImage

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/zImage
sudo cp arch/arm/boot/zImage  /mnt/sd/boot/zImage
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

7 Features

7.1 Baseboard ID

All of our off the shelf baseboards contain a hard wired 3-state 8-input multiplexers. This is not required to implement in custom baseboards, with the TS-4100 it is used to pick the device tree. If a baseboard ID is not present, the default device tree would be loaded. During startup in u-boot, 4 DIO are used to obtain the baseboard model id using the bbdetect command. The red LED (CN2_06) is state 0, green LED (CN2_08) is state 1, BUS_DIR (CN1_98) is state 2, and BD_ID_DATA (CN1_83) is used for data.

The first 6 lines are used as the six bits that define the baseboard. The last two lines (Y6 & Y7 in the schematic image below) define the bits to indicate the board revision.

For custom baseboards we have reserved the address 42 which will never be used by our standard products.

TS-8160 baseboard ID resulting in ID 6.


TS-Baseboard IDs
ID Baseboard
0 TS-8200
1 Reserved
2 TS-TPC-8390
4 TS-8500
5 TS-8400
6 TS-8160
7 TS-8100
8 TS-8820-BOX
9 TS-8150
10 TS-TPC-8900
11 TS-8290
13 TS-8700
14 TS-8280
15 TS-8380
16 TS-AN20
17 TS-TPC-8920
19 TS-8550
255 TS-8200

7.2 Bluetooth

The WIFI option on the board also includes a bluetooth 4.0 LE module. To use bluetooth, it is necessary to first configure the WIFI interface. Then, run the following commands:

# Install bluez if it is not already present
apt-get update
apt-get install bluez bluez-tools
 
hciattach /dev/ttymxc2 any 115200 noflow
hciconfig hci0 up
hcitool cmd 0x3F 0x0053 00 10 0E 00 01
stty -F /dev/ttymxc2 921600 crtscts

Now you may scan for available devices with:

hcitool scan

This will return a list of devices such as:

14:74:11:AB:12:34	SAMSUNG-SM-G900A

You may request more information from a detected device like so:

hcitool info 14:74:11:AB:12:34

This will produce lots of details about the device, for example:

Requesting information ...                                                      
        BD Address:  14:74:11:AB:12:34                                          
        OUI Company: Samsung Electronics Co.,Ltd (4C-A5-6D)                     
        Device Name: SAMSUNG-SM-G900A                                           
        LMP Version: 4.1 (0x7) LMP Subversion: 0x610c                           
        Manufacturer: Broadcom Corporation (15)                                 
        Features page 0: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87        
        .
        .
        .

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

7.3 CAN

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 which can be used to communicate over a CAN network without writing any code. The candump utility can be used to dump all data on the network

## First, set the baud rate and bring up the device:
ip link set can0 type can bitrate 250000
ip link set can0 up
 
## Dump data & errors:
candump 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.

7.4 COM Ports

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

UART TX RX TXEN
ttymxc0 CN2_93 CN2_95 N/A
ttymxc1 CN2_82 CN2_84 N/A
ttymxc2 Onboard Bluetooth RX Onboard Bluetooth TX N/A
ttymxc3 CN2_78 CN2_80 N/A
ttymxc4 CN2_90 CN2_92 N/A
ttymxc6 CN2_86 CN2_88 N/A

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

7.5 CPU

This board uses the i.MX6ul 528MHz or 696MHz CPU which is very similar to the i.MX6 Solo used on the TS-4900 using many of the same CPU peripherals IP cores, but using a Cortex-A7 instead to target lower power consumption.

Refer to NXP's documentation for more detailed information on the CPU core:

7.6 eMMC

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

The eMMC module has a similar concern by default to SD cards in that they should not be powered down during a write/erase cycle. However, 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. Even in cases where the wrong data is present on the next boot, fsck is able to deal with the older data being present in a 512B block. The downsides to setting these modes are that it will about half the size of the eMMC module to 1.759Gib by default, and write speed will slightly be slower.

The mmc-utils package is used to enable these modes.

WARNING: If you are using a custom built TS-4100 with an eMMC sized larger than 4GB, contact us before using these commands. The SLC partition will be specified different on larger disks.
mmc write_reliability set -n 0 /dev/mmcblk1
mmc enh_area set -y 0 1847296 /dev/mmcblk1
WARNING: Setting either of those modes is permanent and using the wrong value it is possible to essentially 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.

7.7 Ethernet Port

This board includes two ethernet ports using the dual onboard CPU controllers and external Micrel PHYs. The MAC address is assigned from the Technologics pool using 00:d0:69:00:00:00, and the two MAC addresses will always be sequential. These MAC addresses are burned into the CPU's fuses during production.

U-boot supports only the ethernet port on CN1_01-11 odd. Once booted to Linux, this is eth1, and CN2_16-24 even provide eth0.

Note: Ethernet Magnetics should be placed as close to CN2 as possible on the base board.

7.8 FPGA

7.8.1 FPGA Registers

The TS-4100 FPGA registers are accessed over I2C. The /sys/class/gpio driver provides access to the IO using these registers. See the #GPIO section for more information on the recommended method for IO access.

The FPGA is available at I2C addresses 0x28-0x2f. First write the address which is 16-bits, followed by the data which is 8-bits.

The first registers 0-127 are used to control the GPIO. Registers 128-255 control the crossbar for the various pins. Use the IO offsets int the second table for the GPIO and CROSSBAR registers.

GPIO_n Register
Address Bits Description
0-127 7:3 Reserved (Write 0)
2 GPIOn Input Data
1 GPIOn Output Data
0 GPIOn Output Enable
128-255 7 CROSSBARn GPIO mode
6:0 CROSSBARn Value
256-271 7:0 GPIOn Bank Input
272-287 7:0 GPIOn Bank Output Data
288-303 7:0 GPIOn Bank Output Enable (1=out)
304 7:0 Model Number MSB (0x41)
305 7:0 Model Number LSB (0x00)
306 7:0 FPGA Rev
307-8191 7:0 Reserved
8192-16384 7:0 ZPU RAM access

In the above table the GPIO, Crossbar, and Bank registers will use the following IO. The bank registers should divide the IO number by 8 to get the offset, and use the modulus to get the bit number.

FPGA IO
IO Number Pad Crossbar support Direction
1 SPARE_1_PAD Y GPIO
2 SPARE_2_PAD Y GPIO
3 SPARE_3_PAD Y GPIO
4 SPARE_4_PAD Y GPIO
5 UART3_TXD_PAD (ttymxc2) Y Input
6 UART3_RTS_PADn (ttymxc2) Y Input
7 UART4_TXD_PAD (ttymxc3) Y Input
8 UART7_TXD_PAD (ttymxc6) Y Input
9 UART3_RXD_PAD Y Output
10 UART3_CTS_PAD Y Output
11 UART4_RXD_PAD Y Output
12 UART7_RXD_PAD Y Output
13 WIFI_RXD_PAD Y Input
14 WIFI_RTS_PAD Y Input
15 WIFI_IRQ_PADN Y Input
16 WIFI_TXD_PAD Y Output
17 WIFI_CTS_PAD Y Output
18 ZPU_BREAK N Input
19 ZPU_RESET N Output
20 EN_WIFI_PWR_PAD DIO Output
21 WIFI_RESET_PAD DIO Output
22 EN_USB_HOST_5V_PAD DIO Output
23 EN_LCD_3V3_PAD DIO Output
24 EN_SD_POWER_PAD DIO Output
25 OFF_BD_RESET_PADN DIO Output
26 EN_SW_3V3_PAD DIO Output
27 GREEN_LED_PADN DIO Output
28 RED_LED_PADN DIO Output
29 UART_A_RXD_PAD UART+Spares GPIO
30 UART_B_RXD_PAD UART+Spares GPIO
31 UART_C_RXD_PAD UART+Spares GPIO
32 UART_D_RXD_PAD UART+Spares GPIO
33 UART_A_TXD_PAD UART+Spares GPIO
34 UART_B_TXD_PAD UART+Spares GPIO
35 UART_C_TXD_PAD UART+Spares GPIO
36 UART_D_TXD_PAD UART+Spares GPIO
37 DIO_0 UART+SPARE pins GPIO
38 DIO_1 UART+SPARE pins GPIO
39 DIO_2 UART+SPARE pins GPIO
40 DIO_3 UART+SPARE pins GPIO
41 DIO_4 UART+SPARE pins GPIO
42 DIO_5 UART+SPARE pins GPIO
43 DIO_6 UART+SPARE pins GPIO
44 DIO_7 UART+SPARE pins GPIO
45 DIO_8 UART+SPARE pins GPIO
46 DIO_9 UART+SPARE pins GPIO
47 DIO_10 UART+SPARE pins GPIO
48 DIO_11 UART+SPARE pins GPIO
49 DIO_12 UART+SPARE pins GPIO
50 DIO_13 UART+SPARE pins GPIO
51 DIO_14 UART+SPARE pins GPIO
52 DIO_15 UART+SPARE pins GPIO
53 DIO_16 UART+SPARE pins GPIO
54 DIO_17 UART+SPARE pins GPIO
55 DIO_18 UART+SPARE pins GPIO
56 DIO_19 UART+SPARE pins GPIO
57 DIO_20 UART+SPARE pins GPIO
58 DIO_21 UART+SPARE pins GPIO
59 DIO_22 UART+SPARE pins GPIO
60 DIO_23 UART+SPARE pins GPIO
61 DIO_24 UART+SPARE pins GPIO
62 DIO_25 UART+SPARE pins GPIO
63 DIO_26 UART+SPARE pins GPIO
64 DIO_27 UART+SPARE pins GPIO
65 DIO_28 UART+SPARE pins GPIO
66 DIO_29 UART+SPARE pins GPIO
67 DIO_30 UART+SPARE pins GPIO
68 DIO_31 UART+SPARE pins GPIO
69 DIO_32 UART+SPARE pins GPIO
70 DIO_33 UART+SPARE pins GPIO
71 DIO_34 UART+SPARE pins GPIO
72 DIO_35 UART+SPARE pins GPIO
73 DIO_36 UART+SPARE pins GPIO
74 DIO_37 UART+SPARE pins GPIO
75 DIO_38 UART+SPARE pins GPIO
76 DIO_39 UART+SPARE pins GPIO
77 DIO_40 UART+SPARE pins GPIO
78 DIO_41 UART+SPARE pins GPIO
79 DIO_42 UART+SPARE pins GPIO
80 DIO_43 UART+SPARE pins GPIO
81 DIO_44 UART+SPARE pins GPIO
82 DIO_45 UART+SPARE pins GPIO
83 DIO_46 UART+SPARE pins GPIO


7.9 GPIO

The i.MX6ul and FPGA GPIO are exposed using the kernel's sysfs GPIO interface. See the kernel's documentation here for more detail. This interface provides a set of files and directories for interacting with GPIO which can be used from any language that can write files.

To interact with a 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. In this case, you can "cat /sys/kernel/debug/gpio" to see what driver has claimed it. If it succeeds you will have a /sys/class/gpio/gpio48/ directory. The relevant files in this directory are:

 direction - "in", "out" (out = low), "low", "high"
 value - write "1" or "0", or read "1" or "0" if direction is in
 edge - write with "rising", "falling", or "none"

With direction you can set it as an output and set the direction at the same time with high/low. If you just specify out this is the same as low.

# Set as a low output
echo "out" > /sys/class/gpio/gpio48/direction
# Set GPIO 48 high
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
 
# You can set it as a high output by setting the direction:
echo "high" > /sys/class/gpio/gpio48/direction

As an output, the in can be written to 0 for low (GND), or 1 for high (3.3V). The GPIO pins directly off of the i.MX6ul processor support an absolute maximum of -0.5 to 3.6V. It is also possible to use any processor GPIO as an interrupt by writing the edge value, and then using select() or poll() on the value file for changes.

7.9.1 CPU GPIO Table

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.

Schematic Name CPU PAD [1] GPIO Number Common Functions [2] Location
CONSOLE_RXD UART1_RX_DATA 17 Console uart CN2_095 / Silabs
CONSOLE_TXD UART1_TX_DATA 16 Console uart CN2_093 / Silabs
SPARE_1 UART1_CTS_B 18 GPIO FPGA Crossbar (Default NC)
SPARE_2 UART1_RTS_B 19 GPIO FPGA Crossbar (Default NC)
UART2_RXD UART2_RX_DATA 21 #COM_Ports CN2_084
UART2_TXD UART2_TX_DATA 20 #COM_Ports CN2_082
CAN_2_TXD UART2_CTS_B 22 #CAN CN1_071
CAN_2_RXD UART2_RTS_B 23 #CAN CN1_069
UART3_RXD UART3_RX_DATA 25 #COM_Ports FPGA Crossbar (Default Bluetooth RX)
UART3_TXD UART3_TX_DATA 24 #COM_Ports FPGA Crossbar (Default Bluetooth TX)
UART3_CTS# UART3_CTS_B 26 #COM_Ports FPGA Crossbar (Default Bluetooth CTS)
UART3_RTS# UART3_RTS_B 27 #COM_Ports FPGA Crossbar (Default Bluetooth RTS)
UART4_RXD UART4_RX_DATA 29 #COM_Ports FPGA Crossbar (Default CN2_080)
UART4_TXD UART4_TX_DATA 28 #COM_Ports FPGA Crossbar (Default CN2_078)
UART5_RXD UART5_RX_DATA 31 #COM_Ports CN2_092
UART5_TXD UART5_TX_DATA 30 #COM_Ports CN2_090
AUD_RXD JTAG_TCK 14 #I2S / #JTAG CN2_042
AUD_CLK JTAG_TDI 13 #I2S / #JTAG CN2_036
AUD_FRM JTAG_TDO 12 #I2S / #JTAG CN2_038
AUD_MCLK JTAG_TMS 11 #I2S / #JTAG CN2_054
AUD_TXD JTAG_TRST_B 15 #I2S / #JTAG CN2_040
EN_ETH_PHY_PWR JTAG_MOD 10 Eth PHY enable / #JTAG CN2_046
CAM_D_0 CSI_DATA00 117 #Camera Interface / GPIO CN2_052
CAM_D_1 CSI_DATA01 118 #Camera Interface / GPIO CN2_056
CAM_D_2 CSI_DATA02 119 #Camera Interface / GPIO CN2_058
CAM_D_3 CSI_DATA03 120 #Camera Interface / GPIO CN2_060
CAM_D_4 CSI_DATA04 121 #Camera Interface / GPIO CN2_062
CAM_D_5 CSI_DATA05 122 #Camera Interface / GPIO CN2_064
CAM_D_6 CSI_DATA06 123 #Camera Interface / GPIO CN2_066
CAM_D_7 CSI_DATA07 124 #Camera Interface / GPIO CN2_068
CAM_HSYNC CSI_HSYNC 116 #Camera Interface / GPIO CN2_070
CAM_MCLK CSI_MCLK 113 #Camera Interface / GPIO CN2_034
CAM_PIX_CLK CSI_PIXCLK 114 #Camera Interface / GPIO CN2_032
CAM_VSYNC CSI_VSYNC 115 #Camera Interface / GPIO CN2_072
USB_OTG1_ID GPIO1_IO00 0 USB1 OTG ID CN2_074 / USB_OTG_5V power switch
GPIO_1_ADC GPIO1_IO01 1 #ADC / GPIO CN2_012
I2C_1_CLK GPIO1_IO02 2 #I2C Onboard Silabs
I2C_1_DAT GPIO1_IO03 3 #I2C Onboard Silabs
EN_OTG1_5V GPIO1_IO04 4 USB OTG switch 5V [3] Onboard Regulator
SD_VSEL_1.8V GPIO1_IO05 5 SD 1.8V switch [4] Onboard Regulator
ETH_MDIO GPIO1_IO06 6 Onboard Ethernet MDIO Onboard PHYs
ETH_MDC GPIO1_IO07 7 Onboard Ethernet MDIO Onboard PHYs
LCD_PWM_ADC8 GPIO1_IO08 8 #PWM, #ADC, GPIO CN1_057
GPIO_9_ADC GPIO1_IO09 9 #ADC, GPIO CN2_091
POWER_FAIL SNVS_TAMPER0 128 Power Notification [5] Onboard PWR Monitor
FPGA_IRQ SNVS_TAMPER1 129 #FPGA FPGA Crossbar (Default NC)
EN_FPGA_PWR SNVS_TAMPER2 130 FPGA 3.3V switch Onboard FET
GPIO_DVFS SNVS_TAMPER3 131 CPU DVFS [6] Onboard Regulator
JTAG_FPGA_TDO SNVS_TAMPER4 132 FPGA JTAG FPGA JTAG pin
JTAG_FPGA_TDI SNVS_TAMPER5 133 FPGA JTAG FPGA JTAG pin
JTAG_FPGA_TMS SNVS_TAMPER6 134 FPGA JTAG FPGA JTAG pin
JTAG_FPGA_TCK SNVS_TAMPER7 135 FPGA JTAG FPGA JTAG pin
SPARE_4 SNVS_TAMPER8 136 GPIO FPGA Crossbar (Default WIFI IRQ)
EN_SD_POWER SNVS_TAMPER9 137 SD power enable Onboard Regulator
I2C_3_DAT LCD_DATA00 69 #I2C [7] CN2_030, HD1 pin 10
I2C_3_CLK LCD_DATA01 70 #I2C [7] CN2_028, HD1 pin 8
LCD_D02 LCD_DATA02 71 #Parallel LCD Interface, GPIO CN1_028
LCD_D03 LCD_DATA03 72 #Parallel LCD Interface, GPIO CN1_030
LCD_D04 LCD_DATA04 73 #Parallel LCD Interface, GPIO CN1_032
LCD_D05 LCD_DATA05 74 #Parallel LCD Interface, GPIO CN1_034
LCD_D06 LCD_DATA06 75 #Parallel LCD Interface, GPIO CN1_038
LCD_D07 LCD_DATA07 76 #Parallel LCD Interface, GPIO CN1_040
CAN_1_TXD LCD_DATA08 77 #CAN, GPIO CN2_097
CAN_1_RXD LCD_DATA09 78 #CAN, GPIO CN2_099
LCD_D10 LCD_DATA10 79 #Parallel LCD Interface, GPIO CN1_023
LCD_D11 LCD_DATA11 80 #Parallel LCD Interface, GPIO CN1_025
LCD_D12 LCD_DATA12 81 #Parallel LCD Interface, GPIO CN1_027
LCD_D13 LCD_DATA13 82 #Parallel LCD Interface, GPIO CN1_031
LCD_D14 LCD_DATA14 83 #Parallel LCD Interface, GPIO CN1_033
LCD_D15 LCD_DATA15 84 #Parallel LCD Interface, GPIO CN1_035
UART7_TXD LCD_DATA16 85 #COM_Ports FPGA Crossbar (Default CN2_86)
UART7_RXD LCD_DATA17 86 #COM_Ports FPGA Crossbar (Default CN2_88)
LCD_D18 LCD_DATA18 87 #Parallel LCD Interface, GPIO CN1_041
LCD_D19 LCD_DATA19 88 #Parallel LCD Interface, GPIO CN1_043
LCD_D20 LCD_DATA20 89 #Parallel LCD Interface, GPIO CN1_045
LCD_D21 LCD_DATA21 90 #Parallel LCD Interface, GPIO CN1_042
LCD_D22 LCD_DATA22 91 #Parallel LCD Interface, GPIO CN1_044
LCD_D23 LCD_DATA23 92 #Parallel LCD Interface, GPIO CN1_046
LCD_PIX_CLK LCD_CLK 64 #Parallel LCD Interface, GPIO CN1_049
LCD_DE LCD_ENABLE 65 #Parallel LCD Interface, GPIO CN1_055
LCD_HSYNC LCD_HSYNC 66 #Parallel LCD Interface, GPIO CN1_051
LCD_VSYNC LCD_VSYNC 67 #Parallel LCD Interface, GPIO CN1_053
FPGA_RESET# NAND_WP_B 107 Used to reset on reload Onboard FPGA
SPI_3_FPGA_CS# NAND_READY_B 108 FPGA SPI CS Onboard FPGA
SPI_3_CLK NAND_CE0_B 109 #SPI CN2_071, HD1 pin 15
SPI_3_MOSI NAND_CE1_B 110 #SPI CN2_067, HD1 pin 11
SPI_3_MISO NAND_CLE 111 #SPI CN2_069, HD1 pin 9
SPARE_3 NAND_DQS 112 GPIO FPGA Crossbar (Default NC)
EMMC_CLK NAND_RE_B 96 #EMMC Onboard eMMC
EMMC_CMD NAND_WE_B 97 #EMMC Onboard eMMC
EMMC_D0 NAND_DATA00 98 #EMMC Onboard eMMC
EMMC_D1 NAND_DATA01 99 #EMMC Onboard eMMC
EMMC_D2 NAND_DATA02 100 #EMMC Onboard eMMC
EMMC_D3 NAND_DATA03 101 #EMMC Onboard eMMC
SPI_4_CLK NAND_DATA04 102 SPI Onboard WIFI
SPI_4_MOSI NAND_DATA05 103 SPI Onboard WIFI
SPI_4_MISO NAND_DATA06 104 SPI Onboard WIFI
SPI_4_CS# NAND_DATA07 105 SPI Onboard WIFI
SPI_3_OFF_BD_CS# NAND_ALE 106 #SPI CN2_065, HD1 pin 13
SD_D0 SD1_DATA0 50 #SD CN1_018, Onboard MicroSD pin 7
SD_D1 SD1_DATA1 51 #SD CN1_020, Onboard MicroSD pin 8
SD_D2 SD1_DATA2 52 #SD CN1_006, Onboard MicroSD pin 1
SD_D3 SD1_DATA3 53 #SD CN1_008, Onboard MicroSD pin 2
SD_CMD SD1_CMD 48 #SD CN1_010, Onboard MicroSD pin 3
SD_CLK SD1_CLK 49 #SD CN1_014, Onboard MicroSD pin 5
  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 for a complete list.
  3. TODO
  4. This is handled automatically by the kernel after negotiating the capabilities of the connected card. Switching to 1.8V on a 3.3V card can cause damage.
  5. This will assert high when power is disconnected and the system and the board is running off supercaps if populated.
  6. Under almost all cases this should be maintained by the kernel
  7. 7.0 7.1 This i2c bus is used to access all of the FPGA GPIO and typically should not be repurposed as GPIO.

7.9.2 FPGA GPIO Table

The FPGA IO in Linux are GPIO 160-287. The crossbar mode indicates what this pin will output from the FPGA's perspective. For example, by default SPARE_4 outputs the value it samples from the WIFI_IRQ pin. WIFI_IRQ however is a GPIO so the FPGA can sample the input value.

Schematic Name GPIO Number Default Crossbar Mode Location
SPARE_1 161 GPIO (0) CPU GPIO (18) UART1_CTS_B
SPARE_2 162 GPIO (0) CPU GPIO (19) UART1_RTS_B
SPARE_3 163 GPIO (0) CPU GPIO (112) NAND_DQS
SPARE_4 164 WIFI_IRQ (15) CPU GPIO
UART3_TXD 165 GPIO (0) CPU ttymxc2 TX UART3_TX_DATA
UART3_RTS 166 GPIO (0) CPU ttymxc2 RTS UART3_RTS_B
UART4_TXD 167 GPIO (0) CPU ttymxc3 TX UART4_TX_DATA
UART7_TXD 168 GPIO (0) CPU ttymxc6 TX LCD_DATA16
UART3_RXD 169 WIFI_RXD (13) CPU ttymxc2 RX UART3_RX_DATA
UART3_CTS 170 GPIO (0) CPU ttymxc2 CTS UART3_CTS_B
UART4_RXD 171 UART_A_RXD (29) CPU ttymxc3 RX UART4_RXD
UART7_RXD 172 UART_B_RXD (30) CPU ttymxc6 RX LCD_DATA17
WIFI_RXD 173 GPIO (0) Onboard WIFI RXD
WIFI_RTS 174 GPIO (0) Onboard WIFI RTS
WIFI_IRQ 175 GPIO (0) Onboard WIFI IRQ
WIFI_TXD 176 UART3_TXD (16) Onboard WIFI TXD
WIFI_CTS 177 UART3_RTS (6) Onboard WIFI CTS
ZPU_BREAK 178 GPIO (0) Register
ZPU_RESET 179 GPIO (0) Register
EN_WIFI_PWR 180 GPIO (0) Onboard WIFI CHIP_EN
WIFI_RESET 181 GPIO (0) Onboard WIFI RESET
EN_USB_HOST_5V 182 GPIO (0) CN1_004
EN_LCD_3V3 183 GPIO (0) CN1_048
EN_SD_POWER_PAD 184 GPIO (0) Onboard Regulator
OFF_BD_RESET 185 GPIO (0) CN1_009
GREEN_LED 187 GPIO (0) CN2_008
RED_LED 188 GPIO (0) CN2_006
UART_A_RXD 189 GPIO (0) CN2_078
UART_B_RXD 190 GPIO (0) CN2_088
UART_C_RXD 191 GPIO (0) CN2_096
UART_D_RXD 192 GPIO (0) CN2_100
UART_A_TXD_PAD 193 UART4_TXD (7) CN2_082
UART_B_TXD_PAD 194 UART7_TXD (8) CN2_086
UART_C_TXD_PAD 195 GPIO (0) CN2_094
UART_D_TXD_PAD 196 GPIO (0) CN2_098
DIO_00 197 GPIO (0) CN1_093
DIO_01 198 GPIO (0) CN1_091
DIO_02 199 GPIO (0) CN1_089
DIO_03 200 GPIO (0) CN1_087
DIO_04 201 GPIO (0) CN1_085
DIO_05 202 GPIO (0) CN1_083
DIO_06 203 GPIO (0) CN1_081
DIO_07 204 GPIO (0) CN1_079
DIO_08 205 GPIO (0) CN1_077
DIO_09 206 GPIO (0) CN1_073
DIO_12 209 GPIO (0) CN1_067
DIO_13 210 GPIO (0) CN1_065
DIO_14 211 GPIO (0) CN1_063
DIO_15 212 GPIO (0) CN1_061
DIO_16 213 GPIO (0) CN1_059
DIO_17 214 GPIO (0) CN1_097
DIO_18 215 GPIO (0) CN1_099
DIO_19 216 GPIO (0) CN1_100
DIO_20 217 GPIO (0) CN1_098
DIO_21 218 GPIO (0) CN1_096
DIO_22 219 GPIO (0) CN1_094
DIO_23 220 GPIO (0) CN1_092
DIO_24 221 GPIO (0) CN1_090
DIO_25 222 GPIO (0) CN1_088
DIO_26 223 GPIO (0) CN1_086
DIO_27 224 GPIO (0) CN1_084
DIO_28 225 GPIO (0) CN1_082
DIO_29 226 GPIO (0) CN1_080
DIO_30 227 GPIO (0) CN1_078
DIO_31 228 GPIO (0) CN1_076
DIO_32 229 GPIO (0) CN1_074
DIO_33 230 GPIO (0) CN1_072
DIO_34 231 GPIO (0) CN1_070
DIO_35 232 GPIO (0) CN1_068
DIO_36 233 GPIO (0) CN1_066
DIO_37 234 GPIO (0) CN1_064
DIO_38 235 GPIO (0) CN1_060
DIO_39 236 GPIO (0) CN1_058
DIO_41 238 GPIO (0) CN1_024
DIO_42 239 GPIO (0) CN1_026
DIO_43 240 GPIO (0) CN1_019
DIO_44 241 GPIO (0) CN1_021
DIO_45 242 GPIO (0) CN1_037
DIO_46 243 GPIO (0) CN1_039

7.10 I2S Audio

TS-4100 I2S Audio

7.11 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 <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);
 
	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;
	}
 
	while(1) {
		int buf; // Holds irq junk data
		FD_SET(irqfd, &fds); //add the fd to the set
		// See if the IRQ has any data available to read
		ret = select(irqfd + 1, NULL, NULL, &fds, NULL);
		if(ret == -1)
			continue;
 
		if(FD_ISSET(irqfd, &fds))
		{
			printf("IRQ detected %d\n", i);
			i++;
			// Clear the junk data in the IRQ file
			lseek(irqfd, 0, 0);
			read(irqfd, &buf, sizeof(buf));
		}
	}
 
	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.

7.12 LCD Interface

TS-4100 LCD Interface

7.13 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
rc-feedback IR Reciever trigger [1]
can0-tx CAN0 transmit activity
can0-rx CAN0 receive activity
can0-rxtx CAN0 activity
can1-tx CAN1 transmit activity
can1-rx CAN1 receive activity
can1-rxtx CAN1 activity
mmc0 MicroSD activity
mmc1 eMMC activity
timer 2hz blink
oneshot Blinks after delay. [2]
heartbeat Similar to timer, but varies the period based on system load
backlight Toggles on FB_BLANK
gpio Toggle based on a specified gpio. [3]
cpu0 Blink on CPU core 0 activity
default-on Only turns on by default. Only useful for device tree.
transient Specify on/off with time to turn off. [4]
  1. There is no IR directly on the TS-4100, this would be from a USB peripheral.
  2. See the Kernel documentation for more details
  3. 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
  4. See the Kernel documentation for more details

7.14 MicroSD Card Interface

The i.MX6ul 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. Sandisk Extreme cards with UHS support have shown 58MB/s Read and 59MB/s write. The linux driver provides access to this socket at /dev/mmcblk0 as a standard Linux block device.

This graph shows our SD write endurance test for 40 TS-7553 boards 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.

Seethe IMX6ul reference manual for more information on this controller.

We have performed compatibility testing on the Sandisk MicroSD cards we provide, and we do not suggest switching brands/models without your own qualification testing. Though SD cards in theory will all follow the standard and just work, in practice cards vary significantly and can fail in subtle ways. We do not recommend ATP or Transcend MicroSD cards specifically due to known corruption issues that can occur after many GB of written data.

Our testing has shown that on average microSD cards will last between 6-12TB of written data before showing a single bit of corruption. This is enough for most applications to write for years and not see any issues, but for more reliable consider the eMMC which is expected to last over 100TB of writes. Higher end SD cards can also extend this, but industrial grade SD cards typically carry a cost much higher than the eMMC.

MicroSD cards should not be powered down during a write/erase cycle or you will eventually experience disk corruption. It is not always possible for fsck to recover from the types of failures that will be seen with SD power loss. The system should be designed to avoid power loss to SD cards, or the eMMC module should be used for storage instead which can be configured to be resilient to power loss.

7.15 Power Consumption

TS-4100 Power Consumption

7.16 RTC

The TS-4100 utilizes the Freescale SNVS Low Power Realtime Clock (RTC) module that's in the iMX6ul. This is /dev/rtc0 in our images, and is accessed using the standard hwclock command.

7.17 USB

7.17.1 USB OTG

Depending on which baseboard the TS-4100 is used with, the OTG port may be usable as host, or it may be brought out to a MicroAB port allowing it to be host or device. Several devices are compiled into the default kernel. Additional 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 which simulates an ethernet network connection between the host pc and the i.MX6.

Mass Storage

modprobe g_mass_storage file=/dev/mmcblk0

This will present the SD card to the host pc connected to the USB port. Eg:

[85421.087855] scsi 4:0:0:0: Direct-Access     Linux    File-Stor Gadget 0401 PQ: 0 ANSI: 2
[85421.088486] sd 4:0:0:0: Attached scsi generic sg2 type 0
[85421.089546] sd 4:0:0:0: [sdc] 31116288 512-byte logical blocks: (15.9 GB/14.8 GiB)
[85421.196213] sd 4:0:0:0: [sdc] Write Protect is off
[85421.196218] sd 4:0:0:0: [sdc] Mode Sense: 0f 00 00 00
[85421.306216] sd 4:0:0:0: [sdc] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[85421.530556]  sdc: sdc1
[85421.746283] sd 4:0:0:0: [sdc] Attached SCSI disk

7.17.2 USB Host

The TS-4100 provides a standard USB 2.0 host supporting 480Mb/s. Typically this is interfaced with by using standard Linux drivers, but low level USB communication is possible using libusb.

7.18 SPI

The default kernel sets up two SPI controllers. One to the Onboard WIFI, and the other to the FPGA and offboard chip selects. SPI is accessible through either specific kernel drivers, or userspace using the /dev/spi interface. See the kernel compile guide here for more details.

Open the baseboard dts from arch/arm/boot/dts/imx6ul-ts4100-<baseboardid>.dtsi, or the generic imx6ul-ts4100.dtsi. The kernel requires a spidev device be added to the relevant ECSPI controller. For example:

&ecspi3 {
	fsl,spi-num-chipselects = <2>;
	cs-gpios = <&gpio4 12 0>, <&gpio4 10 0>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_ecspi3>;
	status = "okay";
 
	spidevfpga: spi@0 {
		compatible = "spidev";
		reg = <0>;
		spi-max-frequency = <1000000>;
	};
 
	spioffbd: spi@1 {
		compatible = "spidev";
		reg = <1>;
		spi-max-frequency = <1000000>;
	};
};

In this case the two spidev devices are set to 1MHz. To adjust this further you will need to modify the kernel for your device. Linux will create two devices for the above spidev nodes:

  • /dev/spidev2.0 #FPGA
  • /dev/spidev2.1 #offboard

The FPGA SPI is left to custom ZPU code. You can also add additional CPU GPIO to the cs-gpios section to create more chip selects. For further information on the SPI programming see the kernel example code and documentation:

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

I2C 1 is internal to the TS-4100 and connects just to the onboard Silabs supervisory microcontroller at 100khz.

/dev/i2c-0
Address Device
0x4a #Silabs

The second I2C bus is brought out on CN2_28 (SCL) and CN2_30 (SDA). This is shared with the onboard FPGA and it goes offboard. This bus also runs at 400khz by default.

/dev/i2c-2
Address Device
0x28-0x2f #FPGA
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, i2cget, i2cset), or you can write your own client.

7.20 Watchdog

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

7.21 WIFI

This board uses an ATWILC3000-MR110CA IEEE 802.11 b/g/n Link Controller Module With Integrated Bluetooth® 4.0. Linux provides support for this module using the wilc3000 driver.

Summary features:

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

8 External Interfaces

8.1 TS-Socket

The TS-SOCKET macrocontrollers all use two high density 100 pin connectors for power and all I/O. These follow a common pinout for various external interfaces so new modules can be dropped in to lower power consumption or use a more powerful processor. The male connector is on the baseboard, and the female connector is on the macrocontroller. You can find the datasheet for the baseboard's male connector here. This can be ordered from the TS-Socket macrocontroller product page as CN-TSSOCKET-M-10 for a 10 pack, or CN-TSSOCKET-M-100 for 100 pieces.

TS-Socket

In our schematics and our table layout below, we refer to pin 1 from the male connector on the baseboard. For designing a custom carrier board for the TS-4100 we recommend using the TS-8550 as a base: https://www.embeddedarm.com/documentation/ts-8550-schematic.pdf

Example Baseboard TS-4100 TS-Socket

9 Revisions and Changes

9.1 TS-4100 PCB Revisions

TS-4100 PCB Changelog

9.2 U-Boot Changelog

TS-4100 U-boot changelog

9.3 FPGA Changelog

TS-4100 FPGA Changelog

9.4 Software Images

9.4.1 Debian Changelog

TS-4100 Debian Changelog

10 Product Notes

10.1 FCC Advisory

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

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

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

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

10.2 Limited Warranty

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

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

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

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