TS-8150-4600
TS-8150 | |
---|---|
Product Page | |
Product Images | |
Specifications | |
Schematic | |
Mechanical Drawing | |
TS-4600 | |
Product Page | |
Product Images | |
Specifications | |
Schematic | |
Mechanical Drawing | |
FTP Path | |
Processor | |
Freescale i.MX283 | |
454MHz ARMv5TE ARM926EJ-S | |
CPU Datasheet |
Overview
The TS-8150 is a low cost TS-Socket Baseboard in the same form factor as the TS-7260, TS-7800, and TS-8160. This board provides a second Ethernet using the port provided by the System-on-Module's Ethernet switch.
The TS-4600 was released June. 2013. This is a small embedded board with a Freescale i.MX283 454Mhz ARM9 CPU, Lattice XP2 5k FPGA, and 128-256MB DDR2.
Getting Started
A Linux workstation is recommended and assumed for development using this documentation. For users in Windows or OSX, we recommend virtualizing Linux. Most of our platforms run Debian, which is recommended for ease of use if there is no personal distribution preference.
Virtualization
Suggested Linux Distributions
Development using a Windows or OSX system may be possible but is not supported. Development will include accessing drives formatted for Linux and often Linux-based tools.
Booting up the board
WARNING: | Be sure to take appropriate Electrostatic Discharge (ESD) precautions. Disconnect the power source before moving, cabling, or performing any set up procedures. Inappropriate handling may cause damage to the board. |
The TS-8100-4600 accepts 5-28VDC input connected to the two terminal blocks.
While operating the board will typically idle at around 320mA@5V, but this can vary slightly based on your application. For example, every USB device can consume up to 500mA@5V. The ethernet interface can draw around 50mA while the interface is up. Every DIO pin can source up to 12mA from the FPGA. A Sandisk SD card can draw 65mA@3.3V during a write, and larger cards can consume more. A typical power supply will allow approximately 10W, but a larger power supply may be needed depending on your peripherals.
Once you have applied power to your baseboard you should look for console output. The next section of the manual provides information on getting the console connected. The first output is from the bootrom:
>> TS-BOOTROM - built Jan 21 2013 16:17:55 >> Copyright (c) 2012, Technologic Systems . . Uncompressing Linux... done, booting the kernel. Booted in 3.52 s Type 'tshelp' for help #
The "Booting From" message will indicate your boot media. The 2 dots after indicate steps of the booting procedure. The first dot means the MBR was copied into memory and executed. The next dot indicates that the MBR executed and the kernel/initramfs were copied into memory and executed.
Get a Console
Option 1: Telnet
If your system is configured with zeroconf support (Avahi, Bonjour, etc) you can simply connect with:
telnet ts7600-<last 6 characters of the MAC address>.local
# You will need to use your TS-7600 MAC address, but
# for example if you mac is 00:d0:69:01:02:03
telnet ts7600-010203.local
When the board first powers up it has two network interfaces. The first interface eth0 is configured to use IPv4LL, and eth0:0 is configured to use DHCP. The board broadcasts using multicast DNS advertising the _telnet._tcp service. You can use this to query all of the available TS-7600s on the network.
From Linux you can use the avahi commands to query for all telnet devices with:
avahi-browse _telnet._tcp
Which would return:
+ eth0 IPv4 TS-7600 console [4f47a5] Telnet Remote Terminal local + eth0 IPv4 TS-7600 console [4f471a] Telnet Remote Terminal local
This will show you the mac address you can use to resolve the board. In this case you can connect to either ts7600-4f47a5.local or ts7600-4f471a.local
From Windows you can use Bonjour Print Services to get the dns-sd command. OSX also comes preinstalled with the same command. Once this is installed you can run:
dns-sd -B _telnet._tcp
Which will return:
Browsing for _telnet._tcp Timestamp A/R Flags if Domain Service Type Instance Name 10:27:57.078 Add 3 2 local. _telnet._tcp. TS-7600 console [4f47a5] 10:27:57.423 Add 3 2 local. _telnet._tcp. TS-7600 console [4f471a]
This will show you the mac address you can use to resolve the board. In this case you can connect to either ts7600-4f47a5.local or ts7600-4f471a.local
Option 2: Serial Console
The TS-8150 console is an RS232 UART at 115200 baud, 8n1 (8 data bits 1 stop bit), and no flow control. You will need a NULL MODEM cable. On the TS-8150 you need to set the "Console Enable" jumper as pictured:
Note: TS-8100 pictured above, your product may vary slightly in placement and nomenclature.
This will bring the console UART to both the DB9 Port, and the COM1 Header.
Note: | If DIO_9 is held low during boot until the red LED comes on (around 5 seconds), console will be redirected to XUART 0. On the TS-8150 DIO9 is installed as a push switch if the second ethernet is not installed. |
Console from Linux
There are many serial terminal applications for Linux, three common used applications are picocom
, screen
, and minicom
. These examples demonstrate all three applications and assume that the serial device is "/dev/ttyUSB0" which is common for USB adapters. Be sure to replace the serial device string with that of the device on your workstation.
picocom
is a very small and simple client.
sudo picocom -b 115200 /dev/ttyUSB0
screen
is a terminal multiplexer which happens to have serial support.
sudo screen /dev/ttyUSB0 115200
Or a very commonly used client is minicom
which is quite powerful but requires some setup:
sudo 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.
Initramfs
When the unit first boots and is connected to a serial console, the output will look similar to the following:
HTLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFLC >> TS-BOOTROM - built Sep 4 2013 14:49:24 >> Copyright (c) 2013, Technologic Systems LLCLLLLLLLFLCLLJUncompressing Linux... done, booting the kernel. Booted in 3.89s Initramfs Web Interface: http://ts7600-4f3029.local #
Note: | Version dates may be different depending on shiped date and the image used. |
This is a minimalistic initial RAM filesystem that includes our specific utilities for the unit, and is then used to bootstrap the Linux root. The initramfs is built into the kernel image so it cannot be modified without rebuilding the kernel, but it does include 8 bits for common configuration option we call soft jumpers. These soft jumpers are set in non-volatile memory inside of the FPGA and provide persistent bits regardless of the boot media.
Jumper | Function |
1 | Boot automatically to Debian [1] |
2 | Reserved |
3 | Reserved |
4 | Enable AUFS unification on root filesystem[2] |
5 | Reserved |
6 | Reserved |
7 | Boot as fast as possible [3] |
8 | Reserved |
- ↑ initramfs boot is default
- ↑ REQUIRES using the 3.14 kernel and the secondary branch mentioned in the compile instructions.
- ↑ This will skip all setup of networking, baseboard detection and configuration, and is not compatible with DoubleStore boot devices
There are 2 ways to manipulate soft jumpers on the board. The web interface at "http://<model>-<last 6 chars of the MAC>.local" has a list of checkboxes that will immediately change the values. The built-in 'tshwctl' command can also be used for this.
# Boot automatically to Debian:
tshwctl --setjp=1
# Or revert to the initramfs:
tshwctl --removejp=1
If a serial console is not being used, we recommend ensuring Debian's network settings are configured first before booting directly to Debian by setting JP1. Once JP1 is enabled, the initramfs does not run any network configuration utilities and Debian must set the network. See Debian's Configuring the Network section for more information.
For most development, we recommend booting to Debian. This can be accomplished by typing "exit" through the serial or telnet console from the initramfs. As discussed, setting soft jumper JP1 will cause the unit to boot automatically to Debian on future boots. Additionally, many applications are capable of running from the initramfs. The initramfs itself cannot be easily modified, and it is not recommended to do so. The initramfs however has several hooks for applications to use. Debian is mounted at "/mnt/root/" as a read only filesystem which includes the "ts/" directory which offers several hooks and config files. Note that once booted to Debian, these files are available at "/ts/" rather than "/mnt/root/ts/".
/mnt/root/ts/init
For headless applications you can create a bash script with any initialization you require in /ts/init. This does not use the same $PATH as Debian, so you should enter the full path to any applications you intend to run from this environment. The init file does not exist by default and must be created:
#!/bin/sh
/path/to/your/application &
USB update mechanism, tsinit
For implementing a custom production process or applying updates in the field, this SBC is capable of detecting a USB device and running a script. The behavior of this process can be tuned, see the config information section below. There are a few requirements of this script: the USB device itself must be the first or only USB storage device connected, the script must be on the first partition of said USB device and be named "tsinit", and the script must be world executable. PATH is passed to the tsinit script, it is what the initramfs environment PATH is, if additional PATHs are required that can be added in the tsinit script. Standard in/out are the standard console port, this means either the serial debug port, or telnet. Please note that if using telnet, output may be missed as the scripts will not wait for a telnet connection to establish, it is recommended to use a real serial port because of this.
During the USB update process, the first partition of the USB drive is mounted to "/mnt/usbdev/" of the initramfs. Then the update mechanism attempts to execute "/mnt/usbdev/tsinit" and thus launches the script. As stated above, PATH is passed to the script as well as standard in and out (linked to the console port) allowing for printed information in the script to appear on the terminal.
/mnt/root/ts/initramfs-xinit
Graphical applications should use /ts/initramfs-xinit. The xinit file is used to start up a window manager and any applications. The default initramfs-xinit starts a webbrowser viewing localhost:
#!/bin/sh
# Causes .Xauthority and other temp files to be written to /root/ rather than default /
export HOME=/root/
# Disables icewm toolbars
export ICEWM_PRIVCFG=/mnt/root/root/.icewm/
# minimalistic window manager
icewm-lite &
# this loop verifies the window manager has successfully started
while ! xprop -root | grep -q _NET_SUPPORTING_WM_CHECK
do
sleep 0.1
done
# This launches the fullscreen browser. If the xinit script ever closes, x11 will close. This is why the last
# command is the target application which is started with "exec" so it will replace the xinit process id.
exec /usr/bin/fullscreen-webkit http://localhost
/mnt/root/ts/config
This config file can be used to alter many details of the initramfs boot procedure.
## This file is included by the early init system to set various bootup settings. ## if $jp7 is enabled none of these settings will be used. ## Used to control whether the FPGA is reloaded through software. ## 1 to enable reloading (default) ## 0 to disable reloading #CFG_FPGARELOAD="0" ## By default dns-sd is started which advertises the ts<model>-<last 6 of mac> ## telnet and http services using zeroconf. ## 1 to enable dns-sd (default) ## 0 to disable dns-sd #CFG_DNSSD_EN="0" ## This is used to discover hosts and advertise this host over multicast DNS. ## 1 to enable mdns (default) ## 0 to disable mdns #CFG_MDNS_EN="0" ## ifplugd is started in the initramfs to start udhcpc, and receive an ipv4ll ## address. ## 1 to enable ifplugd (default) ## 0 to disable ifplugd #CFG_IFPLUGD_EN="0" ## By default telnet is started on port 2323. ## 1 to enable telnet (default) ## 0 to disable telnet ##CFG_TELNET_EN="0" ## The busybox webserver is used to display a diagnostic web interface that can ## be used for development tasks such as rewriting the SD or uploading new ## software ## 1 to enable (default) ## 0 to disable ##CFG_HTTPD_EN="0" ## This eanbles a reset switch on DIO 29 (TS-7700), or DIO 9 on all of the ## boards. Pull low to reset the board immediately. ## 1 to enable the reset sw (default) ## 0 to disable #CFG_RESETSW_EN="0" ## The console is forwarded through xuartctl which makes the cpu console available ## over telnet or serial console. ## 1 to enable network console (default) ## 0 to disable network console #CFG_NETCONS_EN="0" ## By default Alsa will put the SGTL5000 chip into standby after 5 seconds of ## inactivity. This is desirable in that it results in lower power consumption, ## but it can result in an audible popping noise. This setting prevents ## standby so the pop is never heard. ## 1 to disable standby ## 0 to enable standby (default) #CFG_SGTLNOSTBY="1" ## xuartctl is used to access the FPGA uarts. By default it is configured to ## be IRQ driven which is optimized for best latency, but at the cost of ## additional CPU time. You can reduce this by specifying a polling rate. ## The xuartctl process also binds to all network interfaces which can provide a ## simple network API to access serial ports remotely. You can restrict this to ## the local network with the bind option. ## Configure XUART polling 100hz ## Default is IRQ driven CFG_XUARGS="--irq=100hz" ## Configure xuartctl to bind on localhost ## Default binds on all interfaces #CFG_XUARGS="--bind 127.0.0.1 --irq=100hz" ## For a full list of arguments, see the xuartctl documentation here: ## http://docs.embeddedts.com/wiki/Xuartctl#Usage ## By default the system will probe for up to 10s on USB for a mass storage device ## and mount the first partition. If there is an executable /tsinit script in the ## root this will be executed. This is intended for production or updates. ## 2 to enable USB init always (adds 10s or $CFG_USBTIME to startup) ## 1 to enable USB init when jp1=0 (default) ## 0 to disable USB init always #CFG_USBINIT="2" ## The USB init script by default blocks for 10s to detect a thumb drive that ## contains the tsinit script. Most flash media based drives can be detected ## in 3s or less. Some spinning media drives can take 10s, or potentially longer. ## This options is the number of seconds to wait before giving up on the ## mass storage device. #CFG_USBTIME="3" ### TS-8700 ## Using the TS-8700 baseboard the board will by default initialze all of the ## ethernet ports as individual vlan ports, eg eth0.1, eth0.2, eth0,3, and eth0.4 ## The alterantive option sets Port A to eth0.1, and Ports B-D to eth0.2, or ## you can configure all ethernet ports as a single eth0 port. ## See http://docs.embeddedts.com/wiki/TS-8700 for more information ## 2 disables any vlan and passes through all interfaces to eth0 ## 1 enables "WLAN" mode setting "A" as eth0.1, and all others as eth0.2 ## 0 enables "VLAN" mode for 4 individual ports (default) #CFG_4ETH="1" ### TS-4712 / TS-4720 ## These boards include an onboard switch with 2 external ports. By default ## the switch will detect if it is on a known baseboard that supports the second ## ethernet switch port, and set up VLAN rules to define eth0.1 and eth0.2. The ## other option is to configure the switch to pass through the packets to eth0 ## regarless of port. ## 2 Disable VLAN and pass through to eth0 ## 1 Enable VLAN on all baseboards ## 0 Enable VLAN on supported baseboards (Default) #CFG_2ETH="1"
Debian Configuration
For development, it is recommended to work directly in Debian on the SD card. Debian provides many more packages and a much more familiar environment for users already versed in Debian. Through Debian it is possible to configure the network, use the 'apt-get' suite to manage packages, and perform other configuration tasks. Out of the box the Debian distribution does not have any default username/password set. The account "root" is set up with no password configured. It is possible to log in via the serial console without a password but many services such as ssh will require a password set or will not allow root login at all. It is advised to set a root password and create a user account when the unit is first booted.
Note: | Setting up a password for root is only feasible on the uSD image. |
It is also possible to cross compile applications. Using a Debian host system will allow for installing a cross compiler to build applications. The advantage of using a Debian host system comes from compiling against libraries. Debian cross platform support allows one to install the necessary development libraries on the host, building the application on the host, and simply installing the runtime libraries on the target device. The library versions will be the same and completely compatible with each other. See the respective Debian cross compiling section for more information.
Configuring the Network
This board includes a Marvell switch chip which allows 2 separate networks using the same network interface. See the Ethernet port section for more information on the switch settings. When the switch is configured for 2 separate networks (as it is by default), the eth0 interface should not be directly configured. The switch will provide the eth0.1 and eth0.2 interfaces which can be configured. If the switch is configured to pass through, then the eth0 interface should be used as normal.
The board is initially configured to boot to the initramfs. While in this state ifplugd will automatically assign an IP address, and even if you type "exit" to boot to Debian it will retain the address it was assigned. If you need to boot to the full Debian, networking should first be set up in the /etc/network/interfaces file. As an example, to get dhcp from eth0.1: Open /etc/network/interfaces
# We always want the loopback interface.
auto lo
iface lo inet loopback
auto eth0.1
iface eth0.1 inet dhcp
Once this file is set up, either reboot or "/etc/init.d/networking restart" for this to take effect.
From almost any Linux system you can use "ip" or the ifconfig/route commands to manually set up the network. To configure the network interface manually you can use the same set of commands in the initramfs or Debian.
# NOTE: These are generic examples. Be sure to read the entire networking section before trying any of these.
# Bring up the CPU network interface (for systems with only one Ethernet)
ifconfig eth0 up
# Or if you're on a baseboard with a second ethernet port, you can use that as:
ifconfig eth1 up
# Or if you're on a TS-7250-V2...
ifconfig eth0.1 up
ifconfig eth0.2 up
# Set an ip address (assumes 255.255.255.0 subnet mask)
ifconfig eth0 192.168.0.50
# Set a specific subnet
ifconfig eth0 192.168.0.50 netmask 255.255.0.0
# Configure your route. This is the server that provides your internet connection.
route add default gw 192.168.0.1
# Edit /etc/resolv.conf for your DNS server
echo "nameserver 192.168.0.1" > /etc/resolv.conf
Most commonly networks will offer DHCP which can be set up with one command:
Configure DHCP in Debian:
# To setup the default CPU ethernet port
dhclient eth0
# Or if you're on a baseboard with a second ethernet port, you can use that as:
dhclient eth1
# You can configure all ethernet ports for a dhcp response with
dhclient
Configure DHCP in the initramfs:
udhcpc -i eth0
# Or if you're on a baseboard with a second ethernet port, you can use that as:
udhcpc -i eth1
To make your network settings take effect on startup in Debian, edit /etc/network/interfaces:
# Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or # /usr/share/doc/ifupdown/examples for more information. # We always want the loopback interface. # auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 192.168.0.50 netmask 255.255.255.0 gateway 192.168.0.1 auto eth1 iface eth1 inet dhcp
Note: | During Debian's startup it will assign the interfaces eth0 and eth1 to the detected mac addresses in /etc/udev/rules.d/70-persistent-net.rules. If the system is imaged while this file exists it will assign the new interfaces as eth1 and eth2. This file is generated automatically on startup, and should be removed before your first software image is created. The initrd network configuration does not use this file. |
Note: | The /etc/resolv.conf file is linked to /dev/resolv.conf on purpose so both Debian and the Initramfs can use the same settings file. If configuring a static IP, replace the settings in this file with the appropriate settings for the target network. If configuring Debian to use DHCP, the file will be automatically overridden by the DHCP client, and no action is necessary. |
In this example eth0 is a static configuration and eth1 receives its configuration from the DHCP server. For more information on network configuration in Debian see their documentation here.
Installing New Software
Debian provides the apt-get system which lets you manage pre-built applications. Before you do this you need to update Debian's list of package versions and locations. This assumes you have a valid network connection to the internet.
Note: | The NAND image is based on the emdebian project which is no longer maintained. |
Debian Squeeze has been moved to archive so you will need to update /etc/apt/sources.list to contain only these two lines:
deb http://archive.debian.org/debian squeeze main deb-src http://archive.debian.org/debian squeeze main
apt-get update
For example, lets say you wanted to install openjdk for Java support. You can use the apt-cache command to search the local cache of Debian's packages.
<user>@<hostname>:~# apt-cache search openjdk icedtea-6-jre-cacao - Alternative JVM for OpenJDK, using Cacao icedtea6-plugin - web browser plugin based on OpenJDK and IcedTea to execute Java applets openjdk-6-dbg - Java runtime based on OpenJDK (debugging symbols) openjdk-6-demo - Java runtime based on OpenJDK (demos and examples) openjdk-6-doc - OpenJDK Development Kit (JDK) documentation openjdk-6-jdk - OpenJDK Development Kit (JDK) openjdk-6-jre-headless - OpenJDK Java runtime, using Hotspot Zero (headless) openjdk-6-jre-lib - OpenJDK Java runtime (architecture independent libraries) openjdk-6-jre-zero - Alternative JVM for OpenJDK, using Zero/Shark openjdk-6-jre - OpenJDK Java runtime, using Hotspot Zero openjdk-6-source - OpenJDK Development Kit (JDK) source files openoffice.org - office productivity suite freemind - Java Program for creating and viewing Mindmaps default-jdk-doc - Standard Java or Java compatible Development Kit (documentation) default-jdk - Standard Java or Java compatible Development Kit default-jre-headless - Standard Java or Java compatible Runtime (headless) default-jre - Standard Java or Java compatible Runtime
In this case you will likely want openjdk-6-jre to provide a runtime environment, and possibly openjdk-6-jdk to provide a development environment. You can often find the names of packages from Debian's wiki or from just searching on google as well.
Once you have the package name you can use apt-get to install the package and any dependencies. This assumes you have a network connection to the internet.
apt-get install openjdk-6-jre
# You can also chain packages to be installed
apt-get install openjdk-6-jre nano vim mplayer
For more information on using apt-get refer to Debian's documentation here.
Setting up SSH
On our boards we include the Debian package for openssh-server, but we remove the automatically generated keys for security reasons. To regenerate these keys:
dpkg-reconfigure openssh-server
Make sure your board is configured properly on the network, and set a password for your remote user. SSH will not allow remote connections without a password or a shared key.
Note: | Setting up a password for root is only feasible on the uSD image. |
passwd root
You should now be able to connect from a remote Linux or OSX system using "ssh" or from Windows using a client such as putty.
Note: | If your intended application does not have a DNS source on the target network, it can save login time to add "UseDNS no" in /etc/ssh/sshd_config. |
Starting Automatically
From Debian the most straightforward way to add your application to startup is to create a startup script. This is an example simple startup script that will toggle the red led on during startup, and off during shutdown. In this case I'll name the file customstartup, but you can replace this with your application name as well.
Edit the file /etc/init.d/customstartup to contain this:
#! /bin/sh # /etc/init.d/customstartup case "$1" in start) /path/to/your/application ## If you are launching a daemon or other long running processes ## this should be started with # nohup /usr/local/bin/yourdaemon & ;; stop) # if you have anything that needs to run on shutdown /path/to/your/shutdown/scripts ;; *) echo "Usage: customstartup start|stop" >&2 exit 3 ;; esac exit 0
Note: | The $PATH variable is not set up by default in init scripts so this will either need to be done manually or the full path to your application must be included. |
To make this run during startup and shutdown:
update-rc.d customstartup defaults
To manually start and stop the script:
/etc/init.d/customstartup start
/etc/init.d/customstartup stop
While this is useful for headless applications, if you are using X11 you should modify "/usr/bin/default-x-session":
#!/bin/sh
export HOME=/root/
export ICEWM_PRIVCFG=/mnt/root/root/.icewm/
icewm-lite &
while ! xprop -root | grep -q _NET_SUPPORTING_WM_CHECK
do
sleep 0.1
done
exec /usr/bin/fullscreen-webkit http://127.0.0.1
Replace fullscreen-webkit with your own graphical application.
Backup / Restore
This section has not been written. For immediate assistance, please contact us.
MicroSD Card
This section has not been written. For immediate assistance, please contact us.
SPI Flash
This section has not been written. For immediate assistance, please contact us.
Ethernet
The CPU implements a 10/100 ethernet controller with support built into the Linux kernel. This device also includes an integrated Marvell Ethernet switch that allows multiple interfaces from one 10/100 port. This allows a total bandwidth of 100 MB/s between both ports.
Note: | For the first few seconds after power on, the switched Ethernet ports are in switch mode and will forward STP packets. This can cause some switches to block this Ethernet port before the ports are set up in VLAN mode. Contact us for more details. |
The default configuration will have the ports act as 2 individual ports on baseboards where this is supported. When in this mode all network traffic should be directed to eth0.1
and eth0.2
, but not eth0
which will not be forwarded outside of the switch. When using the network with the VLAN mode, do not make any configuration changes to eth0
, instead only use eth0.1
or eth0.2
. On baseboards where the second Ethernet port supports the VLAN ethernet (see note below), /ts/config
can be modified to enable Switch mode of the two ports allowing them to behave as a layer 2 Ethernet switch transparently.
## These boards include an onboard switch with 2 external ports. By default
## the switch will detect if it is on a known baseboard that supports the second
## ethernet switch port, and set up VLAN rules to define eth0.1 and eth0.2. The
## other option is to configure the switch to pass through the packets to eth0
## regarless of port.
## 2 Disable VLAN and pass through to eth0
## 1 Enable VLAN on all baseboards
## 0 Enable VLAN on supported baseboards (Default)
CFG_2ETH="2"
On the next boot the eth0.1
and eth0.2
ports will not be present but only an eth0
. In this case the switch is configured to transparently pass through packets rather than configuring the VLANs.
Note: | Some baseboards create 2 Ethernet ports using a USB Ethernet device rather than a connection to the switch IC. This means that the second Ethernet port is not connected to the switch IC and these ports can only ever be used as separate interfaces. Products that use USB Ethernet for the second port include the TS-8100, TS-8390, and TS-8900. |
The switch ports can also use tshwctl
to detect link and the negotiated link speed:
root@ts4600-f7c0ff:~# tshwctl --ethinfo baseboard_model=0xa baseboard=8900 baseboard_rev=A switch_model=88E6020 switch_ports=a b switchporta_link=0 switchporta_speed=10HD switchportb_link=1 switchportb_speed=100FD
Software Development
Accessing Hardware Registers
This board implements the NUBS bridge between the CPU and FPGA. The CPU does not implement an SMC bus, because of this the NBUS was created to make an atomic bus using a non-atomic interface. Because it is a non-atomic interface, a locking mechanism using semaphores must be used in order to ensure that two processes do not try to access the NBUS at the same time. When writing applications that communicate over the NBUS you should use the calls in nbus.c and nbus.h. These will compile for c/c++ but if you are using another language such as Java or Python the best implementation is typically to write your hardware accesses in C, and use your languages popen/system() calls to execute the application handling NBUS calls.
All of the registers used in this example code are documented in the Syscon.
Cross Compiling
While it is recommend to develop entirely on the SBC itself, it is also possible to develop from an x86 compatible Linux system using a cross compiler. For this SBC use the cross compiler located here. The resulting binary will be for ARM.
[user@localhost]$ /path/to/arm-fsl-linux-gnueabi/bin/arm-linux-gcc hello.c -o hello
[user@localhost]$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
This is one of the simplest examples. For working with a larger project a Makefile will typically be used. More information about Makefiles is available here. Another common requirement is linking to third party libraries provided by Debian on the SBC. There is no exact set of steps for every project when cross compiling, but the process will be very much the same. Provide the cross compiler with access to the necessary headers, libraries, and source files, and install the binary on the target. The following example will link to sqlite from Debian.
Install the sqlite library and header on the SBC:
apt-get update && apt-get install -y libsqlite3-0 libsqlite-dev
This will fetch the binaries from the internet and install them on the SBC. The installed files can then be listed with dpkg:
dpkg -L libsqlite3-0 libsqlite3-dev
The needed files from this output will be the .h and .so files, they will need to be copied to the project directory on the cross-compling host.
See the example with libsqlite3 below. This is not intended to provide any functionality, but just call functions provided by sqlite.
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"
int main(int argc, char **argv)
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
printf("opening test.db\n");
rc = sqlite3_open("test.db", &db);
if(rc){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
if(rc!=SQLITE_OK){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
}
printf("closing test.db\n");
sqlite3_close(db);
return 0;
}
To build this with the external libraries the makefile below can be used. This will have to be adjusted for the proper toolchain path. In this example, the headers are located in external/include and the library in external/lib.
CC=/opt/arm-2008q3/bin/arm-none-linux-gnueabi-gcc
CFLAGS=-c -Wall
all: sqlitetest
sqlitetest: sqlitetest.o
$(CC) sqlitetest.o external/lib/libsqlite3.so.0 -o sqlitetest
sqlitetest.o: sqlitetest.c
$(CC) $(CFLAGS) sqlitetest.c -Iexternal/include/
clean:
rm -rf *o sqlitetest.o sqlitetest
The resulting binary can be copied to the target and executed. There are many ways to transfer the compiled binaries to the board. Using a network filesystem such as sshfs or NFS will be the simplest to use if needed frequently during development, but will require a setup. See the host linux distribution's manual for more details. The simplest network method is using ssh/sftp. If running Windows, winscp can be used, or just scp in linux. Make sure a password is set for a user account, root or otherwise, in order to properly ssh or scp files to the target. From winscp, enter the ip address of the SBC, the root username, and the password; this will create an explorer window that can use drag-and-drop of files to copy them to the target.
For scp in linux, run:
#replace with the binary name and the SBC IP address
scp sqlitetest root@192.168.0.50:/root/
After transferring the file to the board, execute it:
ts:~# ./sqlitetest
opening test.db
closing test.db
Compile the Kernel
For adding new support to the kernel, or recompiling with more specific options, the kernel can be customized and re-built. An x86 compatible Linux workstation that can handle cross compilation is required. We recommend using a Debian distribution. Compiling the kernel on the device is not supported or recommended. Before building the kernel, the necessary support libraries will need to be installed on the Linux workstation:
Prerequisites
RHEL/Fedora/CentOS:
yum install ncurses-devel ncurses
yum groupinstall "Development Tools" "Development Libraries"
Ubuntu/Debian:
sudo apt-get install build-essential libncurses5-dev libncursesw5-dev git
If using a 64-bit system, then 32-bit compatibility libraries will be required for the toolchain, for newer Debian and Ubuntu distributions with Multiarch support, use the command:
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6-dev:i386 zlib1g-dev:i386
On older distributions:
sudo apt-get install ia32-libs
For other distributions, please refer to their documentation to find equivalent tools.
Download sources and configure
git clone https://github.com/embeddedTS/linux-2.6.35.3-imx28.git
# This sets up the default configuration that we ship with
make ts7600_defconfig
ln -sf initramfs.cpio-ts7600 initramfs.cpio
Once the configuration is loaded, any needed changes can be made to it. A common reason for recompiling is to add support that was not built into the standard image's kernel. An ncurses menu to browse available configuration options can be opened with:
make menuconfig
The "/" key is to search for specific terms through the kernel.
Build the kernel
Once any customization is completed, the kernel can be built. This usually takes about 5-10 minutes depending on workstation CPU speeds:
make
Build bootstream
The i.MX28 utilizes what NXP calls a bootstream
This is a series of bootlets
that are all put together in a binary blob that make up a bootloader for the whole system. The in-CPU ROM bootloader is very small and therefore uses the bootstream
on the boot media to handle further loading. The default bootstream
sets up RAM, power, and contains the kernel to be run. Every time the kernel is built, a new bootstream
must be compiled containing the new kernel image. The following script is used to take the newly built kernel and output a bootstream
for an SPI device as well as an SD card:
./build_bootstream
This will create two files, imx-bootlets-src-10.12.01/imx28_ivt_linux.sb
and imx-bootlets-src-10.12.01/imx28_ivt_linux.spi
. The imx28_ivt_linux.sb
file is the standard image used for the SD card, while the imx28_ivt_linux.spi
is meant to be imaged to the SPI flash device on the TS-7600.
Building External Wireless Modules
In order to support the wide range of USB WiFi modules that Technologic Systems has offered over the years, the compat-wireless
project is used to build all compatible modules. A simple command is used to build them:
./build_wireless
Install the bootstream (kernel/initramfs) and Modules
Next, install the kernel and modules to the SD card. NXP uses a specialized booting mechanism for their processor, so to simplify installation we provide two scripts to handle installation of the kernel+bootstream, kernel modules, headers, and compat-wireless modules.
For example, if your workstation's SD card is /dev/mmcblk0:
./install_bootstream imx-bootlets-src-10.12.01/imx28_ivt_linux.sb mmcblk0 p1
./install_hdr_mod mmcblk0p2
Note: | On newer Linux distributions, the output of 'fdisk' has changed. If the unit fails to boot after a compile, take a look at the output of the './install_bootstream ... ' command. If the line
./install_bootstream: line 122: [: !=: unary operator expected
is printed, then a patch must be applied to address this issue. Use the following command to apply the patch: patch -p1 < install_bootstream-newer-fdisk.patch
|
Install the bootstream (kernel/initramfs) to SPI flash
The ./build_bootstream
command creates the file imx-bootlets-src-10.12.01/imx28_ivt_linux.spi
that can be used to program the SPI flash, see the SPI Flash section for more information. The ./install_hdr_mod
command copies both the SPI bootstream and the stock bootstream to /lib/modules
so they may be used to program SPI devices or NAND.
This bootstream is the exact same kernel/initramfs that is made for the SD card, it has the exact same init script.
Using the Oracle JRE
Oracle provides a headless JRE binary for the ARMv5 processor series which is compatible with this processor. In many cases the OpenJDK JRE is sufficient for an application, but Oracle's JRE provides better performance. To install this JRE, first accept the license and download this from Oracle here.
Your version number may be slightly different, but the process should remain the same:
tar -xf ejre-7u45-fcs-b15-linux-arm-sflt-headless-26_sep_2013.tar.gz
mv ejre1.7.0_45/ /usr/share/oracle-jre/
ln -s /usr/share/oracle-jre/bin/java /usr/bin/java
You can verify this is installed by checking the version:
root@ts:~# java -version java version "1.7.0_45" Java(TM) SE Embedded Runtime Environment (build 1.7.0_45-b15, headless) Java HotSpot(TM) Embedded Client VM (build 24.45-b08, mixed mode)
Features
CPU
This board features the i.MX286 454 MHz ARM9 from NXP. For more information about the processor and it's included peripherals, refer to the CPU manual.
FPGA
The TS-7600 features an FPGA designed to accentuate the i.MX28 CPU peripherals with some additional peripherals and flexibility. The FPGA is connected to the CPU through our NBUS interface, which is a 16-bit data bus interface. There are no 8bit bus cycles to the FPGA.
To access peripherals in the FPGA, use the following base addresses:
Offset | Usage |
---|---|
0x00 | Syscon registers |
0x40 | XUART Interface registers |
0x5c | XUART Memory window interface |
0x60 | SPI interface |
FPGA Bitstreams
The FPGA has the capability to be reloaded on startup and reprogram itself with different configurations. The default bitstream is hardcoded into the FPGA, but the soft reloaded bitstreams can be placed in /ts/ts4600-fpga.vme.bz2 on the linux root to make the board load the bitstream on startup. Pre-built FPGA bitstreams can be found on our FTP site. If we do not have a configuration you need, you can build a new bitstream, or contact us for our engineering services.
Bitstream | XUARTs | SPI | MWIN | MUXBUS | Touchscreen |
---|---|---|---|---|---|
Default | 0-4 | On | On | On | On |
MUXBUS-SPI | 0-5 | On | On | On | Off |
TS-SPI | 0-5 | On | Off | Off | On |
You can update to the latest FPGA by booting to Debian and running:
cd /ts/
wget https://files.embeddedTS.com/ts-socket-macrocontrollers/ts-4600-linux/binaries/ts-bitstreams/ts4600-fpga-latest.vme.bz2
mv ts4600-fpga-latest.vme.bz2 ts4600-fpga.vme.bz2
The FPGA is loaded in to the FPGA SRAM on every poweron, so this file will need to exist for all future boots.
An FPGA revision changelog can be found in the Revisions and Changes section.
FPGA Programming
Note: | We do not provide support for the opencores under our free support, however we do offer custom FPGA programming services. If interested, please contact us. |
The opencore FPGA sources are available here.
We have prepared the opencore projects which gives you the ability to reprogram the FPGA while either preserving or removing our functionality as you choose. The code sources are in verilog, and we use Lattice Diamond to generate the JEDEC file. You can download Lattice Diamond from their site. You can request a free license, and it will run in either Windows or Linux (only Redhat is supported). In the sources you can find the functionality switches in the ts4600_top.v file:
parameter spi_opt = 1'b1;
parameter mwin_opt = 1'b1;
parameter xbus_opt = 1'b1;
parameter touchscreen_opt = 1'b1;
/* software currently requires these to be enabled/disabled contiguously. */
parameter xuart0_opt = 1'b1;
parameter xuart1_opt = 1'b1;
parameter xuart2_opt = 1'b1;
parameter xuart3_opt = 1'b1;
parameter xuart4_opt = 1'b1;
parameter xuart5_opt = 1'b0;
parameter xuart6_opt = 1'b0;
parameter xuart7_opt = 1'b0;
You can use these switches to enable and disable functionality. We do not enable everything at the same time because of space constraints on the FPGA. So for example, to disable SPI, MWIN, and MUXBUS and enable the rest of the XUARTS:
parameter spi_opt = 1'b0;
parameter mwin_opt = 1'b0;
parameter xbus_opt = 1'b0;
parameter touchscreen_opt = 1'b1;
/* software currently requires these to be enabled/disabled contiguously. */
parameter xuart0_opt = 1'b1;
parameter xuart1_opt = 1'b1;
parameter xuart2_opt = 1'b1;
parameter xuart3_opt = 1'b1;
parameter xuart4_opt = 1'b1;
parameter xuart5_opt = 1'b1;
parameter xuart6_opt = 1'b1;
parameter xuart7_opt = 1'b1;
For more advanced changes you may look to opencores.org which has many examples of FPGA cores. To build the FPGA with your new changes, go to the 'Processes' tab and double-click 'JEDEC File'. This will build a jedec file in the project directory. On a linux system, either x86 compatible or ARM, we provide an application called jed2vme.
We also have the sources here.
WARNING: | Do not use the 'jed2vme' provided by Lattice. Their version writes to flash and as the opencores do not contain the bootrom so this will brick your board. |
jed2vme can be used like this:
jed2vme bitstream.jed | bzip2 > bitstream.vme.bz2
To execute this on your board run this:
tshwctl --loadfpga=bitstream.vme.gz
To load this bitstream automatically you can place it in the root of the Debian partition and name it '/ts/ts4600-fpga.vme.bz2'. The initramfs will by default load this bitstream immediately on startup (before the shell starts). You should first test it manually to make sure it loads ok.
The FPGA contains flash memory which contains Technologic System's default FPGA flash load. Using an SRAM bitstream generated by our "jed2vme" with "tshwctl --loadfpga" will not overwrite the flash memory of the FPGA and will only load the SRAM contents of the FPGA, making for an unbrickable system.
NBUS (FPGA to CPU connection)
This CPU uses a NAND bus to access the FPGA registers. Since this is not an atomic access, we have created the NBUS to allow applications to safely share access to FPGA resources.
Example NBUS application
/* When compiling use the following gcc command:
* gcc -oexample example.c nbus.c -mcpu=arm9
*
* nbus.c and nbus.h must be in the same folder where the gcc command is being run from
*/
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include "nbus.h"
int main (int argc, char **argv)
{
uint16_t val;
int i;
nbuslock();
/* Set DIO 7 low
* Set output value to 0
*/
val = nbuspeek16(0xa);
nbuspoke16(0xa, val & ~(1 << 7));
// Set dio 7 direction to output
val = nbuspeek16(0xc);
nbuspoke16(0xc, val | (1 << 7));
/* Set DIO 7 high
* DDR is already set to output, so
* set output value
*/
val = nbuspeek16(0xa);
nbuspoke16(0xa, val | (1 << 7));
// Toggle Red LED 10 times
val = nbuspeek16(0x2);
/* The NBUS lock should be held as little as possible
* since other peripherals will need access. When
* going into an operation like a sleep, a flush, or
* any other syscal that will stall the system without
* actually needing the lock, it should be released first.
*/
nbusunlock();
printf("Starting loop\n");
nbuslock();
for(i = 0; i < 10; i++) {
if(i % 2) {
nbuspoke16(0x2, val & ~(1 << 14));
} else {
nbuspoke16(0x2, val | ( 1 << 14));
}
/* nbuspreempt() can be used to check if there
* are other processes waiting to use the bus. If there
* are, then the bus is unlocked, given to other processes
* and then the bus is re-locked. When nbuspreempt()
* returns the calling process will have the lock again
*/
nbuspreempt();
}
nbusunlock();
return 0;
}
Another NBUS example can be found in dio.c, this also requires the nbus.c and nbus.h files in order to compile.
UARTs
The XUART controller is a core we have included in the FPGA, as well as a userspace application called xuartctl for accessing these UARTs. Rather than using a kernel driver with the standard serial interface, we have implemented the XUARTs with features to simplify application development. The XUARTs allow you to easily use arbitrary baud rates, nonstandard modes such as DMX or 9n1, and they allow a very low latency operation. The XUART layer also uses the very low overhead TCP layer which allows you to transport serial over the network without writing any code.
The simplest example to get started is to define the port with:
xuartctl --server --port=1 --speed=115200
This will return "ttyname=/dev/pts/0", or a higher pts number. You can use this /dev/pts/# device to access the UART, but note that the pts device number can change based on other ssh, telnet or other processes. See this section for a sample script to setup the XUARTs with a predictable device name.
For more information and detailed usage, see the xuartctl page.
Battery Backed RTC and Temperature Sensor
This board includes a temperature compensating RTC which maintains ±5 ppm between 0C to +85C. This is accessed in software using tshwctl. By default, tshwctl will run "tshwctl --getrtc" on startup which will pull system time from the RTC, and set the system time. During the Technologic Systems production process the RTC will be programmed with an accurate time.
If time ever needs to be set you can run:
tshwctl --setrtc
This will take the system time and write it to the RTC. The battery in the RTC will last approximately 10 years for most applications, but the RTC allows you to see when the battery reaches low or critical voltages:
# tshwctl --rtcinfo
rtc_present=1
rtctemp_millicelsius=36000
rtcinfo_oscillator_ok=1
rtcinfo_batt_low=0
rtcinfo_batt_crit=0
rtcinfo_firstpoweroff=0000000000
rtcinfo_lastpoweron=0000000000
rtcinfo_oscillator_ok is true when the RTC is operational and time is being kept
rtcinfo_batt_low is true when the battery is less than 2.805v (85% of 3.3v)
rtcinfo_batt_crit is true when the battery is less than 2.475v (75% of 3.3v)
Note: | While the RTC will remain operational with a battery voltage down to 1.8v, the lithium battery used has a very steep discharge curve. Once the battery reaches critical level it should be replaced. |
rtcinfo_first/lastpoweroff/on are two registers that denote the first time the RTC started using battery power, and the last time power was restored and the RTC stopped using battery power for timekeeping. The output of these registers is in the format MMDDhhmmss. Once `tshwctl --rtcinfo` is called, these registers are cleared and able to be set again. This is a great tool to check if a power off has occurred and how long it lasted.
SD
The i.MX28 SD card controller is used for both SD cards present on the board which supports the SD and SDHC specifications. This controller has been tested with Sandisk Extreme SD cards which allow read speeds up to 20.5MB/s, and write speeds up to 21.5MB/s.
Our default software image contains 2 partitions:
Device | Contents |
---|---|
/dev/mmcblk0 | SD Card block device |
/dev/mmcblk0p1 | Kernel and initramfs |
/dev/mmcblk0p2 | Full Debian linux partition |
Syscon
Offset | Bits | Usage |
---|---|---|
0x0 | 15:0 | Model ID: Reads 0x4600 |
0x2 | 15 | Green LED (1 - on) |
14 | Red LED (1 - on) | |
13-12 | Scratch Reg | |
11 | Reset Switch Enable (1 - reboot when dio9 low) | |
10:9 | Reserved | |
8 | Mode1 Latched value | |
7-4 | Board Submodel (0x0 on production units) | |
3:0 | FPGA revision | |
0x4 | 15:0 | Random data changed every 1 second |
0x6 | 15-5 | Reserved |
4 | Move SPI pins for TS-8280/TS-8290 LCD | |
3 | Lattice tagmem clock | |
2 | Lattice tagmem serial in | |
1 | Lattice tagmem CSn | |
0 | Lattice tagmem serial out | |
0x8 | 15:0 | DIO 15:0 input data |
0xa | 15:0 | DIO 15:0 output data |
0xc | 15:0 | DIO 15:0 data direction (1 - output) |
0xe | 15:0 | DIO 31:16 input data |
0x10 | 15:0 | DIO 31:16 output data |
0x12 | 15:0 | DIO 31:16 data direction (1 - output) |
0x14 | 15:0 | DIO 47:32 input data |
0x16 | 15:0 | DIO 47:32 output data |
0x18 | 15:0 | DIO 47:32 data direction (1 - output) |
0x1a | 15:0 | DIO 63:48 input data |
0x1c | 15:0 | DIO 63:48 output data |
0x1e | 15:0 | DIO 63:48 data direction (1 - output) |
0x20 | 15:6 | Reserved |
5:0 | DIO 69:64 input data | |
0x22 | 15:6 | Reserved |
5:0 | DIO 69:64 output data | |
0x24 | 15:6 | Reserved |
5:0 | DIO 69:64 data direction ( 1 - output) | |
0x26 | 15:0 | EVGPIO DR |
0x28 | 15:0 | EVGPIO DDR |
0x2a | 15:0 | Watchdog Feed Register |
0x2c | 15:0 | MUXBUS Config register |
0x2e | 15:14 | Touchscreen SPI [1] |
13 | SD#1 LED Blink Enable | |
12 | SD#1 LED Enable | |
11 | SD#0 LED Blink Enable | |
10 | SD#0 LED Enable | |
9:8 | #External Clocks [2] | |
7:0 | XUART 7:0 TX Enable |
Watchdog
By default there is a /dev/watchdog with the tshwctl daemon running at the highest possible priority to feed the watchdog. This is a pipe that is created in userspace, so for many applications this may provide enough functionality for the watchdog by verifying that userspace is still executing applications. If you would like to have the watchdog functionality more tightly integrated with your application you can specify various feed options.
At the lower level there are 3 valid watchdog feed values that are written to the watchdog register in the #Syscon:
Value | Result |
---|---|
0 | feed watchdog for another .338s |
1 | feed watchdog for another 2.706s |
2 | feed watchdog for another 10.824s |
3 | disable watchdog |
The watchdog is armed by default for 10s for the operating system to take over, after which the startup scripts autofeed the watchdog with:
echo a2 > /dev/watchdog
The /dev/watchdog fifo accepts 3 types of commands:
Value | Function |
---|---|
f<3 digits> | One time feed for a specified amount of time which uses the 3 digit number / 10. For example, "f456" would feed for 45.6 seconds. |
"0", "1", "2", "3" | One time feed with the value in the above table. |
a<num 0-3> | This value autofeeds with the value in the above table. |
Most applications should use the f<3 digits> option to more tightly integrate this to their application. For example:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
void do_some_work(int data) {
/* The contract for sleep(int n) is that it will sleep for at least n
* seconds, but not less. If other kernel threads or processes require
* more time sleep can take longer, but when your process has a high
* priority this is usually measured in millseconds */
sleep(5);
}
int read_some_io() {
/* If this function (or do_some_work) misbehave and stall thee watchdog
* will not be fed in the main loop and cause a reboot. You can test
* this by uncommenting the next line to force an infinite loop */
// while (1) {}
return 42;
}
int main(int argc, char **argv)
{
int wdfd;
/* In languages other than C/C++ this is still essentially the same, but
* make sure you are opening the watchdog file synchronously so the writes
* happen immediately. Many languages will buffer writes together to make
* them more efficient, but the watchdog needs the writes to be timed
* precisely */
wdfd = open("/dev/watchdog", O_SYNC|O_RDWR);
while (1) {
int data;
/* This loop is expected to take about 5-6 seconds, but to allow some
* headroom for other applications, I will feed the watchdog for 10s. */
write(wdfd, "f100", 4);
data = read_some_io();
do_some_work(data);
}
}
DIO
This board uses both CPU and a DIO controller in the FPGA. The CPU DIO typically have up to 4 functions associated with various pins (I2C, PWM, SPI, etc). See the CPU manual CPU manual for the complete listing and for information on how to control these DIO. This section only lists FPGA DIO.
Bit masking: Any bits not expressly mentioned here should be masked out. Direction setting: 0 is input, 1 is output.
All FPGA DIO are controlled by three distinct register types: Direction, Input Data, and Output Data. To use any DIO pin, the direction register must be set (0 for input, 1 for output), then either the input register may be read, or the output register may be written to. These registers are described in the Syscon memory table.
For example, to write to DIO_0, bit 0 (the LSB) of 0xC (The direction register for DIO_0 through DIO_15) must be set high, then the desired value (high = 1 low = 0) should be written to bit 0 of 0xA (the Output Data register for DIO_0 through DIO_15). Alternatively to read the status of that pin, the Direction Register must be set low, then bit zero of 0x8 would reflect the status of that pin.
The TS-4600 FPGA contains our EVGPIO core, event driven GPIO. This allows for atomic setting of DIO pins (no need to read-modify-write) as well as setting up pins to generate interrupts on state changes. See the EVGPIO and Interrupts sections for more information.
All 69 of the DIO from the FPGA will default to the DIO mode. These pins coming from the FPGA are all 3.3V tolerant. To manipulate these DIO you can access the Syscon, either through tshwctl or a custom application.
DIO Number | Connector Location | Alternate Function |
---|---|---|
0 | CN1_93 | N/A |
1 | CN1_91 | N/A |
2 | CN1_89 | N/A |
3 | CN1_87 | 12.5MHz/14.28MHz clock |
4 | CN1_85 | N/A |
5 | CN1_83 | Board ID |
6 | CN1_81 | ADC_DAT |
7 | CN1_79 | XUART5 TX_EN, ADC_CLK |
8 | CN1_77 | AN_SEL, XUART1 TX_EN |
9 | CN1_73 | External Reset |
10 | CN1_71 | XUART2 TX_EN |
11 | CN1_69 | N/A |
12 | CN1_67 | XUART0 TX_EN |
13 | CN1_65 | XUART3 TX_EN |
14 | CN1_63 | XUART4 TX_EN |
15 | CN2_97 | CAN1_TXD |
16 | CN2_99 | CAN1_RXD |
17 | CN1_97 | BUS_WAIT# |
18 | CN1_99 | BUS_BHE# |
19 | CN1_100 | BUS_CS# |
20 | CN1_98 | BUS_DIR, MODE2 |
21 | CN1_96 | BUS_ALE# |
22 | CN1_94 | MUX_AD_00 |
23 | CN1_92 | MUX_AD_01 |
24 | CN1_90 | MUX_AD_02 |
25 | CN1_88 | MUX_AD_03 |
26 | CN1_86 | MUX_AD_04 |
27 | CN1_84 | MUX_AD_05 |
28 | CN1_82 | MUX_AD_06 |
29 | CN1_80 | MUX_AD_07 |
30 | CN1_78 | MUX_AD_08 |
31 | CN1_76 | MUX_AD_09 |
32 | CN1_74 | MUX_AD_10 |
33 | CN1_72 | MUX_AD_11 |
34 | CN1_70 | MUX_AD_12 |
35 | CN1_68 | MUX_AD_13 |
36 | CN1_66 | MUX_AD_14 |
37 | CN1_64 | MUX_AD_15 |
38 | CN2_72 | N/A |
39 | CN2_70 | N/S |
40 | CN2_68 | N/A |
41 | CN2_66 | XUART0 CTS |
42 | CN2_64 | XUART1 CTS |
43 | CN2_62 | XUART2 CTS |
44 | CN2_60 | XUART3 CTS |
45 | CN2_58 | XUART4 CTS |
46 | CN2_56 | XUART5 CTS |
47 | CN2_52 | N/A |
48 | CN2_32 | N/A |
49 | CN1_61 | N/A |
50 | CN1_59 | N/A |
51 | CN1_60 | N/A |
52 | CN1_58 | N/A |
53 | CN2_78 | XUART0 TXD |
54 | CN2_80 | XUART0 RXD |
55 | CN2_82 | XUART1 TXD |
56 | CN2_84 | XUART1 RXD |
57 | CN2_86 | XUART2 TXD |
58 | CN2_88 | XUART2 RXD |
59 | CN2_90 | XUART3 TXD |
60 | CN2_92 | XUART3 RXD |
61 | CN2_94 | XUART4 TXD |
62 | CN2_96 | XUART4 RXD |
63 | CN2_98 | XUART5 TXD |
64 | CN2_100 | XUART5 RXD |
65 | CN2_67 | SPI_MOSI [1] |
66 | CN2_71 | SPI_CLK [1] |
67 | CN2_69 | SPI_MISO [1] |
68 | CN2_65 | SPI_FRM [1] |
69 | CN1_4 | N/A |
- ↑ 1.0 1.1 1.2 1.3 Note that the DIO and SPI functions cannot be used simultaneously. A bitstream with the SPI core disabled must be soft-reloaded in order to use these pins as DIO. See the FPGA Programming section for more information.
EVGPIO
This board features the EVGPIO core (Event Driven GPIO) which allows a low bandwidth mechanism to monitor all FPGA DIO on a shared interrupt. All DIO are accessed atomically through two registers. The Data/IRQ En. register is used to read DIO state changes, set output values, and enable IRQ on DIO state changes. The Data Direction Register is used to set a DIO to an input or output. The Data/IRQ En. Register will only return data on reads when the IRQ En. bit is set on a DIO Number, a DIO pin has changed state since the IRQ En. was set, and all previous state changes of DIO have been read. The Data Direction Register will never read back anything other than 0x0.
Once the EVGPIO core senses a state change it will wait to be read before updating other pin states. What this means is, DIO_X changes state and the EVGPIO core generates an interrupt; if DIO_Y changes state and then reverts back before the first DIO_X change is read, then the DIO_Y state change is never seen. That being said, if DIO_X changes state, then DIO_Y changes state once, and DIO_X changes back before the first DIO_X state change is read, all three events will be reported by the EVGPIO core. At most, the core will retain two state changes per DIO. Pin states are only updated while the EVGPIO core is idling waiting for a state change, or once a reported state change is read. Once a state change has been read for a particular DIO, then the EVGPIO core can queue up another change. If however a particular DIO cycles multiple times before it is read, the number of times it changed state will be lost and the EVGPIO core will return at most 2 state changes. Because of this it, is beneficial to use the userspace IRQ examples or evgpioctl to watch pin states and read them quickly to an end application. See the Interrupts section for more information on IRQ latency with userspace IRQs and the NBUS.
The EVGPIO data and mask registers can be used directly in your application. Setting a pin direction, output value, and reading input changes are accessed through the EVGPIO data register.
Using Number 0 to 69 will set Value to DIO_Number. Using Number 70 to 127 will set IRQ Enable for DIO_(Number - 70). Note that this scheme will only allow interrupts on DIO 0 to 57. See Interrupts for more information on using these interrupts, and see Syscon for information on where this EVGPIO core is located in address space.
Bits | Description |
---|---|
15:9 | Reserved (Write 0) |
8 | Valid Read Data [1] |
7 | Value |
6:0 | DIO/Mask Number |
- ↑ When writing, write 0. During a read this indicates if this read includes new valid changes. After an interrupt this register should be read until this bit returns 0.
The second register is Data Direction Register. DIO Number is set to an Output when bit 7 is set, and set to an Input when bit7 is cleared.
Bits | Description |
---|---|
15:8 | Reserved (Write 0) |
7 | Output/Input |
6:0 | DIO number |
Random Number Generator
Because many embedded systems do not have much entropy, we have included a core in the FPGA with a random number generator. On startup, tshwctl is called with the --setrng option to seed Linux's random number generator from the hardware random number generator. Without a good source of entropy, Linux's random number generator will start up in a very predictable state which is undesirable for the security of many cryptography protocols.
Interrupts
We include a userspace IRQ patch in our kernels. This allows you to receive interrupts from your applications where you would normally have to write a kernel driver. This works by creating a file for each interrupt in '/proc/irq/<irqnum>/irq'. The new irq file allows you to block on a read on the file until an interrupt fires.
The original patch is documented here.
The Linux kernel supports 3 IRQs from the FPGA. Because of the nature of the NBUS, this requires three separate lines from the FPGA to the CPU. Currently only two IRQs are used from the CPU, one for XUARTS and one for EVGPIO. The third IRQ is not hooked up by default. Any of the IRQs can be repurposed by customization of the FPGA. At any time, the FPGA can toggle the interrupt line, however in order for the kernel to respond to it, the IRQ must be opened first.
CPU IRQ # | Name |
---|---|
155 | XUART IRQ (not used by xuartctl --server by default) |
145 | EVGPIO IRQ |
228 | Unused |
This example below will work with any of our products that support userspace IRQs. It opens the IRQ number specified in the first argument, and prints when it detects an IRQ.
#include <stdio.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char **argv)
{
char proc_irq[32];
int ret, irqfd = 0;
int buf; // Holds irq junk data
fd_set fds;
if(argc < 2) {
printf("Usage: %s <irq number>\n", argv[0]);
return 1;
}
snprintf(proc_irq, sizeof(proc_irq), "/proc/irq/%d/irq", atoi(argv[1]));
irqfd = open(proc_irq, O_RDONLY| O_NONBLOCK, S_IREAD);
if(irqfd == -1) {
printf("Could not open IRQ %s\n", argv[1]);
return 1;
}
while(1) {
FD_SET(irqfd, &fds); //add the fd to the set
// See if the IRQ has any data available to read
ret = select(irqfd + 1, &fds, NULL, NULL, NULL);
if(FD_ISSET(irqfd, &fds))
{
FD_CLR(irqfd, &fds); //Remove the filedes from set
printf("IRQ detected\n");
// Clear the junk data in the IRQ file
read(irqfd, &buf, sizeof(buf));
}
//Sleep, or do any other processing here
usleep(10000);
}
return 0;
}
I2C
A standard two-wire I2C interface is provided on this SBC. The i.MX28 CPU has I2C hardware to communicate with devices on the bus. The hardware is able to be accessed from userspace with the linux i2c-dev interface. On this SBC the I2C pins from the CPU are connected to the on-board RTC, and then brought out to external pins. See the External Interfaces section for the location of these signals.
The RTC on the SBC uses two different addresses, one for the actual RTC registers, the other for the RTC's onboard NVRAM.
Address | Function |
---|---|
0x6F | RTC |
0x57 | NVRAM |
Outside of those addresses, no other I2C addresses are in use on this SBC.
For more information on the i.MX28 I2C implementation, see the CPU manual.
External Reset
Driving the external reset pin (DIO 9) low will reset the CPU by default. You can disable this functionality by running:
tshwctl --resetswitchoff
MUXBUS
The MUXBUS is the bus between the FPGA on the SoM to communicate with the off-board CPLD. The CPLD controls PC/104 access as well as some DIO. The MUXBUS config register in the Syscon allows enabling and configuring the speed for this bus. The MUXBUS timing also influences the communication with PC/104 peripherals.
For more advanced details on the MUXBUS, refer to the implementation details here.
The ts.subr
file in the initramfs defines helper functions to access devices on the MUXBUS (both the baseboard and PC/104 devices). See this file for more details on how accesses are handled.
The MUXBUS can be enabled from the initramfs with the following:
## Fast value (default on TS-8150)
muxbus_enable
PC/104
The TS-8150 supports 21 bits of PC/104 addressing with the standard 8-bit data as well as our 16-bit data implementation inside the single 104 pin header. Most of the embeddedTS' simple I/O based PC/104 devices, in either 8 or 16 bit modes, are supported on this platform. Third party 16-bit devices will not be properly supported. But many simple 8-bit PC/104 devices will work without issue.
The PC/104 address space overlays on top of the whole MUXBUS address space. Because of this, addresses 0x00-0xFF are reserved for accessing the PLD. See the table below:
MUXBUS Address Range | Function |
---|---|
0x00000-0x000FF | TS-8150 register access[1] |
0x00100-0x07FFF | 16-bit PC/104 bus space[2] |
0x10100-0x17FFF | 8-bit PC/104 bus space (mapped down to 0x0100-0x7FFF PC/104 addresses) |
Note that the MUXBUS address space is 15-bit wide (32 KiB) while the TS-8150 PC/104 offers 21 bits of address. Physical PC/104 address bit 16 is used to indicate that an 8-bit PC/104 bus cycle should be emitted. The lower 15-bits of address are put on the bus as requested.
For example, an 8-bit PC/104 device starting at address 0x100 can be read with:
# TS-DIO24 set up at base address 0x100
muxbuspeek8 0x10100
0x54
A 16-bit PC/104 device starting at address 0x120 can be read with:
# TS-ADC16 set up at base address 0x120 AND JP3 for 16-bit special access
muxbuspeek16 0x120
0x553e
Baseboard Register Map
All of these registers are intended for 16-bit access. The MUXBUS configuration register must first be set before accessing this range. For example, to read the board ID:
muxbuspeek16 0x0 # Read Board ID register (0x0)
Offset | Bits | Access | Description |
---|---|---|---|
0x0 | 15:0 | Read Only | Board ID (0x8150) |
0x2 | 3:0 | Read Only | PLD revision |
7:4 | Read/Write | Value to control PWM for LCD contrast | |
8 | Read/Write | TS-8150 USB Reset | |
9 | Read/Write | Controls ISA_RESET on the PC/104 bus | |
10 | Read/Write | Enables a 14.3 MHz clock on the PC/104 bus (B30) and the PLD (default 1) | |
11 | Read/Write | Enables the RS-232 transceiver (default 1) | |
12 | Read/Write | Toggles 5 V to the LCD header pin 1 | |
13 | Read/Write | Enable CAN1 standby | |
14 | Read/Write | Enable CAN2 standby | |
15 | Read/Write | Enables the PWM output for the contrast value | |
0x4 | 1:0 | Read/Write | PC/104 B12:B11 output data |
2 | Read/Write | PC/104 B19 output data | |
15:3 | N/A | Reserved | |
0x6 | 7:0 | Read/Write | LCD pins 14:7 output data |
8 | Read/Write | LCD Header pin 6 output data | |
9 | Read/Write | LCD Header pin 3 output data | |
10 | Read/Write | LCD Header pin 5 output data | |
11 | Read/Write | AVR MOSI | |
12 | Read/Write | AVR SCLK | |
13 | Read/Write | AVR RESET | |
14:15 | N/A | Reserved | |
0x8 | 1:0 | Read/Write | PC/104 B12:B11 data direction |
2 | Read/Write | PC/104 B19 data direction | |
15:3 | N/A | Reserved | |
0xa | 7:0 | Read/Write | LCD pins 14:7 data direction |
8 | Read/Write | LCD Header pin 6 data direction | |
9 | Read/Write | LCD Header pin 3 data direction | |
10 | Read/Write | LCD Header pin 5 data direction | |
15:11 | N/A | Reserved | |
0xc | 1:0 | Read Only | PC/104 B12:B11 input |
2 | Read Only | PC/104 B19 input data | |
15:3 | N/A | Reserved | |
0xe | 7:0 | Read Only | LCD header pins 14-7 input data |
8 | Read Only | LCD Write/Read (pin 6) input data | |
9 | Read Only | LCD Register Select (pin 3) input data | |
10 | Read Only | LCD Enable (pin 5) input data | |
11 | Read/Write | AVR MISO | |
15:12 | N/A | Reserved |
Note: | The registers for controlling the #DIO Header are not used on the TS-8150. On the TS-8150 these are brought from the FPGA on the SoM. Refer to the #DIO Header section for more details. |
External Interfaces
USB Port
The USB is available on two ports as a USB 2.0 host.
|
DIO header
The TS-8100 includes a 2x8 0.1" pitch header with 8 DIO, I2C, and SPI. Most DIO on this header are rated for 3.3 V and are not tolerant of 5 V I/O. The only exception is SPI_MOSI which is 5 V tolerant. The DIO on this baseboard can be accessed via SoM GPIO.
All DIO pins on this header have 3.9 kohm pull up resistors.
Pinout | Header | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
LCD Header
The LCD header is designed around compatibility with our low cost LCD-LED: Alphanumeric 2x24 LCD. These I/O are manipulated through tsctl, or through manipulation of the TS-81xx registers directly. Connector CN8 is a 14 pin (2x7) 0.1" spacing header.
Pinout | Header | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
WARNING: | LCD_D0 thru LCD_D7 are 5V tolerant. LCD_WR#, LCD_RS, and LCD_EN are not. |
Power to the LCD header can be toggled by manipulating LCD Enable in the #Register Map. The LCD_5V pin can provide up to 1400mA, but this is a shared 5V rail and will depend on your power supply and what other devices are using that rail.
PC104 Header
See the #MUXBUS section for more details on working with the MUXBUS peripherals.
The PC/104 connector consists of two rows of pins labeled A and B, the numbering of of which is shown below. The signals for the PC/104 are generated by the MAX240 PLD located on the baseboard. It converts the MUXBUS signals from the dual 100-pin System-on-Module (SoM) interface bus. Pin A1 is nearest to the SoM mounting hole.
Any of the IO on this board labelled DIO_ can be controlled through tsctl as PC104_A/B<pin>, or through manipulation of the registers directly.
# Start tsctl server if it is not already running.
# This only needs to be done once
tsctl --server &
# Lookup the logical DIO mapping of the PC104 header pin A16
eval `tsctl 127.0.0.1 System MapLookup PC104_A16`
# If you run this outside of the eval it will return:
# PC104_A16=138
# Toggle the DIO high and low:
tsctl 127.0.0.1 DIO Set $PC104_A16 high
tsctl 127.0.0.1 DIO Set $PC104_A16 low
You can also drive these DIO to manually manipulate the PC/104 address to make peripherals usable that require a higher range of address than provided by the default address space of the MUXBUS.
WARNING: | Most of the pins on the PC/104 bus are only 3.3 V tolerant. Refer to the schematic for more details. |
Product Notes
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.
Limited Warranty
See our Terms and Conditions for more details.