TS-4200

From embeddedTS Manuals
Revision as of 18:12, 11 February 2022 by Lionel (talk | contribs) (Add Arm trademarks and usage notice)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
TS-4200
ts-4200.gif
Product Page
Product Images
Specifications
Documentation
Schematic
Mechanical Drawing
FTP Path
Processor
Atmel at91sam9g20
400MHz Arm®v5TEJ Arm926
(Arm9™-compatible)
CPU Datasheet
CPU Manual
CPU Technical Reference Manual

Overview

The TS-4200 is a high performance low power 400MHz Atmel AT91SAM9G20 ARM9 with 128MB RAM.

Getting Started

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

  • Linux filesystems on the microSD card can be accessed on the PC.
  • More ARM cross-compilers are available.
  • If recovery is needed, a bootable medium can be written.
  • A network filesystem can be served.
  • Builds such as Linux kernel, buildroot, yocto, distro-seed will not work from WSL1/2 on a case insensitive filesystem.
WARNING: Be sure to take appropriate Electrostatic Discharge (ESD) precautions. Disconnect the power source before moving, cabling, or performing any set up procedures. Inappropriate handling may cause damage to the board.

The TS-4200 receives power through several pins on the socket connector. Refer to your baseboard documentation or schematics for locating the power in on your board.

Development Kit and Accessories

The KIT-4200 includes the items that are commonly necessary for development with the TS-4200.

KIT-4200 Contents
Item Description
TS-8200 The TS-8200 is a baseboard that brings out RS232, RS485, CAN, Ethernet, USB, and provides a switching regulator that can accept 5-12V.
TS-ENC820 This enclosure measures 139.88mm (5.507 in.) W x 102.02mm (4.016 in.) D x 35.06mm (1.380 in.) H. The end-plate brings out 1x 10/100 Ethernet port, 1x USB Host port, 1 USB Device port, 2 user controlled red and green LEDs, multipurpose reset/script button, power input and COM port. The power source is either 5-12V DC through a commercial-grade barrel connector on the front of the unit or USB cable via USB Device port.
MSD-2GB-USB-4200 A Sandisk MicroSD card with a Vivitar SD reader. We recommend Sandisk SD cards as that is what we use for testing. Whenever we receive batches of SD cards from our suppliers, we will pull a few cards for testing to ensure they behave within our expectations. The Vivitar reader is also recommended because it was tested to work with the most SD cards, and it does not have a potentially damaging voltage drop that many consumer SD readers have.
CB-DB9Y The CB-DB9Y is a splitter cable used to bring out multiple uarts on the same header.
CB7-05 The CB7-05 is a 5 foot null modem cable. This is commonly used to connect to your workstation.
CB-USB-AMBM This is a USB A male to USB B male which is commonly used to connect the board to your PC as a USB device. This is also used for connecting the TS-9449 to your workstation for a USB to serial console.
CB-USB-AF5P The CB-USB-AF5P connects from a standard 5 pin 0.1" pitch header to a USB A host. This can be used to expose a single USB port while keeping the rest internal to your own enclosure.
PS-5VDC-REG-1AMP-BC This is a 5V 1A DC power supply on a center pin positive barrel connector. Optionally type I or C adapters are available and will ship with the product if ordered to a country where this specific adapter is required. If you require one of these adapters it is recommended to put this in the comments for your order.

The other options include:

Item Description
CN-TSSOCKET-M The CN-TSSOCKET-M is the male connector which can be used for custom baseboard development. 2 Connectors are needed for each custom baseboard.
WIFI-N-USB The WIFI-N-USB is an ASUS 802.11N adapter. See the WIFI-N-USB page for more details.

Get a Console

Console on the TS-4200 will by default come out of the CPU UART (ttyS0). The console will use 8n1, no flow control, and a 115200 baud rate. You can also telnet to the board with the default network configuration, though this will omit the bootrom messages which can be helpful for diagnostics.

Use a null modem cable to connect the ARM system to your workstation. If you do not have a COM port on your system (as many newer systems do not), you can find a USB serial adapter that will bring out RS232.

Console from Linux

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

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

Picocom is a very small and simple client.

picocom -b 115200 /dev/ttyUSB0

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

screen /dev/ttyUSB0 115200

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

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

Console from Windows

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

Device Manager Putty Configuration

Initrd / Busybox

When the board first boots you should see output similar to this:

 >> TS-BOOTROM - built Mar  9 2011 09:59:23
 >> Copyright (c) 2011, Technologic Systems
 >> Booting from SD card...
 .
 .
 .
 Uncompressing Linux... done, booting the kernel.
 >> Booted from: SD card                 Booted in: 1.40 seconds
 >> SBC Model number: TS-4200            SBC Sub-model number: 0
 >> CPU clock rate: 396 MHz              RAM size: 128MB
 >> NAND Flash size: 256MB               NAND Flash Type: 0xdc20 (STMicro)
 >> MAC number: 00:D0:69:44:3E:9B        SBC FPGA Version: 4
 >> Temperature Sensor: 31.500 degC      MODE1 bootstrap: OFF
 >> RTC present: YES                     Date and Time: Jan  1 2001 00:01:49
 >> Base board type: TS-8200/Unknown     Base board FPGA Version: not present
 >> MODE2 bootstrap: ON                  SD card size: 1886MB
 >> Offboard SPI flash type: not present Offboard SPI flash size: not present
 >> XUARTs detected: 0                   CAN present: NO
 >> Linux kernel version: 2.6.36.2       Linux kernel date: Oct 7 2011
 >> Bootrom date: unknown                INITRD date: Oct  7 2011
 >> ts4200ctl date: Sep 27 2011          sdctl date: not present
 >> canctl date: not present             nandctl date: Sep 26 2011
 >> spiflashctl date: not present        xuartctl date: not present
 >> dioctl date: not present             spictl date: not present
 >> dmxctl date: not present             busybox date: Sep 26 2011 (v1.18.3)
 >> ts4200.subr date: Sep 29 2011        daqctl date: not present
 >> linuxrc date: Sep 27 2011            rootfs date: Oct  7 2011
 >> MBR date: Sept 20 2011
 
 Type 'tshelp' for help
 # 

This is a busybox shell which presents you with a very minimalistic system. This filesystem is loaded into memory, so none of the changes will be saved unless you type the command

save

or mount a filesystem as read/write. This can also provide a simple mechanism for running your application in an entirely read-only environment. The linuxrc script will be the first thing executed as soon as the kernel is loaded. This sets the default IP address, starts the userspace ctl applications, and more. Read the linuxrc for more information.

While busybox itself doesn't contain much functionality, it does mount the Debian partition under /mnt/root/. It will also add common paths and load libraries from the Debian system. Many of the Debian applications will work by default. Whether or not a Debian application will work in fastboot needs to be judged per application. If an application relies on certain paths being in certain places, or running services, you should instead boot to Debian to run them.

This shell when started on the COM port is what is blocking a Debian boot. If you close it by typing

exit

the boot process will continue. If you are connected through telnet, this will instead open up its own instance of the shell so typing

exit

will only end that session. Through any connection method you can relink the linuxrc to change it to boot by default to Debian.

The initrd has these boot scripts available:

Script Function
linuxrc-fastboot (default) Boots immediately to a shell in ramdisk. This will mount whichever boot medium you have selected to /mnt/root/. When you type 'exit', it will boot to that medium.
linuxrc-nandmount Same as the linuxrc-fastboot script, but will mount and boot the debian partition from NAND.
linuxrc-sdmount Same as the linuxrc-fastboot script, but will mount and boot the debian partition from SD.
linuxrc-sdroot Boots immediately to the Debian stored on either SD or NAND depending on which device you have currently selected.
linuxrc-sdroot-readonly Same as linuxrc-sdroot, except it will mount the Debian partition read only while creating a unionfs with a ramdisk. Changes will only happen in memory and not on disk.
linuxrc-usbroot Mounts the first partition of the first detected USB mass storage device and boots there.
Note: Keep in mind the boot medium is selected by the pinout on your baseboard, not through software.

For example, to set the linuxrc to boot immediately to Debian on the SD you would run this:

rm linuxrc; ln -s /linuxrc-sdroot /linuxrc; save

The small default initrd is only 2Mbyte but there is space for approximately 300 Kbyte of additional user applications. The binaries on the initrd are dynamically linked against embedded Linux's "uclibc" library instead of the more common Linux C library "glibc". "uclibc" is a smaller version of the standard C library optimized for embedded systems and requires a different set of GCC compiler tools which are available here.

The compiled instance of busybox includes several internal commands listed below:

 BusyBox v1.18.3 (2011-09-22 17:52:49 MST) multi-call binary.
 Copyright (C) 1998-2009 Erik Andersen, Rob Landley, Denys Vlasenko
 and others. Licensed under GPLv2.
 See source distribution for full notice.
 
 Usage: busybox [function] [arguments]...
    or: busybox --list[-full]
    or: function [arguments]...
 
 	BusyBox is a multi-call binary that combines many common Unix
 	utilities into a single executable.  Most people will create a
 	link to busybox for each function they wish to use and BusyBox
 	will act like whatever it was invoked as.
 
 Currently defined functions:
 	[, [[, ar, ash, basename, cat, chat, chgrp, chmod, chown, chroot, chrt,
 	cmp, cp, cpio, cttyhack, cut, date, dc, dd, depmod, devmem, df,
 	dirname, dmesg, dnsdomainname, du, echo, egrep, env, expr, false,
 	fdisk, fgrep, find, free, grep, gunzip, gzip, halt, head, hostname,
 	hush, hwclock, ifconfig, insmod, ipcrm, ipcs, kill, killall, ln, login,
 	ls, lsmod, lsusb, md5sum, mdev, microcom, mkdir, mkfifo, mknod,
 	modinfo, modprobe, more, mount, mv, netstat, nohup, ping, pivot_root,
 	poweroff, printf, ps, pwd, rdate, reboot, rm, rmdir, rmmod, route, rx,
 	sed, seq, setconsole, setsid, sh, sha1sum, sha256sum, sha512sum, sleep,
 	stty, sync, sysctl, tail, tar, tee, telnetd, test, tftp, time, top,
 	touch, tr, true, udhcpc, umount, uname, unxz, unzip, uptime, usleep,
 	uudecode, uuencode, vi, watch, wget, xargs, xz, xzcat, yes, zcat


Also on the initrd are the TS specific applications: nandctl and ts4200ctl. We also provide the ts4200.subr which provides the following functions:

 eth_off()
 eth_on()
 attime()
 usb_off()
 usb_on()
 usbload()
 sdload()
 nandsave()
 sdsave()
 save()
 sd2nand()
 nand2sd()
 setdiopin()
 getdiopin()
 getadc()
 pc104on()
 pc104off()
 setupclk()
 tshelp()

By default, linuxrc will not insert the necessary modules into the kernel to mount and use USB devices within the initrd/busybox environment if there is no USB device present upon bootup (USB support is enabled by default within the Debian environment). The quickest way to get a USB device (like a USB thumb drive) to mount in the initrd/busybox environment is to ensure that it is plugged in before the SBC is powered up. In order to get hot-swappable USB devices regardless of device presence at bootup time, you must "modprobe" the necessary modules. This has been done for you in the ts4200.subr file with the usbload() function.

Getting Started with tsctl

First, download and install the latest version of tsctl as documented in the Getting Started Guide.

In the examples below you can follow along by typing the commands (the portion after the prompt) and expect to see the output below the prompt. Note that while the results should be similar, in some cases you might not see exactly the same results due to variations in execution.

Let's start the tsctl shell:

$ tsctl
tsctl 0.93-ts (Dec  7 2012 15:34:29)
Type "?" to get context-sensitive help.
tsctl>

Let's check that we really have a TS-4200.

tsctl> System ModelId
16896
tsctl>

That doesn't look like 4200! The reason is that the ModelId (and BaseBoardId) commands return 0x4200 (hexadecimal 4200), but the tsctl shell defaults to decimal output. (Note that the command line defaults to hexadecimal!)

We can change to hexadecimal output using the mode command. There is no output from this command.

tsctl> Mode Hex
tsctl>

Now let's try again.

tsctl> System ModelId
0x00004200
tsctl>

In addition to the base the output is represented in, you can also change the general format. The tsctl shell defaults to "NoAssign" mode in which only the input or inputs are printed, each on a separate line. The "Assign" mode (which is the default for the command line) prints a descriptive name=value pair for each value output.

tsctl> Mode Assign
tsctl>

Now let's re-run the previous command. If your version of tsctl is linked against libreadline, you can use the up-arrow twice to pull the System ModelId command back instead of typing it out.

tsctl> System ModelId
System_ModelId_0=0x00004200
tsctl>

Let's run the command again.

tsctl> System ModelId
System_ModelId_1=0x00004200
tsctl>

Notice that the name changed slightly. The first part of the name is the class, the second it the field name (which is also the function name in cases where the value is directly returned at the C API level), and the third is a number. This number is the index of the number of times this class function has been called during the current invocation of tsctl.

Let's switch back to NoAssign mode. Although the field names can be useful if you aren't familiar with what the output fields mean, mostly Assign mode is meant for evaluating by the shell to set variables.

tsctl> Mode NoAssign
tsctl>

Now let's see what base board we have. Your output will differ depending on what you actually have installed.

tsctl> System BaseBoardId
0x00008200
tsctl>

Let's switch back to decimal output.

tsctl> Mode Dec
tsctl>

Now, let's enter the System class onto the command stack so that we don't have to type it repeatedly.

tsctl> System
tsctl System>

Note that our first command, "System" was incomplete, which caused tsctl to push it onto the command stack. This can be used to reduce typing when repetitive sequences start with the same partial command. To pop an element off the stack in the shell, enter an empty line.

One feature of libtsctl is the System Map, which contains name/value pairs. The name is any string (8-bit Array) and the value is an integer. First, let's see how many entries are stored in the table.

tsctl System> MapLength
458
tsctl System>

The entries in the table are stored sorted by name (case-insensitively). Entries are used to store DIO names, enumerated values, attributes, and user-defined name/value pairs. If you want to see the entire table you can get each entry one at a time by index number, starting at 1:

tsctl System> MapGet 1
AIO_ADC
1
tsctl System>

The first line contains the name, while the second contains the value.

To get several entries at once let's first put the function name on the command stack

tsctl System> MapGet
tsctl System MapGet>

One feature of tsctl is the ability to separate commands by a semi-colon. In the shell (e.g. bash) this requires quoting the semi-colon; in the tsctl shell it does not. Let's get the next ten entries:

tsctl System MapGet> 2;3;4;5;6;7;8;9;10;11
AIO_DAC
2
attrib.8200.Wire.Connector.1.0
1
attrib.8200.Wire.Connector.1.1
1
attrib.8200.Wire.Connector.10.0
2
attrib.8200.Wire.Connector.12.0
2
attrib.8200.Wire.Connector.12.1
2
attrib.8200.Wire.Connector.13.0
2
attrib.8200.Wire.Connector.13.1
2
attrib.8200.Wire.Connector.14.0
2
attrib.8200.Wire.Connector.15.0
2
tsctl System MapGet>

What happened here is that each number got appended as the parameter to the System MapGet function.

Hit enter on an empty line to pop the MapGet function off the command stack.

tsctl System MapGet> 
tsctl System>

Let's look at some of the attributes available. We can find the name of a connector by number as follows:

tsctl System> MapLookupPartial attrib.Connector.Name. 2
CN2_
tsctl System>

How many connectors are there?

tsctl System> MapLookup attrib.Connector.Count
2
tsctl System>

Depending on your system, you may have more than this! How many pins does connector 1 have?

tsctl System> MapLookup attrib.Connector.1.Pins
100
tsctl System>

Most boards have a green and red LEDs, but the DIO number differs from board to board. Let's see what DIO numbers they are on this board. If the lookup fails, a negative value will be returned.

tsctl System> MapLookup;GREEN_LED;RED_LED;;
128
129
tsctl System>

Note that we used two semi-colons with nothing between them to pop the MapLookup function back off the stack.

What connector is the GREEN_LED on? We can determine this by searching the connector attribute for a value corresponding to the DIO number of GREEN_LED. In the above case, that value is 128. However we can also use GREEN_LED, as the tsctl text interface will automatically translate it to the correct value:

tsctl System> MapLookupPartial attrib.Connector. GREEN_LED
2.8
tsctl System>

Note that in a few rare cases the above lookup will conflict with another attribute and may not work. This is because MapLookupPartial looks for a name starting with the specified string, having the specified value. If we specified a value of "100" we might match "attrib.Connector.1.Pins", "attrib.Connector.2.Pins", or "attrib.Connector.1.8" as these all have a value of 100.

The interpretation of 2.8 is "Connector 2, Pin 8". This is also known as "CN2_8", by combining the name of the connector with the pin number on that connector.

tsctl System> MapLookup CN2_8
128
tsctl System>

NOTE: For widest cross-platform compatibility it is recommended to perform lookups based on connectors, rather than board specific DIO names.

How many DIO are on the board?

tsctl System> MapLookup attrib.DIO.Count
130
tsctl System>

If you have a peripheral board such as a baseboard or PC-104 board with supported DIO, you will see a higher number than this. Note that this number counts all raw, internally addressable DIO, regardless of whether or not they are brought out to pins. As such the actual number of usable DIO will frequently be lower than the number contained in this attribute.

Let's pop the System class from the command stack.

tsctl System> 
tsctl>

What revision of the FPGA is on the board?

tsctl> System FPGARevision
4
tsctl>

We can read the I2C (TWI) temp sensor on the TS-4200 with tsctl. First let's switch to hexadecimal output for Arrays of bytes.

tsctl> Mode AHex
tsctl>

Next, we need to make sure that the pins that are used for TWI are correctly set up, as they are frequently multi-function pins. The easiest way to make sure the pins are set correctly is to lock the function you are going to use. As part of locking the pin will be initialized to the correct function. For some boards (notably the TS-4800) the TWI must always be locked during use as it uses an underlying operating system file to perform its functionaity.

tsctl> TWI Lock 0 0
1
tsctl>

Now verify that the temperature sensor is present at device address 0x49.

tsctl> TWI Read 0x49 1 7 2
TWISuccess
0x01:0x90
tsctl>

If the bytes read back are not 0x01:0x90 (the first value returned is the result code), then the temperature sensor is not present, or there is another problem with the TWI bus. Assuming we get the correct response back, we can next send the commands to start an aquisition, and read back the raw temperature data from the sensor.

tsctl> TWI Write;0x49 1 1 0x40:0x0;0x49 0 0 0x40:0x0;;Read 0x49 1 0 2;;
TWISuccess
TWISuccess
TWISuccess
0x12:0x60
tsctl>


The value returned can be converted to a temperature as follows:

tempC = (byte[0] * 256 + byte[1]) / 128
tempC = (0x12 * 256 + 0x60) / 128
tempC = 36.75C

Note: The ts8160ctl sample application provides the above TWI temp sensor reading functionality using the -t option.

Be sure to unlock any resource when you are done. Best practice is to hold a lock for the minimum amount of time necessary.

tsctl> TWI Unlock 0 0
1
tsctl>

There are also several timing based functions you can use. For instance, you can delay for a specific amount of time. You should see a delay of approximately 1 second (1,000,000 microseconds) when running the command below:

tsctl> Time;Delay 1000000
tsctl Time>

Note that the Delay function does not return a value. If you want to see the actual number of microseconds delayed, use the Wait function instead:

tsctl Time> Wait 1000000;;
1011557
tsctl>

The only difference between Wait and Delay is that the former returns the number of microseconds actually spend waiting, and the latter returns no value. This is an important nuance in the TCP classes, as in certain modes functions that return no data are not called until subsequent functions that do return data are called. This allows for things such as commanding a relay to cycle power on the board issuing the command (so long as it isn't the board interpreting the command), since otherwise the command to restore power would not be sent before power was cut.

Short delay times are generally only useful when using direct access from C. Otherwise, the overhead of parsing the command, sending it across TCP, and interpreting it on the server will be significant in comparison to the amount of time to delay.

Boot Process

For most applications knowledge of this process is unnecessary. Our images already account for this bootloader, but the important part to note is that the XNAND and SD boot processes are independent of each other.

The TS-BOOTROM consists of two parts, the code in the FPGA which does low level initialization of the CPU and MMU. It reads the first 512 bytes of the SD card or XNAND depending on your boot jumpers or MODE pins, and jumps execution to the binary there. The code in the MBR looks at the partition table for the first partition of type 0xda, and loads this to memory 0x20008000. The second partition of type 0xda is loaded into memory at 0x21000000. This also sets up the ATAGS which are used by the kernel to identify the hardware, and so it knows where to load the initrd. After that it jumps into execution at 0x20008000 to the kernel. The kernel will recognize the ATAGS (which are in a standard location for ARM at 0x100) and it will see the initrd as /dev/ram0. If you look at the default kernel config, we define the cmdline as: "root=/dev/ram0 rw init=/linuxrc lpj=498688 console=null". This is how it gets the initrd loaded and executes the linuxrc script.


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

From almost any Linux system you can use "ip" or the ifconfig/route commands to initially set up the network. To configure the network interface manually you can use the same set of commands in the initrd or Debian.

# Bring up the CPU network interface
ifconfig eth0 up

# Or if you're on a baseboard with a second ethernet port, you can use that as:
ifconfig eth1 up

# Set an ip address (assumes 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 initrd:

udhcpc -i eth0
# Or if you're on a baseboard with a second ethernet port, you can use that as:
udhcpc -i eth1

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

 # Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or 
 # /usr/share/doc/ifupdown/examples for more information.          
                                                                   
 # We always want the loopback interface.                          
 #
 auto lo
 iface lo inet loopback
 
 auto eth0
 iface eth0 inet static
   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.

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.

To make your changes permanent in the initrd you will need to edit the linuxrc script. Use the same commands you would use to manually configure it and place them over the current ifconfig calls.

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.

Installing New Software on NAND

Debian on NAND is based on Emdebian Squeeze, which has been discontinued. No known mirrors exist to be able to install new applications. What follows is the last known information: The file /etc/apt/sources.list.d/multistrap-grip.list needs to be updated to contain only the following two lines:

  deb http://emdebian.bytesatwork.ch/mirror/grip/ squeeze main
  deb-src http://emdebian.bytesatwork.ch/mirror/grip/ squeeze main
apt-get update

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)
     /sbin/ts4700ctl --redledon
     ## If you are launching a daemon or other long running processes
     ## this should be started with
     # nohup /usr/local/bin/yourdaemon &
     ;;
   stop)
     /sbin/ts4700ctl --redledoff
     ;;
   *)
     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

To make your application startup from the initrd you only need to add this from the linuxrc script. Usually the best place to add in your application is right after /mnt/root/ is mounted so the Debian libraries and applications are available.

Backup / Restore

If you are using a Windows workstation there is no support for writing directly to block devices. However, as long as one of your booting methods still can boot a kernel and the initrd you can rewrite everything by using a usb drive. This is also a good way to blast many stock boards when moving your product into production. You can find more information about this method with an example script here.

Note: Note that the MBR installed by default on this board contains a 446 byte bootloader program that loads the initial power-on kernel and initrd from the first and second partitions. Replacing it with an MBR found on a PC would not work as a PC MBR contains an x86 code bootup program.

MicroSD Card

If backing up on a separate workstation, keep in mind windows does not have direct block device support needed to write these images. You will also need to determine the SD card device. You can usually find this in the output of 'dmesg' after inserting the SD card and you will typically see something like '/dev/sdb' as the block device and '/dev/sdb1' for the first partition. On some newer kernels you will see '/dev/mmcblk0' as the block device and '/dev/mmcblkop1' for the first partition. For these examples I will use the '/dev/mmcblk0' format.

If you are backing up directly on the board you will likely need to use some kind of offboard storage like a thumbdrive or external hard drive. Make sure you have any nbd devices unmounted before trying to restore new ones.

You can find the latest SD card image here. Make sure you decompress the image first before writing.

Note: Not all SD cards are created equally, over time they tend to shrink in size due to automatic retiring of bad blocks. All of Technologic System's images are 10% smaller than the target disc size. We STRONGLY recommend following that same practice on any mass-replicated images.

From Workstation


Backup

Entire SD card

dd if=/dev/mmcblk0 of=/path/to/backup.dd bs=32k && sync && sync
Note: Not all SD cards are created equally, over time they tend to shrink in size due to automatic retiring of bad blocks. All of Technologic System's images are 10% smaller than the target disc size. We STRONGLY recommend following that same practice on any mass-replicated images.

Kernel

dd if=/dev/mmcblk0p2 of=/path/to/zImage bs=32k && sync && sync

Initrd

dd if=/dev/mmcblk0p3 of=/path/to/initrd bs=32k && sync && sync

Restore

Entire SD card

dd if=/path/to/backup.dd of=/dev/mmcblk0 bs=32k && sync && sync

Kernel

dd if=/path/to/zImage bs=32k of=/dev/mmcblk0p2 && sync && sync

Initrd

dd if=/initrd bs=32k of=/dev/mmcblk0p3 && sync && sync

From SBC


Backup

Entire card

dd if=/dev/mmcblk0 of=/path/to/backup.dd && sync && sync

Kernel

dd if=/dev/mmcblk0p2 of=/path/to/backup.dd && sync && sync

Initrd

dd if=/dev/mmcblk0p3 of=/path/to/backup.dd && sync && sync

Restore

The entire card from SBC

dd if=/path/to/2gbsd-4200-latest.dd of=/dev/mmcblk0 && sync && sync

Kernel

dd if=/mnt/root/zImage of=/dev/mmcblk0p2 && sync && sync

Initrd

dd if=/mnt/root/initrd of=/dev/mmcblk0p3 && sync && sync

Expected Partition Layout

Partition Contents
1 FAT32 (empty)
2 kernel binary (0xda)
3 initrd (0xda)
4 Debian root filesystem (EXT3)

XNAND

This needs to be done directly on the SBC. Please note that all NBD partitions from the NAND card must be dismounted before attempting to image the NAND on the SBC.

WARNING: It is not safe to run multiple instances of the 'nandctl' application on this platform. Be sure that all NAND filesystems are unmounted before reading/writing them with the instructions below. The following examples use 'dd' on devices nodes, this operation is safe while 'nandctl' is running, and is the preferred method.

You can find the latest xnand image here.

Backup

Entire Image

# Compressed
dd if=/dev/nbd0 bs=131072 count=2048 | bzip2 > backup.dd.bz2
# or uncompressed
dd if=/dev/nbd0 bs=131072 count=2048 of=backup.dd

Kernel

dd if=/dev/nbd1 bs=512 count=5119 of=/path/to/backup/zImage

Initrd

dd if=/dev/nbd2 bs=512 count=5120 of=/path/to/backup/initrd

Restore

Entire Image

dd if=xnand-4200-latest.dd bs=131072 count=2048 of=/dev/nbd0 conv=fsync

Kernel

dd of=/dev/nbd1 bs=512 count=5119 if=/path/to/backup/zImage conv=fsync

Initrd

dd of=/dev/nbd2 bs=512 count=5120 if=/path/to/backup/initrd conv=fsync

Expected Partition Layout

Partition Contents
1 kernel binary (0xda)
2 initrd (0xda)
3 Debian root filesystem (EXT3)

Software Development

Most of our examples are going to be in C, but Debian will include support for many more programming languages. Including (but not limited to) C++, PERL, PHP, SH, Java, BASIC, TCL, and Python. Most of the functionality from our software examples can be done from using system calls to run our userspace utilities. For higher performance, you will need to either use C/C++ or find functionally equivalent ways to perform the same actions as our examples. Our userspace applications are all designed to go through a TCP interface. By looking at the source for these applications, you can learn our protocol for communicating with the hardware interfaces in any language.

The most common method of development is directly on the SBC. Since debian has space available on the SD card, we include the build-essentials package which comes with everything you need to do C/C++ development on the board.


Editors

Vim is a very common editor to use in Linux. While it isn't the most intuitive at a first glance, you can run 'vimtutor' to get a ~30 minute instruction on how to use this editor. Once you get past the initial learning curve it can make you very productive. You can find the vim documentation here.

Emacs is another very common editor. Similar to vim, it is difficult to learn but rewarding in productivity. You can find documentation on emacs here.

Nano while not as commonly used for development is the easiest. It doesn't have as many features to assist in code development, but is much simpler to begin using right away. If you've used 'edit' on Windows/DOS, this will be very familiar. You can find nano documentation here.

Compilers

We only recommend the gnu compiler collection. There are many other commercial compilers which can also be used, but will not be supported by us. You can install gcc on most boards in Debian by simply running 'apt-get update && apt-get install build-essential'. This will include everything needed for standard development in c/c++.

You can find the gcc documentation here. You can find a simple hello world tutorial for c++ with gcc here.

Build tools

When developing your application typing out the compiler commands with all of your arguments would take forever. The most common way to handle these build systems is using a make file. This lets you define your project sources, libraries, linking, and desired targets. You can read more about makefiles here.

If you are building an application intended to be more portable than on this one system, you can also look into the automake tools which are intended to help make that easier. You can find an introduction to the autotools here.

Cmake is another alternative which generates a makefile. This is generally simpler than using automake, but is not as mature as the automake tools. You can find a tutorial here.

Debuggers

Linux has a few tools which are very helpful for debugging code. The first of which is gdb (part of the gnu compiler collection). This lets you run your code with breakpoints, get backgraces, step forward or backward, and pick apart memory while your application executes. You can find documentation on gdb here.

Strace will allow you to watch how your application interacts with the running kernel which can be useful for diagnostics. You can find the manual page here.

Ltrace will do the same thing with any generic library. You can find the manual page here.

Cross Compiling

While you can develop entirely on the board itself, if you prefer to develop from another x86 compatible Linux system we have a cross compiler available. For this board you will want to use this toolchain. To compile your application, you only need to use the version of GCC in the cross toolchain instead of the version supplied with your distribution. The resulting binary will be for ARM.

[user@localhost]$ /opt/arm-2008q3/bin/arm-none-linux-gnueabi-gcc hello.c -o hello
[user@localhost]$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.14, not stripped

This is one of the simplest examples. If you want to work with a project, you will typically create a makefile. You can read more about makefiles here. Another common requirement is linking to third party libraries provided by Debian on the board. There is no exact set of steps you can take for every project, but the process will be very much the same. Find the headers, and the libraries. Sometimes you have to also copy over their binaries. In this example, I will link to sqlite from Debian (which will also work in the Ubuntu image).

Install the sqlite library and header on the board:

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

This will fetch the binaries from the internet and install them. You can list the installed files with dpkg:

dpkg -L libsqlite3-0 libsqlite3-dev

The interesting files from this output will be the .so files, and the .h files. In this case you will need to copy these files to your project directory.

I have a sample 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 I have the makefile below. This will have to be adjusted for your toolchain path. In this example I placed the headers 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

You can then copy this directly to the board and execute it. 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 you are frequently updating data, but will require more setup. See your linux distribution's manual for more details. The simplest network method is using ssh/sftp. You can use winscp if from windows, or scp from linux. Make sure you set a password from debian for root or set up a shared key. Otherwise the ssh server will deny connections. From winscp, enter the ip address of the SBC, the root username, and the password you have set or the use of a shared key. This will provide you with an explorer window you can drag files into.

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

For scp in linux, run:

#replace with your app name and your 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

Kernel Compile Guide

WARNING: Backup any important data on the board before continuing.

For adding new support to the kernel, or recompiling with more specific options you will need to have an X86 compatible linux host available that can handle the cross compiling. Compiling the kernel on the board is not supported or recommended. Before building the kernel you will need to install a few support libraries on your workstation:

Prerequisites

RHEL/Fedora/CentOS:

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

Ubuntu/Debian:

apt-get install build-essential libncurses5-dev libncursesw5-dev

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

Set up the Sources and Toolchain

# Download the cross compile toolchain (EABI)from Technologic Systems:
ftp://ftp.embeddedTS.com/ts-socket-macrocontrollers/ts-4200-linux/cross-toolchains/arm-2008q3-72-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

# Extract to current working directory:
tar xvf arm-2008q3-72-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

# Download the Kernel sources
wget ftp://ftp.embeddedTS.com/ts-socket-macrocontrollers/ts-4200-linux/sources/linux-2.6.36-ts-src-latest.tar.gz

# Extract the Kernel Sources
gzip -dc linux-2.6.36-ts-src-latest.tar.gz | tar xf -

cd linux-2.6.36-release/

Configure the Sources

The kernel sources need a few variables to be exported.

# Set the CROSS_COMPILE variable to the absolute path to the toolchain.  This may be different for your system:
export CROSS_COMPILE=/opt/4200/arm-2008q3/bin/arm-none-linux-gnueabi-

# Normally, ARCH will be set based on your build hosts architecture.
export ARCH=arm

This sets up the default configuration that we ship with for the TS-4200

make ts4200_defconfig

This will bring up a graphical menu where you can edit the configuration to include support for new devices. For Example, to include support for a Prolific USB to serial adapter you would go to 'Device Drivers -> USB Support-> USB Serial Support' and then select 'USB Prolific 2303 Single Port Serial Driver'. Since the kernel only has a limited space try to build build drivers as modules whenever possible.

make menuconfig

Build the kernel Once you have it configured, start building. This usually takes a few minutes.

make && make modules

The new kernel will be at "arch/arm/boot" in a compressed format called zImage. The uncompressed version is simply called Image. With the default partitioning scheme it is REQUIRED that the kernel be < 2620416 bytes in size. If you need to shorten the size, try including your changes to the kernel as modules instead. Otherwise you will need to resize the kernel partition to account for the size difference.

Install the kernel Now that you have a kernel you can install it as you would our stock. See the #Backup / Restore section for examples on writing this to disk.

Install Modules Script to make directory and install modules

./build-module-bundles.sh

The build-module-bundles.sh script is meant to be run as a user (not root) and will create directories and install modules to them. The directory structure is created at /home/`whoami`/src/ts-4200/dist/<ts4200 kernel release number>/modules-install/. In that directory is initrd-modules/, lib/, and modules-<ts4200 kernel release number>.tgz.

initrd-modules/modules.tar.gz is a tarball that contains a minimal number of modules. This tarball needs to be copied to the initrd partition of the boot media. The boot process of the board will automatically un'tar this and insert any necessary modules.

Now the contents of lib/ can be copied to the root of the TS-4200. It is also possible to copy over modules-<ts4200 kernel release number>.tgz to the TS-4200 and unpack it in the root linux directory. You may want to remove any old modules on the board in /lib/modules/* before copying them to the board to rule out any incompatibilities. Once you boot up to the board, you need to run 'depmod' once to calculate module dependencies. You can then run 'modprobe' with the device drivers you've added. For the Prolific adapter added in the example, this would be:

modprobe pl2303

Getting Started with tsctl

First, download and install the latest version of tsctl as documented in the Getting Started Guide.

In the examples below you can follow along by typing the commands (the portion after the prompt) and expect to see the output below the prompt. Note that while the results should be similar, in some cases you might not see exactly the same results due to variations in execution.

Let's start the tsctl shell:

$ tsctl
tsctl 0.93-ts (Dec  7 2012 15:34:29)
Type "?" to get context-sensitive help.
tsctl>

Let's check that we really have a TS-4200.

tsctl> System ModelId
16896
tsctl>

That doesn't look like 4200! The reason is that the ModelId (and BaseBoardId) commands return 0x4200 (hexadecimal 4200), but the tsctl shell defaults to decimal output. (Note that the command line defaults to hexadecimal!)

We can change to hexadecimal output using the mode command. There is no output from this command.

tsctl> Mode Hex
tsctl>

Now let's try again.

tsctl> System ModelId
0x00004200
tsctl>

In addition to the base the output is represented in, you can also change the general format. The tsctl shell defaults to "NoAssign" mode in which only the input or inputs are printed, each on a separate line. The "Assign" mode (which is the default for the command line) prints a descriptive name=value pair for each value output.

tsctl> Mode Assign
tsctl>

Now let's re-run the previous command. If your version of tsctl is linked against libreadline, you can use the up-arrow twice to pull the System ModelId command back instead of typing it out.

tsctl> System ModelId
System_ModelId_0=0x00004200
tsctl>

Let's run the command again.

tsctl> System ModelId
System_ModelId_1=0x00004200
tsctl>

Notice that the name changed slightly. The first part of the name is the class, the second it the field name (which is also the function name in cases where the value is directly returned at the C API level), and the third is a number. This number is the index of the number of times this class function has been called during the current invocation of tsctl.

Let's switch back to NoAssign mode. Although the field names can be useful if you aren't familiar with what the output fields mean, mostly Assign mode is meant for evaluating by the shell to set variables.

tsctl> Mode NoAssign
tsctl>

Now let's see what base board we have. Your output will differ depending on what you actually have installed.

tsctl> System BaseBoardId
0x00008200
tsctl>

Let's switch back to decimal output.

tsctl> Mode Dec
tsctl>

Now, let's enter the System class onto the command stack so that we don't have to type it repeatedly.

tsctl> System
tsctl System>

Note that our first command, "System" was incomplete, which caused tsctl to push it onto the command stack. This can be used to reduce typing when repetitive sequences start with the same partial command. To pop an element off the stack in the shell, enter an empty line.

One feature of libtsctl is the System Map, which contains name/value pairs. The name is any string (8-bit Array) and the value is an integer. First, let's see how many entries are stored in the table.

tsctl System> MapLength
458
tsctl System>

The entries in the table are stored sorted by name (case-insensitively). Entries are used to store DIO names, enumerated values, attributes, and user-defined name/value pairs. If you want to see the entire table you can get each entry one at a time by index number, starting at 1:

tsctl System> MapGet 1
AIO_ADC
1
tsctl System>

The first line contains the name, while the second contains the value.

To get several entries at once let's first put the function name on the command stack

tsctl System> MapGet
tsctl System MapGet>

One feature of tsctl is the ability to separate commands by a semi-colon. In the shell (e.g. bash) this requires quoting the semi-colon; in the tsctl shell it does not. Let's get the next ten entries:

tsctl System MapGet> 2;3;4;5;6;7;8;9;10;11
AIO_DAC
2
attrib.8200.Wire.Connector.1.0
1
attrib.8200.Wire.Connector.1.1
1
attrib.8200.Wire.Connector.10.0
2
attrib.8200.Wire.Connector.12.0
2
attrib.8200.Wire.Connector.12.1
2
attrib.8200.Wire.Connector.13.0
2
attrib.8200.Wire.Connector.13.1
2
attrib.8200.Wire.Connector.14.0
2
attrib.8200.Wire.Connector.15.0
2
tsctl System MapGet>

What happened here is that each number got appended as the parameter to the System MapGet function.

Hit enter on an empty line to pop the MapGet function off the command stack.

tsctl System MapGet> 
tsctl System>

Let's look at some of the attributes available. We can find the name of a connector by number as follows:

tsctl System> MapLookupPartial attrib.Connector.Name. 2
CN2_
tsctl System>

How many connectors are there?

tsctl System> MapLookup attrib.Connector.Count
2
tsctl System>

Depending on your system, you may have more than this! How many pins does connector 1 have?

tsctl System> MapLookup attrib.Connector.1.Pins
100
tsctl System>

Most boards have a green and red LEDs, but the DIO number differs from board to board. Let's see what DIO numbers they are on this board. If the lookup fails, a negative value will be returned.

tsctl System> MapLookup;GREEN_LED;RED_LED;;
128
129
tsctl System>

Note that we used two semi-colons with nothing between them to pop the MapLookup function back off the stack.

What connector is the GREEN_LED on? We can determine this by searching the connector attribute for a value corresponding to the DIO number of GREEN_LED. In the above case, that value is 128. However we can also use GREEN_LED, as the tsctl text interface will automatically translate it to the correct value:

tsctl System> MapLookupPartial attrib.Connector. GREEN_LED
2.8
tsctl System>

Note that in a few rare cases the above lookup will conflict with another attribute and may not work. This is because MapLookupPartial looks for a name starting with the specified string, having the specified value. If we specified a value of "100" we might match "attrib.Connector.1.Pins", "attrib.Connector.2.Pins", or "attrib.Connector.1.8" as these all have a value of 100.

The interpretation of 2.8 is "Connector 2, Pin 8". This is also known as "CN2_8", by combining the name of the connector with the pin number on that connector.

tsctl System> MapLookup CN2_8
128
tsctl System>

NOTE: For widest cross-platform compatibility it is recommended to perform lookups based on connectors, rather than board specific DIO names.

How many DIO are on the board?

tsctl System> MapLookup attrib.DIO.Count
130
tsctl System>

If you have a peripheral board such as a baseboard or PC-104 board with supported DIO, you will see a higher number than this. Note that this number counts all raw, internally addressable DIO, regardless of whether or not they are brought out to pins. As such the actual number of usable DIO will frequently be lower than the number contained in this attribute.

Let's pop the System class from the command stack.

tsctl System> 
tsctl>

What revision of the FPGA is on the board?

tsctl> System FPGARevision
4
tsctl>

We can read the I2C (TWI) temp sensor on the TS-4200 with tsctl. First let's switch to hexadecimal output for Arrays of bytes.

tsctl> Mode AHex
tsctl>

Next, we need to make sure that the pins that are used for TWI are correctly set up, as they are frequently multi-function pins. The easiest way to make sure the pins are set correctly is to lock the function you are going to use. As part of locking the pin will be initialized to the correct function. For some boards (notably the TS-4800) the TWI must always be locked during use as it uses an underlying operating system file to perform its functionaity.

tsctl> TWI Lock 0 0
1
tsctl>

Now verify that the temperature sensor is present at device address 0x49.

tsctl> TWI Read 0x49 1 7 2
TWISuccess
0x01:0x90
tsctl>

If the bytes read back are not 0x01:0x90 (the first value returned is the result code), then the temperature sensor is not present, or there is another problem with the TWI bus. Assuming we get the correct response back, we can next send the commands to start an aquisition, and read back the raw temperature data from the sensor.

tsctl> TWI Write;0x49 1 1 0x40:0x0;0x49 0 0 0x40:0x0;;Read 0x49 1 0 2;;
TWISuccess
TWISuccess
TWISuccess
0x12:0x60
tsctl>


The value returned can be converted to a temperature as follows:

tempC = (byte[0] * 256 + byte[1]) / 128
tempC = (0x12 * 256 + 0x60) / 128
tempC = 36.75C

Note: The ts8160ctl sample application provides the above TWI temp sensor reading functionality using the -t option.

Be sure to unlock any resource when you are done. Best practice is to hold a lock for the minimum amount of time necessary.

tsctl> TWI Unlock 0 0
1
tsctl>

There are also several timing based functions you can use. For instance, you can delay for a specific amount of time. You should see a delay of approximately 1 second (1,000,000 microseconds) when running the command below:

tsctl> Time;Delay 1000000
tsctl Time>

Note that the Delay function does not return a value. If you want to see the actual number of microseconds delayed, use the Wait function instead:

tsctl Time> Wait 1000000;;
1011557
tsctl>

The only difference between Wait and Delay is that the former returns the number of microseconds actually spend waiting, and the latter returns no value. This is an important nuance in the TCP classes, as in certain modes functions that return no data are not called until subsequent functions that do return data are called. This allows for things such as commanding a relay to cycle power on the board issuing the command (so long as it isn't the board interpreting the command), since otherwise the command to restore power would not be sent before power was cut.

Short delay times are generally only useful when using direct access from C. Otherwise, the overhead of parsing the command, sending it across TCP, and interpreting it on the server will be significant in comparison to the amount of time to delay.

Features

CPU

The TS-4200 features a AT91SAM9G20 400MHz ARM9. For more information on the processor and it's integrated peripherals, refer to the CPU manual.

MicroSD Card Interface

The SD interface supports both MicroSD and MicroSDHC cards. There is a linux driver provided in the default TS-4200 kernel that allows you to access the SD card block device as /dev/mmcblk0, or /dev/mmcblk0p# for accessing a specific partition. By default the TS-4700 will use this layout:

Device Contents
/dev/mmcblk0p1 Fat32 partition.
/dev/mmcblk0p2 Linux kernel.
/dev/mmcblk0p3 Initrd/Fastboot
/dev/mmcblk0p4 Debian Filesystem

The FAT32 partition isn't necessarily required, but unless Windows can recognize one of the partitions it will ask the user if they want to formt the disk. If you remove this partition you will need to modify the linuxrc scripts accordingly

XNAND

The XNAND is a custom block device abstraction which is designed to vastly increase the reliability of NAND access. This board includes a 512MB flash chip, but the XNAND algorithm will limit this to a usable 256MB from redundancy. The software layer to access the XNAND is implemented in userspace in conjunction with NBD (network block device). You may want to refer to the nandctl page which will show more advanced usage, but by default the linuxrc script will mount the sd card with the following layout:

 /dev/nbd0 - whole disk device of XNAND drive
 /dev/nbd1 - 1st partition (kernel partition)
 /dev/nbd2 - 2nd partition (EXT2 initrd)
 /dev/nbd3 - 3rd partition (~252MByte mini Debian EXT3 filesystem)
 /dev/nbd4 - 4th partition (unused)
 
Note: NBD devices do not report size correctly. If you are formatting a partition or using dd you will need to specify the size.

XNAND2

Note: As of January 16th, 2017 the TS-4200 has been shipping with an XNAND2 compatible bootrom, an XNAND2 formatted NAND device, and the SD and NAND images have updated nandctl binaries to support XNAND2

XNAND2 is an innovation built upon its XNAND predecessor. This engineering effort was predicated by the NAND industry's falling quality standards and Technologic Systems' dedication to continued superior quality, long lifespan products. XNAND2 introduces a more robust system of redundant, error-corrected data storage, and a whole-device wear leveling system that ensures the longest possible lifespan for NAND media.

Please see our whitepaper on the subject for more detail and information.


To facilitate this new paradigm, a new 'nandctl' binary has been introduced. The features and output of this new utility are detailed in this section.

The command line options for the XNAND2 nandctl are very similar to the original:

# nandctl --help
Usage: nandctl [OPTION] ...
Technologic Systems NAND flash manipulation.

General options:
  -R, --read=N            Read N blocks of flash to stdout
  -W, --write=N           Write N blocks to flash
  -x, --writeset=BYTE     Write BYTE as value (default 0)
  -i, --writeimg=FILE     Use FILE as file to write to NAND
  -t, --writetest         Run write speed test
  -r, --readtest          Run read speed test
  -n, --random=SEED       Do random seeks for tests
  -z, --blocksize=SZ      Use SZ bytes each read/write call
  -k, --seek=SECTOR       Seek to 512b sector number SECTOR
  -d, --nbdserver=NBDSPEC Run NBD userspace block driver server
  -I, --bind=IPADDR       Bind NBD server to IPADDR
  -Q, --stats             Print NBD server stats
  -m, --dmesg             Print log of NAND activity
  -f, --foreground        Run NBD server in foreground
  -X, --xnand             Use XNAND RAID layer
  -I, --xnandinit         Initialize flash chip for XNAND
  -L, --listbb            List all factory bad blocks
  -v, --verbose           Be verbose (-vv for maximum)
  -P, --printmbr          Print MBR and partition table
  -M, --setmbr            Write MBR from environment variables
  -h, --help              This help

When running a NBD server, NBDSPEC is a comma separated list of
devices and partitions for the NBD servers starting at port 7525.
e.g. "lun0:part1,lun1:disc" corresponds to 2 NBD servers, one at port
7525 serving the first partition of chip #0, and the other at TCP
port 7526 serving the whole disc device of chip #1.

The --dmesg command will show a running event log since boot. This is useful for troubleshooting if a failure is suspected.

The --stats command will show a mixture of long-term and short-term statistical data about the NAND chip and the XNAND2 layer over it:

# nandctl --stats
nbdpid=146
nbd_readreqs=0
nbd_read_blks=0
nbd_writereqs=0
nbd_write_blks=0
nbd_seek_past_eof_errs=0
xnand2_most_worn=5936
xnand2_spares_used=6
xnand2_spares_remaining=1014
xnand2_total_erases=24156537
xnand2_ecc_fixups=0
xnand2_parity_recovers=0
read_seeks=0
write_seeks=0

This --stats output is helpful for systems where monitoring long-term health is useful.

Stats output definitions:
nbdpid: This is the process id of the nandctl process.
nbd_readreqs: This is the number of read requests received by nandctl since boot.
nbd_read_blks: This is the number of blocks read by the nbd client since boot.
nbd_writereqs: This is the number of write requests received by nandctl since boot.
nbd_write_blks: This is the number of blocks written by the nbd client since boot.
nbd_seek_past_eof_errs: This statistic should always read zero. It's the number of times the OS has asked nandctl to seek past the end of the media.
xnand2_most_worn: This is the number of writes that have been made to the most worn block on the NAND chip over the lifetime of the XNAND2 media.
xnand2_spares_used: This is the number of bad blocks marked by XNAND2 over the lifetime of the XNAND2 media.
xnand2_spares_remaining: This is the number of blocks not currently in active use by the disk block device or the RAID5 like redundant data backup.  They are available to participate in wear-leveling activities (along with the blocks used by the disk block device and redundant data).
xnand2_total_erases: This is the number of erases over the lifetime of the XNAND2 media since boot.
xnand2_ecc_fixups: This is the total number of ecc correctable errors XNAND2 has corrected since boot.
xnand2_parity_recovers: This is the total number of blocks XNAND2 has had to recover from parity data.
read_seeks: This is the number of read seeks done since boot.
write_seeks: This is the number of write seeks done since boot.

Upgrading to XNAND2

Replacing XNAND1 with XNAND2 in a dd image for use in production programming



The latest nandctl binary with XNAND2 support for the TS-4200 can be downloaded here.


An XNAND2 formatted NAND device will work on supported products with any bootrom date, whether or not the bootrom supports XNAND2.  However, devices can only be booted from the XNAND technology that their bootrom supports. An XNAND2 formatted NAND cannot be booted from a bootrom that only supports XNAND1 and vice versa. This allows for application support of XNAND2, regardless of bootrom support, but only if NAND is not the boot media. Because of this, it is important to update all programming and production processes to support XNAND2. For other production preparation processes that do not re-image the entire device, it is still important to confirm the production process is using the XNAND2 nandctl binary dated October 2016 or later. The following section provides the necessary information to update an existing XNAND1 image with the new XNAND2 nandctl software.

The latest nandctl binary is compatible with both XNAND1 and XNAND2; however it will assume that disk initialization will be targeted at XNAND2 support and it is not possible to force XNAND1 formatting. Because of this, the bootrom should be updated to be compatible with XNAND2 before using '--xnandinit' against a NAND device using the latest nandctl binary. TS-BOOTROMs with a date after October 2016 are compatible with and able to boot XNAND2 devices.

This update will walk through the steps of updating the nandctl binary contained in a customized production image. These steps are not necessary when using our stock image, only if your production process is using an SD or NAND image that has been based on any of our previous shipping images. Note that both SD and NAND images should be updated to properly support XNAND2 in all situations.

To prepare this update, a workstation running linux is necessary, either in a virtual machine or native install. From the workstation, open a terminal window and copy your original production image file to a local working directory (this is done to limit working on production used images).  This file will be referenced as diskimg.dd in the following instructions. The latest XNAND2 compatible nandctl binary (link to download is at the top of this section) should also be downloaded in the same working directory.

Next, run the following command:

sudo fdisk -l diskimg.dd

This will produce output like the following:

Disk diskimg.dd: 268 MB, 268435456 bytes
255 heads, 63 sectors/track, 32 cylinders, total 524288 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

      Device Boot      Start         End      Blocks   Id  System
diskimg.dd1                1        5119        2559+  da  Non-FS data
diskimg.dd2             5120       10239        2560   da  Non-FS data
diskimg.dd3            10240      524287      257024   83  Linux

The above is the partition table of an XNAND disk. An image for an SD card will have 4 partitions rather than 3, but the same basic layout. The necessary information is the start sector of the second partition with the Id of "da," and the "Sector size" listed above the partition table. In this case it is partition 2 in which the start block is 5120 and the Sector size is 512. Multiply the two numbers to obtain the necessary offset:  5120 * 512 = 2621440.

Next, the initrd partition from the disk image file is mounted to a folder created in the working directory:

mkdir mnt
sudo mount -orw,loop,offset=$((5120*512)) diskimg.dd mnt/

The new XNAND2 nandctl binary is copied to the mounted folder structure

cp nandctl mnt/sbin/nandctl
sync

The disk image can be unmounted and renamed as needed:

sudo umount mnt
mv diskimg.dd diskimg-xnand2.dd


Upgrading a TS-4200 XNAND1 format to XNAND2 without losing data


It is possible to upgrade TS-4200 systems that are using XNAND1 to the new XNAND2 technology. While we do recommend doing so, it is not critical to existing applications.  This upgrade can be applied to products prior to deployment or after they have been deployed to the field.   The update process described below will preserve all of the data in the file system.  In order to use XNAND2, the platform must have its bootrom updated to support XNAND2, the NAND device formatted to XNAND2, and the final image on NAND and/or SD must have a nandctl binary that supports XNAND2. All of these are updated in the provided USB update disk image and process that is outlined below. Additionally, the system being updated must have reliable power for the upgrade process or else data integrity could be compromised or the unit itself may be rendered unbootable if power is lost during mid-process.

The instructions below presume that the device being upgraded is accessible and has an available USB Host port.  If this is not the case it is possible to convert the script used below to work from another available interface which provides remote access to the unit. It is not possible to perform the update directly from the TS-4200 SD card due to the SD card being disabled in order to write the bootrom to SPI flash. The USB media image provided contains all files and scripts necessary to develop your own custom update and deployment strategy. For more information please feel free to contact Technologic Systems Support, support@embeddedTS.com.


Prerequisites


  • A Linux workstation, either in a virtual machine or native install
  • A TS-4200 on a baseboard with USB Host ports
    • Non-TS baseboards should have at least one USB Type-A Host port.
  • A serial terminal connected to the TS-4200 serial console output (optional, for diagnostic purposes if there is an error).
  • A USB data storage device (thumb drive or equivalent) of at least 32 MB capacity (note that this procedure will erase all data on the USB disk).


Preparation


1. Download the TS-4200 XNAND2 USB Update disk image from the Technologic Systems FTP site:
wget ftp://ftp.embeddedTS.com/ts-socket-macrocontrollers/ts-4200-linux/binaries/ts-images/ts4200-XNAND2-upgrade-usb-20161003.dd.bz2
2. Extract the file on the Linux workstation using bunzip2:
bunzip2 ts4200-XNAND2-upgrade-usb-20161003.dd.bz2
3. Connect the USB media to the Linux workstation. If using a virtual machine, make sure the USB device is available to Linux before continuing.
4. If automatically mounted, unmount all USB media partitions. Note, in the example below '/dev/sdXy' should be replaced with the actual device node on your desktop computer - the X is the device letter, and y is the partition number.
sudo umount /dev/sdXy
5. Install the image on the USB media device using dd. Note that the image is being written to the whole disk rather than a partition. This process may take several minutes, and the data on the USB device will be erased:
dd if=ts4200-XNAND2-upgrade-usb-20161003.dd of=/dev/sdX bs=4M conv=fsync && sync && sleep 1
6. The updater USB device is now ready for use. Disconnect it from the workstation.


Installation:


  1. Insert the USB update disk to the USB Host port of the TS-4200
  2. Apply power to the unit.
  3. Allow the USB update scripts to run. Note: This process will take a long time. Allow at least 20 minutes. During this time the green LED (if present on baseboard) will blink slowly through the process.
  4. When the script is finished executing, the baseboard's green LED (if present) will turn on and remain solid. If the process fails, the red LED will turn on and remain solid. More information about the failure will be on the TS-4200 serial console output.

SPI

The SPI controller is provided by the Atmel CPU. We provide sample code to set up the SPI port and initiate a write to an SPI flash device. This is used to demonstrate a simple read and write, as well as a more complex overall process. A TS-4200 compatible binary is available here with the sources available here.


Documentation for the CPU SPI peripheral can be found in the CPU manual in section 30 (page 391).

Ethernet

The Atmel Processor implements a 10/100 ethernet controller with support built into the Linux kernel. You can use standard Linux utilities such as ifconfig/ip to control this interface. See the #Configuring the Network section for more details. For the specifics of this network controller see the CPU manual.

USB Host

The Atmel CPU contains 2 USB Host ports that communicate at 12mbps.

USB Device

Note: There exists a pertinent errata to this topic. Please see also the errata section.

This section will discuss the configuration and use of the Linux USB device gadgets (http://www.linux-usb.org/).

NOTE: Due to a bug, a kernel update must be performed in order to reliably enable this feature. Please contact our support team here for more information.

The USB Mass Storage Device Linux USB gadget will allow you to use your board as a storage device, like a USB thumb drive, when connected to a host PC. Subsequently, the CPU can access the saved data through the storage element named usb_storage_file.

The IP over USB (A.K.A. USB Ethernet) Linux USB gadget will allow you to connect to your board with a USB cable from a PC like you would with a CAT5 Ethernet cable. You will have access to the board via the TCP/IP connection allowing you to use any networking utility (e.g. ping, ssh, ftp, http, etc).

For Windows, a driver interface configuration file (linux.inf) will need to be downloaded and installed on the host PC. This procedure is described in detail below. The linux.inf file can be downloaded here.

The TS-4200 can only be one device at a time. It cannot be both a USB Mass Storage device AND a USB Ethernet device simultaneously. Load only ONE of these drivers.

USB Device as Mass Storage

The USB Gadget file storage device will allow you to allow access to a block device (file or otherwise) over USB. To use this functionality, you must first have a block device to give to the driver. In this example I will use a 100MB file on the Debian filesystem.

dd if=/dev/zero of=/root/usbstorage.img bs=1MB count=100

Load the driver with the file as an argument

modprobe g_file_storage file=/root/usbstorage.img

If you now, or are have already connected the USB device cable to a host pc, you should now see the USB device. Like inserting any other usb drive you should now have a new device on your system. From a linux host pc:

[690892.624575] sd 23:0:0:0: Attached scsi generic sg3 type 0
[690892.626160] sd 23:0:0:0: [sdd] 195312 512-byte logical blocks: (99.9 MB/95.3 MiB)
[690892.628419] sd 23:0:0:0: [sdd] Write Protect is off
[690892.628424] sd 23:0:0:0: [sdd] Mode Sense: 0f 00 00 00
[690892.628911] sd 23:0:0:0: [sdd] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[690892.644202]  sdd: unknown partition table
[690892.647287] sd 23:0:0:0: [sdd] Attached SCSI disk

Now on your workstation you can use this device as any other usb storage. As this file contains all zeros, you will need to format it and create a partition/filesystem to be able to store data on it. See the documentation for your workstation for more details. Keep in mind you cannot mount the same block device or file twice so this will not allow you to share your live filesystem over USB.

USB Device as USB Ethernet

In order to use USB Device as USB Ethernet you will first need a new kernel compiled from source. The instructions to compile the kernel can be found here.

Install the kernel Now that you have a kernel you can install it as you would our stock. See the #Backup / Restore section for examples on writing this to media.

Once you have added the newly compiled kernel to your image you will now have Ethernet Gadgets driver built in which will allow you to use USB Device as USB Ethernet. The board must be setup prior to connection to a host PC.

Now assign an IP address to the new usb0 interface

ifconfig usb0 192.168.42.20

The IP address in the above example may be any valid IP address, but should typically not be on the same subnet as the Ethernet network on the the board (if connected), or the host computer to which the SBC will be connected.

Connecting Linux Host to the board via IP over USB

Most modern Linux distributions already have all of the required modules (such as usbnet.ko) and utilities installed, so the setup steps are minimal. Simply plug in the board after it has been prepared for IP over USB (see above) and observe that a new interface has been added named usb0 or similar (use dmesg | tail to verify). You can now assign an IP address to that interface with ifconfig (e.g. ifconfig usb0 192.168.42.21) and begin using the TCP/IP connection. To test your connection, use ping 192.168.42.20. You should also be able to login to the SBC using ssh ie. ssh root@192.168.42.40.

Connecting Windows XP Host to the board via IP over USB

An additional driver interface configuration file called linux.inf is required for IP over USB connection to a Windows host. First, download this file onto the Windows PC and remember where you placed it. The linux.inf file can be downloaded here. Next, connect the board and Windows PC with the A to B USB cable (ISB Cable). You should see the "Found New Hardware Wizard". Answer the prompts as follows:

  • Select Include this location in the search and choose the location of the driver you downloaded. Finish running the wizard.
  • Go to the Control Panel and open "Network Connections". Right-click the new connection (labeled "Linux USB Ethernet/RNDIS Gadget") and click "Rename". Rename it to something useful such as "USB Network".
  • Right-click on the newly labeled icon, and select properties.
  • Under the properties General tab, select the item labeled Internet Protocol (TCP/IP)
  • Select Use the following IP Address, and enter 192.168.42.21.
  • Click OK; Click OK
  • You may now access the board via the TCP/IP connection. Use ping in the Command Prompt window to verify connectivity (e.g. ping 192.168.42.20).
Note: The IP address above may be any valid IP address, but must be in the same subnet as the IP address assigned to the board IP over USB connection above. The subnet used should also be different from any other interfaces on the SBC or PC, otherwise strange results may occur.

External Reset

The external reset pin (DIO 9) will reset the CPU by default when it is low. You can disable this functionality to use this as a DIO by running:

ts4200ctl --resetswitchoff

FPGA

The TS-4200 features a Low power Actel FPGA clocked by the CPU only when needed. This FPGA is not end user programmable, but you can use the MUXBUS to allow communication to an offboard FPGA. The TS-4200 provides access to the FPGA in an 8 bit region and a 16 bit region. The 8 bit base address is 0x10000000. The 16 bit base address is 0x30000000. All registers inside the TS-4200 FPGA are 16 bit registers and should be accessed via the 16 bit space. The 8 bit space is only needed for off-board 8 bit devices on the MUXBUS. To access hardware cores in the FPGA, add the offset in the table below to the base address.

This table shows our top level decode for the FPGA. Use the 16 or 8 bit address with these offsets to talk to our various FPGA cores.

Offset Usage
0x0 Syscon registers
0x080 ADC registers (for off-board ADC)
0x100 NAND flash registers
0x200 NVRAM control registers
0x400 1KB MUXBUS space
0x800 2KB Direct blockram access (For NVRAM transfers)

Syscon

The registers listed below are all 16 bit registers and must be accessed with 16 bit reads and writes. This register block appears at base address 0x30000000.

Offset Bits Usage
0x0 15:0 Model ID: Reads 0x4200
0x2 15 Green LED (1 = on)
14 Red LED (1 = on)
13:8 Reserved
7:4 Board Sub-model: reads 0x0 on standard unit
3:0 FPGA revision
0x4 15:0 DIO direction for DIO 15(MSB)-0(LSB)
0x6 15:0 DIO output data for DIO 15(MSB)-0(LSB)
0x8 15:0 DIO input data for DIO 15(MSB)-0(LSB)
0xa 15:12 Reserved
11 UART0 9 bit mode (so that TX_EN works correctly)
10 1 = use DIO12 for uart0 TX_EN instead of DIO
9 1 = use 512Hz for WDT instead of 200Hz
8 1 = auto reboot when DIO 9 is driven low (enable reset button)
7:6 Scratch Register (used by bootrom)
5:4 Mode strapping inputs Mode2 and Mode1
3 Reserved
2 1 = Enable power to Ethernet PHY
1 1 = Enable power to SD card
0 Offboard reset signal (1 = reset)
0xc 15:0 32-bit 1MHz free running counter (16 LSBs)
0xe 15:0 32-bit 1MHz free running counter (16 MSBs)
0x10 15:0 Watchdog feed register
0x12 15:0 DIO direction for DIO 31(MSB) - 16(LSB)
0x14 15:0 DIO output data for DIO 31(MSB) - 16(LSB)
0x16 15:0 DIO input data for DIO 31(MSB) - 16(LSB)
0x18 15:0 Hardware RNG (16 LSB)
0x1a 15:0 Hardware RNG (16 MSB)
0x1c 15 Embedded FlashROM CLK
14:8 Embedded FlashROM Address
7:0 Embedded FlashROM Data Byte
0x1e 15:0 UART0 baud rate divisor (for UART0 TX_EN)
0x20 15:0 MUXBUS configuration register
0x22 15:0 IRQ register
0x24 15:0 IRQ mask register

The born-on date of the unit and the MAC address can be read by from the FPGA FlashROM. See ts4200ctl source code for sample usage.

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, but it can be useful to identify the board in software. During startup of the System-on-Module, 4 DIO are used to obtain the baseboard model ID. 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.

You can find example code for accessing the baseboard ID in ts4200ctl. For example, "ts4200ctl -B" will return "baseboard_model=" with the detected baseboard.

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, do not use
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
20 TS-TPC-8950
22 TS-8551
42 Reserved for customer use, never used by us
63 TS-8200

LEDs

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

Green Behavior Red behavior Meaning
On On for about .5s, off for 5s, on for 1s, off After the red LED stays off the system has booted and is running.
On Off System is booted and running.
On On for approximately 15s, then off Once the system has booted the kernel and executed the startup script, it will check for a USB device and then determine if it is a mass storage device. This is used for updates/blasting through USB. Once it determines this is not a mass storage device the red LED will turn back off.
On for 10s, off for 100ms, and repeating Turns on after Green turns off for 300ms, and then turns off for 10s The watchdog is continuously resetting the board. This happens when the system cannot find a valid boot device, or the watchdog is otherwise not being fed. This is normally fed by ts4200ctl once a valid boot media has started. See the #Watchdog section for more details.
Off Off The FPGA is not able to start. Typically either the board is not being supplied with enough voltage, or the FPGA has been otherwise damaged. If using an off the shelf baseboard and a stable 5V is being provided and the supply is capable of providing at least 1 A and 5 V to the System-on-Module, an RMA is suggested.

ADC Core

The ADC core supports the MCP3428 which is an affordable 16-bit ADC board. This is available on several of the TS-Socket baseboards.

This core assumes the standard circuit which allows 2 differential channels and 4 single-ended channels. The single-ended channels are chosen using analog muxes controlled by the AN_SEL line. Since different base boards use a different pin for AN_SEL, a register is also provided to select the correct line. Channels 1 and 2 are differential channels with a range of -2.048V to +2.048V. Channels 3-6 are 0 to 10.24V.

Offset Bits Access Usage
0x0 15-8 Read Only Core ID register (0xad)
7-6 Read Only Reserved
5-4 Read/Write Analog Select

0 = Do not use an AN_SEL <br\> 1 = Use CN1 pin 77 for AN_SEL (TS-81X0) <br\> 2 = Use CN1 pin 74 for AN_SEL (TS-8390) <br\> 3 = Reserved

3-2 Read/Write Speed

0 = 240Hz, 12 bit resolution
1 = 60Hz, 14 bit resolution
2 = 15Hz, 16 bit resolution
3 = Reserved

1-0 Read/Write Programmable Gain

0 = No gain
1 = 2x gain
2 = 4x gain
3 = 8x gain

0x2 15-0 Read/Write Channel Mask
0x4 15-0 Read Only Channel 1 most recent conversion value
0x6 15-0 Read Only Channel 2 most recent conversion value
0x8 15-0 Read Only Channel 3 most recent conversion value
0xa 15-0 Read Only Channel 4 most recent conversion value
0xc 15-0 Read Only Channel 5 most recent conversion value
0xe 15-0 Read Only Channel 6 most recent conversion value

The channel mask register controls which channels are enabled. Bits 0-5 enable channels 1-6 respectively. If a given channel is not enabled, (enable bit == 0) it will not be sampled and its conversion value register will contain an obsolete and meaningless value. The more channels that are enabled, the lower the sampling speed on each channel.

This example will sample the current value of all ADCs and output them in millivolts.

#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>

volatile uint16_t *fpga = 0;
uint16_t peek16(uint16_t addr) 
{
	uint16_t value;

	if(fpga == 0) {
		int mem = open("/dev/mem", O_RDWR|O_SYNC);
		fpga = mmap(0,
			getpagesize(),
			PROT_READ|PROT_WRITE,
			MAP_SHARED,
			mem,
			0x30000000);
	}

	return fpga[addr/2];
}

void poke16(uint16_t addr, uint16_t value)
{
	if(fpga == 0) {
		int mem = open("/dev/mem", O_RDWR|O_SYNC);
		fpga = mmap(0,
			getpagesize(),
			PROT_READ|PROT_WRITE,
			MAP_SHARED,
			mem,
			0x30000000);
	}

	fpga[addr/2] = value;
}

int main()
{
	int x, i;
	// Select TS-81XX, 15hz, 16-bit resolution with 0x gain
	poke16(0x80, 0x18); 

	// Select TS-8390, 15hz, 16-bit resolution with 0x gain
	//poke16(0x80, 0x28); 

	// unmaks to enable all 6 channels
	poke16(0x82, 0x3f); 

	usleep(500000); // allow time for conversions
	for (i = 1; i <= 6; i++) {
		x = (signed short)peek16(0x82 + 2*i);
		if (i > 2) x = (x * 1006)/200;
		x = (x * 2048)/0x8000;
		printf("adc%d=%d\n", i, x);
	}

	return 0;
}

Watchdog

By default the watchdog is fed by ts4200ctl. This way if userspace, the kernel, or the FPGA communication has any issue the board will reboot. You can tailor this more specifically to your application by feeding the watchdog on your own criteria. The Watchdog feed register is write-only. Valid write values are:

Write Value Effect
0 Feed watchdog for the next 0.5 sec
1 Feed watchdog for the next 2 sec
2 Feed watchdog for the next 16 sec
3 Disable watchdog

These watchdog timeout times assume that the 512Hz clock is being used as a watchdog clock. At power-up, the 200Hz clock is used, which means that the timeout times would actually be roughly 150% longer. The 512Hz clock signal is not turned on until a time is written to the RTC. The default linuxrc writes the RTC, which enables the 512Hz signal, and then switches the watchdog to the 512Hz signal.

If you would like to run your own watchdog you will need to kill ts4200ctl when switching to your own application. This below code is a minimalistic example for feeding the watchdog.

#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>
 
int main()
{
        int mem;
        volatile uint16_t *syscon;
 
        mem = open("/dev/mem", O_RDWR|O_SYNC);
        syscon = mmap(0,
                      getpagesize(),
                      PROT_READ|PROT_WRITE,
                      MAP_SHARED,
                      mem,
                      0x30000000);
 
        for(;;) {
                // This feeds the watchdog for 16s.
                syscon[0x10/2] = 2;
                sleep(8);
        }
 
        return 0;
}

NVRAM

The TS-4200 features an 8KB non-volatile SRAM. If a voltage is supplied on V_BAT, the TS-4200 can shut down without losing SRAM data. To communicate with the SRAM, software must read and write the FPGA blockram region, and use NVRAM control registers to initiate block transfers between the FPGA blockram and the SRAM. The NVRAM control register map is as follows:

Offset Bits Usage
0x0 15:2 Reserved
1 power fail. 1 = further transfers are not permitted.
0 busy flag. Indicates transfer is occurring.
0x2 15:3 Reserved
2:1 NVRAM bank used for copy
0 0 = copy NVRAM to blockram
0x4 15:1 Reserved
0 transfer enable register
0x6 15:0 Power fail flag can be cleared by writing 0 to this register.

Data transfers between FPGA blockram and SRAM happen in 2KB blocks. The NVRAM consists of 8KB divided into 4 banks of 2KB. The correct software algorithm for a single transfer is as follows:

  • Make sure the busy flag and power fail flag are not set
  • Program the NVRAM bank register and direction register as desired
  • Set the transfer enable flag
  • Poll the busy flag until it goes high
  • Clear the transfer enable flag

The ts4200ctl utility source code includes a function that demonstrates the above algorithm.

MUXBUS

Muxbus timing.png

All TS-SOCKET System-on-Modules have an external bus called the MUXBUS. The bus consists of 16 muxed address/data lines, ALE#, CS#, DIR, BHE#, and WAIT#. The MUXBUS provides a way for TS-SOCKET base board designers to include static memory devices, bridges to other industry standard buses such as PC/104, or an FPGA that implements custom features. Verilog modules ts8100.v and muxbusbridge.v are provided as examples of how to interface with the MUXBUS.

MUXBUS slaves can be 8 bit or 16 bit devices. Each SoM has an 8 bit MUXBUS address space which must be accessed with 8 bit reads and writes, and a 16 bit MUXBUS address space which must be accessed with 16 bit reads and writes. Software that works with the MUXBUS must know whether it is talking to an 8 bit or 16 bit slave device and act accordingly.

The bus cycle speed depends on the FPGA clock speed, which varies from one SoM to another. Thus, the MUXBUS behavior is specified in clock cycles. The bus cycle works as follows:

  • ALE# is asserted, and the address is driven on the bus lines. This condition is held for TP_ALE + 1 clock cycles.
  • ALE# is de-asserted while the address remains valid for TH_ADR + 1 clock cycles.
  • Data is driven on the bus lines (for a write) or the bus lines go high-Z (for a read) for TSU_DAT + 1 clock cycles.
  • CS# is asserted for TP_CS + 1 clock cycles.
  • CS# is de-asserted and data remains valid for TH_DAT + 1 clock cycles.

BHE# and DIR remain valid throughout the whole bus cycle. WAIT# is an input. The external device can assert the WAIT signal during the CS# pulse to extend it. The bus can work in 8 bit or 16 bit modes. In 8 bit mode, mux lines 8-15 are not used for data and BHE# is ignored. In 16 bit mode, byte reads and writes are still supported using BHE# and A0.

Each module will have a 16 bit external bus configuration register in its #Syscon.

Bus Config Register Bits Usage
bit 0 Bus enable (otherwise, pins are GPIO or reserved)
bits 2:1 TP_ALE
bits 4:3 TH_ADR
bits 6:5 TSU_DAT
bits 12:7 TP_CS [1]
bits 15:13 TH_DAT
  1. A TP_CS of 0x3f is not supported -- use a value from 0 to 62 (that's 0x00 to 0x3e).

IMPLEMENTATION TIMING NOTES:

On a MUXBUS write, all timing values are controlled by the bus config register. The slave device is permitted to latch data on either the leading edge or the trailing edge of the CS# pulse, or any time in between.

One a MUXBUS read, the MUXBUS latches data on the trailing edge of the CS# pulse. The slave device should begin driving the data bus in response to CS# assertion. Users should program TP_CS so that TSU_RD is at least 10ns plus any delays between the two boards. A conservative TP_CS setting is recommended, because an extra clock cycle here will not have a significant effect on net MUXBUS bandwidth.

The slave device must stop driving the data bus in response to CS# de-assertion. TH_RD must be at most 30ns. The TS-4200 uses a 20.20 ns clock cycle.

PC104

With the baseboards that make use of the PC104 bus, you must first set up the MUXBUS configuration registers. From Debian, you would run this:

source /initrd/ts4200.subr 
pc104on

NOTE: The `pc104on` command sets the MUXBUS timing config register to 0x181, which is aggressive timing. This may not work for all PC/104 devices, in which case we recommend writing a more conservative config value, something like `peekpoke 16 0x30000020 0x381`

From your application you can now talk to the MUXBUS for communication to PC104. The TS-4200 with our baseboards will implement the 8 bit PC104 address space from 0x10000400 to 0x100007ff. The 16 bit access is available from 0x30000400 to 0x300007fe. This example uses the TS-RELAY8.

#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#include <assert.h>

// This offset is for the TS-4200 8bit SMC (FPGA)
#define BASE_ADDRESS 0x10000000

// This assumes jumper 1 is on the TS-RELAY8
#define PLD_OFFSET 0x140

unsigned short *muxbus_base;
typedef enum {
  RLYON = 0x00,
  RLYOFF = 0xFF,
  RLY1 = 1 << 0,
  RLY2 = 1 << 1,
  RLY3 = 1 << 2,
  RLY4 = 1 << 3,
  RLY5 = 1 << 4,
  RLY6 = 1 << 5,
  RLY7 = 1 << 6,
  RLY8 = 1 << 7
} RelayFlags;

static void poke8(unsigned int adr, uint8_t val) {
        muxbus_base[adr / 2] = val;
}

void set_relays(RelayFlags bits) {
    // This adds the PLD offset to talk to the TS-RELAY8
    // the 0x400 is the offset for the MUXBUS (see the FPGA Functionality section)
    // 0x2 is added for the offset of the actual relays.  See the TS-RELAY8 wiki for more details
    poke8(PLD_OFFSET + 0x400 + 0x2, bits);
    usleep(15000);
}

int main(int argc, char **argv) {
    int mem = open("/dev/mem", O_RDWR|O_SYNC);
    assert(mem != -1);
    muxbus_base = mmap(0,
         getpagesize(),
         PROT_READ|PROT_WRITE,
         MAP_SHARED,
         mem,
         BASE_ADDRESS);
    assert(muxbus_base != MAP_FAILED);

    while(1)
    {
	set_relays(RLYOFF);
        set_relays(RLY1);
        set_relays(RLY1|RLY2);
        set_relays(RLY1|RLY2|RLY3);
        set_relays(RLY1|RLY2|RLY3|RLY4);
        set_relays(RLY1|RLY2|RLY3|RLY4|RLY5);
        set_relays(RLY1|RLY2|RLY3|RLY4|RLY5|RLY6);
        set_relays(RLY1|RLY2|RLY3|RLY4|RLY5|RLY6|RLY7);
        set_relays(RLYON);
    }
    return 0;
}

UARTs

The TS-4200 brings out 7 UARTs at 0-3.3V levels, but typically the baseboard will include transceivers to bring this to RS232, RS485, or RS422. You can find resources for programming with serial ports in Linux here:

When ttyS1 is connected to an RS485 transceiver the FPGA can be configured to autmoatically toggle TX Enable. This uses the FPGA to assert TXEN when transmitting and deassert when not. You can enable this by toggling a register in the #Syscon:

# Enables auto TX Enable in FPGA for ttyS1
peekpoke 16 0x3000000A 0x756

For UART4 (ttyS5) you will need to toggle the TX enable FPGA DIO14 manually.

Device TX Location RX Location TX EN
/dev/ttyS0 CN2-93 CN2-95 N/A
/dev/ttyS1 CN2-78 CN2-80 CN1-67
/dev/ttyS2 CN2-82 CN2-84 N/A
/dev/ttyS3 CN2-86 CN2-88 N/A
/dev/ttyS4 CN2-90 CN2-92 N/A
/dev/ttyS5 CN2-94 CN2-96 CN1-63
/dev/ttyS6 CN2-98 CN2-100 N/A

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.

This example below will work with any of our TS-Socket boards running Linux. This 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;
}

The TS-4200 has 4 IRQs that can be used by external devices. See page 30 of the CPU manual for a complete listing of all of the available IRQs.

IRQ # Interrupt Condition Name Socket Location
31 Configurable [1] PC14_IRQ2 CN2-91
192 High Level IRQ5/DIO_00 CN1-93
193 High Level IRQ6/DIO_01 CN1-91
194 High Level IRQ7/DIO_02 CN1-89
  1. See the CPU manual for details on customizing this IRQ. This supports operating as a posedge or negedge interrupt
Note: IRQs 192-194 require 'pc104on' to be run to MUX these IRQs. See the #PC104 chapter.
IRQ # Interrupt Condition Name Socket Location
31 Configurable [1] PC14_IRQ2 CN2-91
192 High Level IRQ5/DIO_00 CN1-93
193 High Level IRQ6/DIO_01 CN1-91
194 High Level IRQ7/DIO_02 CN1-89
  1. See the CPU manual for details on customizing this IRQ. This supports operating as a posedge or negedge interrupt
Note: IRQs 192-194 require 'pc104on' to be run to MUX these IRQs. See the #PC104 chapter.

External Interfaces

TS-Socket

The TS-SOCKET System-on-Modules (SoMs) 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 SoM. You can find the datasheet for the baseboard's male connector here. This can be ordered from the TS-Socket SoM product page as CN-TSSOCKET-M-10 for a 10 pack, or CN-TSSOCKET-M-100 for 100 pieces, or from the vendor of your choice, the part is an FCI "61083-102402LF".

TS-Socket

We have an Eaglecad library available for developing a custom baseboard here. We also provide the entire PCB design for the TS-8200 baseboard here which you can modify for your own design.

In our schematics and our table layout below, we refer to pin 1 from the male connector on the baseboard.

Example Baseboard Please refer to your baseboard wiki or schematics for more details on which of these pins go where.

CN1 CN2
Name Pin Pin Name
FPGA_JTAG_TMS 1 2 EXT_RESET#
FPGA_JTAG_TCK 3 C 4 EN_USB_5V
FPGA_JTAG_TDO 5 N 6 SDCARD_D2
FPGA_JTAG_TDI 7 1 8 SDCARD_D3
OFF_BD_RESET# 9 10 SDCARD_CMD
BOOT_OVERRIDE 11 12 SDCARD_3.3V
SPI0_CLK 13 C 14 SDCARD_CLK
POWER 15 N 16 POWER
Reserved 17 1 18 SDCARD_D0
Reserved 19 20 SDCARD_D1
Reserved 21 22 SER_FLASH_WP
Reserved 23 C 24 Reserved
Reserved 25 N 26 Reserved
Reserved 27 1 28 Reserved
POWER 29 30 Reserved
Reserved 31 32 Reserved
Reserved 33 C 34 Reserved
Reserved 35 N 36 V_BAT
Reserved 37 1 38 Reserved
Reserved 39 40 Reserved
Reserved 41 42 Reserved
Reserved 43 C 44 Reserved
Reserved 45 N 46 Reserved
POWER 47 1 48 Reserved
Reserved 49 50 Reserved
Reserved 51 52 Reserved
Reserved 53 C 54 Reserved
Reserved 55 N 56 Reserved
Reserved 57 1 58 Reserved
Reserved 59 60 Reserved
Reserved 61 62 GND
DIO_14 63 C 64 MUX_AD15
DIO_13 65 N 66 MUX_AD14
DIO_12 67 1 68 MUX_AD13
DIO_11 69 70 MUX_AD12
DIO_10 71 72 MUX_AD11
DIO_9 73 C 74 MUX_AD10
GND 75 N 76 MUX_AD09
DIO_8 77 1 78 MUX_AD08
DIO_7 79 80 MUX_AD07
DIO_6 81 82 MUX_AD06
DIO_5 83 C 84 MUX_AD05
DIO_4 85 N 86 MUX_AD04
DIO_3 87 1 88 MUX_AD03
DIO_2 89 90 MUX_AD02
DIO_1 91 92 MUX_AD01
DIO_0 93 C 94 MUX_AD00
GND 95 N 96 BUS_ALE#
BUS_WAIT# 97 1 98 BUS_DIR
BUS_BHE# 99 100 BUS_CS#
Name Pin Pin Name
ETH_RX+ 1 2 ETH_LEFT_LED
ETH_RX- 3 C 4 ETH_RIGHT_LED
ETH_CT 5 N 6 RED_LED#
ETH_TX+ 7 2 8 GREEN_LED#
ETH_TX- 9 10 SHUT_DOWN
ETH_CT 11 12 WAKE_UP
3.3V 13 C 14 PC6
GND 15 N 16 PC0
Reserved 17 2 18 PC1
Reserved 19 20 PC2
GND 21 22 PC3_SPI_CS3#
DEV_USB_M 23 C 24 AN_VREF
DEV_USB_P 25 N 26 PA22
1.0V BU 27 2 28 TW_CLK
HOST_USB_M 29 30 TW_DAT
HOST_USB_P 31 32 PA6
1.0V 33 C 34 Reserved
HOSTB_USB_M 35 N 36 PB16
HOSTB_USB_P 37 2 38 PB17
3.3V 39 40 PB18
Reserved 41 42 PB19
Reserved 43 C 44 CPU_JTAG_TMS
GND 45 N 46 CPU_JTAG_TCK
Reserved 47 2 48 CPU_JTAG_TDI
Reserved 49 50 CPU_JTAG_TDO
GND 51 52 PB28
Reserved 53 C 54 PC8
Reserved 55 N 56 DIO_16
1.8V 57 2 58 PB20
Reserved 59 60 PB21
Reserved 61 62 PB22
1.5V 63 C 64 PB25
SPI_CS0# 65 N 66 PB26
SPI_MOSI 67 2 68 PB27
SPI_MISO 69 70 PB30
SPI_CLK 71 72 PB29
GND 73 C 74 Reserved
PC4_SPI_CS2# 75 N 76 Reserved
PC4_SPI_CS1# 77 2 78 UART0_TXD(PB4)
3.3V 79 80 UART0_RXD(PB5)
PB23 81 82 UART1_TXD(PB6)
Reserved 83 C 84 UART1_RXD(PB7)
PC9 85 N 86 UART2_TXD(PB8)
PC10 87 2 88 UART2_RXD(PB9)
PC13 89 90 UART3_TXD(PB10)
PC14_IRQ2 91 92 UART3_RXD(PB11)
DEBUG_TXD 93 C 94 UART4_TXD(PA31)
DEBUG_RXD 95 N 96 UART4_RXD(PA30)
DIO_15 97 2 98 UART5_TXD(PB12)]]
PC7 99 100 UART5_RXD(PB13)

Errata

Rev 6 FPGA cannot reboot out of the box

Synopsis A specific combination of bootrom and FPGA revision will not correctly reboot.
Severity Major
Class Software bug
Affected TS-4200 with Rev 6 FPGA and bootrom date "Sep 16 2011"
Status Software workaround available

Description:

Revision 6 of the FPGA was intended to fix a bug that would occur during the FPGA programming of the production process. While this fixed the internal issue, it presented a new issue of not allowing the TS-4200 to reboot when a `ts4200ctl -R` was issue or if the WDT expired. This has been fixed on March 22nd 2012, any boards shipped with this bootrom date will have an updated bootrom that fixes this issue.


Workaround:

The post-bootup workaround is to issue the following command:

devmem 0xfffff864 32 0x00008000

This should be issued in the fastboot shell, or added to the linuxrc. A combination of Rev 6 FPGA and a "Mar 22 2012" bootrom will not need this command any longer as the bootrom has been updated to resolve the issue.

Rev 6 FPGA 512hz clock watchdog

Synopsis When selecting the 512hz clock for the watchdog (200hz default), the watchdog can become unreliable and cause unnecessary reboots.
Severity Minor
Class Software bug
Affected TS-4200 with Rev 6 or below FPGAs
Status Fixed in REV 7, workaround available

Description:

Revision 6 and below of the TS-4200 include unreliable logic for the WDT when using the 512Hz clock.

Workaround:

Do not use the 512hz clock. The default 200hz clock is not affected.

USB Device Port Disabled By Default

Synopsis The USB Device port on the TS-4200 relies on a floating IO signal for the OS to determine whether the port is enabled or not.
Severity Minor
Class Software bug
Affected All un-patched TS-4200.
Status Kernel recompile required. See "workaround" below for patch.

Description:

The default TS-4200 kernel relies on a floating signal to determine the enable status of the USB Device port. As a result the port will work randomly or not at all on some TS-4200 systems. A kernel patch is required to fix this bug.

Workaround:

Download the current TS-4200 kernel sources from here, build and install the new kernel.

Product Change Notices

NAND Change

Synopsis The NAND chips used for the TS-4200 changed due to an end-of-life issue from our upstream provider. As a result a new version of the 'nandctl' userspace driver is required for all TS-4200 shipped on or after August 25, 2015.
Severity Major
Class Necessary software change.
Affected All TS-4200 shipped on or after August 25, 2015. The appropriate hardware is identifiable by the brand name TOSHIBA on the chip at U13.
Status New software available.

Description:

Due to an end-of-life notice from the previous provider of NAND chips used on the TS-4200, a new provider was chosen and implemented. The new TOSHIBA NAND meets all requirements set forth in the original TS-4200 specification, however due to internal differences in the hardware, a software alteration is necessary within the nandctl user-space driver.

Identification:

The affected hardware will have U13 populated by a TOSHIBA branded NAND chip. Only TS-4200 with this chip require this software change.

Necessary Action:

The most recent shipping TS-4200 image contains the required nandctl software. If this software is necessary for inclusion in further software duplication processes, it is available on the Technologic Systems FTP server. You can find the shipping SD card image at this location, and the new nandctl binary at this location. This file should be used to replace the old copy of nandctl. WARNING: This file should NOT be installed on a presently operating TS-4200. This file should only be used to replace the existing nandctl file on an SD card or other filesystem image *before* it is mounted as the TS-4200's operating system media.

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.

Trademarks

Arm9 is a trademark, and Arm is a registered trademark, of Arm Limited (or its subsidiaries) in the US and/or elsewhere.