From Technologic Systems Manuals
Jump to: navigation, search
TS-7558-BOX
TS-7558.jpg
Product Page
Image Gallery
Documentation
Schematic
Mechanical Drawing
FTP Path
Processor
Cavium Networks CNS2132
250MHz ARM9
CPU Datasheet
RAM
64MB DDR
FPGA
Lattice LFXP2 8K
Reprogrammable with Opencore
DIO
12
External Interfaces
USB 2.0 2 hosts
1x 10/100 Ethernet
1x I2C/TWI
SPI
1x CAN
2x RS232
1x RS485
Internal Storage Media
1x SD
256MB XNAND
Power Requirements
5-30VDC
Operates as low as 1.7W
Operating Temperature
Cold 0C
Hot 70C
Mechanical
191mm x 128mm x 45mm (w/enclosure)
Weight 351 (approx)

Contents

1 Overview

The TS-7558-BOX is a multi-functional industrial controller based on a Cavium 250MHz ARM9 CPU that provides industrial grade opto-isolated input/output channels.

2 Getting Started

A Linux PC is recommended for development. For developers who use Windows, virtualized Linux using VMWare or virtualbox is 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 macrocontroller. 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.

Once you have a development environment, you should continue on and power up the board.

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

The TS-7558-BOX receives power through the bottom left terminal block which accepts 5-30 VDC.

2.1 Development Kit and Accessories

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

KIT-7553 Contents
Item Description
MSD-2GB-USB-7500 A 2GB 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.
RC-DB9 The RC-DB9 brings out the 10 pin connection to a DB9. See the RC-DB9 page for the exact pinout. The red line indicates pin 1 and should be lined up with the white dot on the board.
TS-9448 The TS-9448 console board allows you to control the boot media with the switch, reset the board, and you can even boot to the offboard flash by setting JP1 on this board. The TS-9448 also brings the TTL console (ttyS0) to RS232 on a standard 10 pin header. The RC-DB9 is also pictured to bring out console. For new development, you can also instead use the TS-9449 (not included in the kit) at the same cost which brings out a USB port that can be plugged into your workstation which eliminates the requirement for a serial on your workstation.
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.
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-AMAF The CB-USB-AMAF is a USB type A male to a USB type A female adapter. This lets you easily expose the internal USB Host port externally.

The other options include:

Item Description
TS-9449 The TS-9449 console board is an alternative to the TS-9448. This board converts the TTL console to a USB serial device using an FTDI chip.
TS-7558-64-256XF-BOX-DIN The TS-7558-BOX can include a DIN rail for mounting support.


2.2 Get a Console

If you have a TS-9448, you can connect that to the 26 pin header and use the 10 pin header (labeled "Console") which will by default be the console port. If you do not have a TS-9448, you can hold the reset button for 5 seconds (until the red led lights up) and let go to switch the console port to the DB9 port using the standard 8n1, no flow control, 115200 baud rate. This will initialize xuartctl configured on port 0.

You can also telnet to the board with the default network configuration, though this will omit the TS-BOOTROM messages.

The TS-9449 is autodetected by most recent operating systems using the FTDI serial to USB chipset. In Linux, this is the ftdi_sio driver. Upon inserting this to your workstation you can get the device name from dmesg. The dmesg output is chronological order so the last output should show the connection:

 usb 2-2.1: new full speed USB device using uhci_hcd and address 4
 usb 2-2.1: New USB device found, idVendor=0403, idProduct=6001
 usb 2-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
 usb 2-2.1: Product: FT232R USB UART
 usb 2-2.1: Manufacturer: FTDI
 usb 2-2.1: SerialNumber: A501BUBF
 usb 2-2.1: configuration #1 chosen from 1 choice
 USB Serial support registered for FTDI USB Serial Device
 ftdi_sio 2-2.1:1.0: FTDI USB Serial Device converter detected
 usb 2-2.1: Detected FT232RL
 usb 2-2.1: Number of endpoints 2
 usb 2-2.1: Endpoint 1 MaxPacketSize 64
 usb 2-2.1: Endpoint 2 MaxPacketSize 64
 usb 2-2.1: Setting MaxPacketSize 64
 usb 2-2.1: FTDI USB Serial Device converter now attached to ttyUSB1
 usbcore: registered new interface driver ftdi_sio
 ftdi_sio: v1.5.0:USB FTDI Serial Converters Driver

So in this case my device is "/dev/ttyUSB1". These are allocated numerically so if you do not have another usb serial device it may be "/dev/ttyUSB0". If you do not see this device you will need to see your distribution's support for adding the ftdi_sio driver. New versions of Ubuntu/Debian/Fedora and most popular distributions include this by default.

If you're in Windows XP or above the USB FTDI driver will be autodetected if you allow it to search for drivers on Windows Update. If you go into "Device Manager" you will see the COM# device that was allocated.

Device Manager

In this example, my COM device is COM5.

The TS-9448 board connects to your workstation through a db9 serial cable. Connect the RC-DB9 to the TS-9448 lining up the red wire with the white dot on the "Console" 10 pin header. The CB-705 null modem cable which crosses the RX/TX pairs included in the kit connects to the RC-DB9. On your workstation you will need to determine which UART you are using.

Under Linux these will typically show up as /dev/ttyS0 or a similar number if they are connected through pci, or embedded in a laptop. If you're using a USB to RS232 device these will show up as /dev/ttyUSB#. On Windows you will need to check the device manager to get the COM device from the "Ports" section.


Console from Linux

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

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

Picocom is a very small and simple client.

picocom -b 115200 /dev/ttyUSB0

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

screen /dev/ttyUSB0 115200

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

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


Console from Windows

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

Device Manager Putty Configuration

2.3 Initrd / Busybox

After the board is first booted you will be at this shell:

  >> TS-BOOTROM - built Oct 12 2011 13:35:38
  >> Copyright (c) 2009, Technologic Systems
  >> Booting from SD card...
  .
  .
  .
  >> Booted from: SD card                 Booted in: 3.93 seconds
  >> SBC Model number: TS-XXXX            SBC Sub-model number: 0
  >> CPU clock rate: 250MHz               RAM size: 64MB
  >> NAND Flash size: 256MB               NAND Flash Type: 0xdcec (Samsung)
  >> MAC number: 00:D0:69:4F:6F:04        SBC FPGA Version: 7
  >> Temperature Sensor: 37.500 degC      MODE1 bootstrap: ON
  >> RTC present: YES                     Date and Time: Jan  1 1970 00:00:03
  >> MODE2 bootstrap: OFF                 SD card size: 1886MB
  >> Offboard SPI flash type: Micron      Offboard SPI flash size: 8MB
  >> XUARTs detected: 3                   CAN present: NO
  >> Linux kernel version: 2.6.24.4       Linux kernel date: Jun 8 2011
  >> Bootrom date: Oct 12 2011            INITRD date: Dec 27 2011
  >> ts7500ctl date: Jun  8 2011          sdctl date: Jun  8 2011
  >> canctl date: Jun  8 2011             nandctl date: Aug 15 2011
  >> spiflashctl date: Aug 15 2011        xuartctl date: Aug 15 2011
  >> dioctl date: Feb 10 2011             spictl date: Jan 24 2011
  >> dmxctl date: Jun  8 2011             busybox date: Jun 30 2010 (v1.14.2)
  >> ts7500.subr date: Jun 10 2011        daqctl date: Aug 15 2011
  >> linuxrc date: Aug 31 2011            rootfs date: Jan  1 1970
  >> MBR date: Jul 14 2009
  
  Type 'tshelp' for help
  # 
Note: Your version dates may be different depending on ship date and the image used.

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 '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, loads a reloadable FPGA bitstream if one is present, 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. 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 script to always boot into 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 SD or NAND, you would run this:

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

To use any of the other boot scripts, you can simply replace 'linuxrc-sdroot' with the script name mentioned above. Once you have booted to Debian you can return to the initrd by creating the file "fastboot" in root.

touch /fastboot

To automatically boot back to Debian you will need to remove this file.

The small default initrd is only 2Mbyte but there is space for approximately 800 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:

   # /bin/busybox --help
   BusyBox v1.14.2 (2009-08-07 14:43:48 MST) multi-call binary
   Copyright (C) 1998-2008 Erik Andersen, Rob Landley, Denys Vlasenko
   and others. Licensed under GPLv2.
   See source distribution for full notice.
   
   Usage: busybox [function] [arguments]...
      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:
           [, [[, ash, basename, cat, chgrp, chmod, chown, chroot, cmp, cp,
           cpio, cttyhack, cut, date, dd, depmod, devmem, df, dirname, dmesg,
           du, echo, egrep, env, expr, false, fdisk, fgrep, find, grep, gunzip,
           gzip, halt, head, hostname, hush, ifconfig, insmod, kill, killall,
           ln, login, ls, lsmod, md5sum, mdev, mkdir, mknod, modprobe, more,
           mount, msh, mv, netstat, ping, pivot_root, poweroff, printf, ps,
           pwd, reboot, rm, rmdir, rmmod, route, rx, sed, setconsole, setsid,
           sh, sleep, stty, sync, tail, tar, telnetd, test, tftp, top, tr,
           true, udhcpc, umount, unzip, usleep, uudecode, uuencode, vi, wget,
           xargs, yes, zcat

Also on the initrd are the TS specific applications: sdctl, spiflashctl, nandctl, daqctl, ts7500ctl, canctl, and xuartctl. We also provide the ts7500.subr which provides the following functions:

 cvtime()
 usbload()
 sdsave()
 spiflashsave()
 save()
 sd2spiflash()
 spiflash2sd()
 setdiopin()
 getdiopin()
 setrelay()
 setout()
 getin()
 tshelp()
 gettemp()

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 ts7500.subr file with the usbload() function.

2.4 Booting up the board

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

The TS-7558 is powered through the terminal block P2 which requires 5-30VDC. The development kit includes a wall wart power supply that can be connected to the terminal block power connector which provides 1A@12V.

Once you have applied power you should look for console output. The first output is from the bootrom:

  >> TS-BOOTROM - built Oct 12 2011 13:35:38
  >> Copyright (c) 2009, Technologic Systems
  >> Booting from SD card...
  .
  .
  .

This output will only appear on the serial console on the 26 pin header and cannot be redirected like the rest of the booting messages. The "Booting From" message will indicate your boot media. The 3 dots after indicate steps of the booting procedure. The first dot means the MBR was copied into memory and executed. The next two dots indicate that the MBR executed and the kernel and initrd were found and copied to memory.

When you first apply power to the board, the logic values on the MODE1 and MODE2 pins are latched. These signals decide if you boot from the MicroSD, XNAND, or offboard flash. Keep in mind this only includes the initial boot of the kernel and initrd, but once the initrd is booted you can load the Debian partition from the XNAND, SD, USB drive, or an NFS root regardless of your initially booted media. Most common cases will boot from only one media.

The typical case for a production unit does not contain the development boards so you can just use the "SD Boot" jumper to control the boot device. If the SD boot jumper is on as expected it will boot to the MicroSD slot if there is a card available. If there is no jumper then it will boot to XNAND. If the SD card is not detected on boot, it will fall back to the XNAND. The XNAND however will not fall back to the SD card. Both the MODE1 and MODE2 signals are also available on the #26 Pin Header and can be influenced by the TS-9448/TS-9449 development boards.

The MODE1 and MODE2 signals both have 4.7k pull-ups. For a logic 0 these should be pulled to ground with a 680ohm resistor.

Boot Modes
Booot Device MODE1 MODE2
XNAND 1 1
SD Card 1 0
Offboard Flash 0 1

The offboard SPI flash is only present with the TS-9449/TS-9448. The TS-9449 shows the MODE signals with an LED. The TS-9448 controls the modes through the switch, and JP1.

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

3.1 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/mmcblk0p1' 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.

From Workstation


Backup

Entire SD card

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

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

Kernel

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

Initrd

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

From SBC


Backup

Entire card

# Determine the block size
eval $(sdctl)
dd if=/dev/nbd5 of=/path/to/backup.dd bs=512 count=$cardsize_sectors conv=sync && sync

Kernel

sdctl -R 4096 -z 512 --seek part1 > kernel

Initrd

sdctl -R 4096 -z 512 --seek part2 > initrd

Restore

The entire card from SBC

dd if=/path/to/2gbsd-noeclipse-latest.dd bs=512 conv=sync of=/dev/nbd5 && sync

Kernel

dd if=/mnt/root/zImage bs=512 conv=sync of=/dev/nbd7 && sync

Initrd

dd if=/mnt/root/initrd bs=512 conv=sync of=/dev/nbd8 && sync

3.2 XNAND

This needs to be done directly on the SBC. If you are running from the SD card the XNAND will not be mounted by default. You can also boot to the initrd of the XNAND and unmount the xnand:

umount /mnt/root
WARNING: Rewriting the XNAND from a Debian filesystem on the XNAND will result in a corrupted image.

You can find the latest xnand image here. Once downloaded you can decompress the image using bzip2:

bzip2 -d xnandimg-latest.dd.bz2

The resulting file will be "xnandimg-latest.dd".

Backup

To backup the entire image containing the MBR/Kernel/Initrd/Debian you can run one command:

nandctl -XR 2048 -z 131072 > /path/to/backup.dd

To backup the current kernel:

nandctl -XR 4096 -z 512 --seek part1 > /path/to/kernel

To backup the initrd:

nandctl -XR 4096 -z 512 --seek part2 > /path/to/initrd

Restore

To write the entire image containing the MBR/Kernel/Initrd/Debian you can run one command:

nandctl -XW 2048 -z 131072 -i /path/to/xnandimg-latest.dd

To write a new kernel:

dd if=zImage bs=512 conv=sync | nandctl -X -W 4095 -k kernel -z 512 -i -

To write a new initrd:

dd if=initrd bs=512 conv=sync | nandctl -X -W 4095 -k initrd -z 512 -i -

3.3 Offboard SPI Flash (TS-9448)

This needs to be done directly on the SBC. You can find the latest SPI image here. Once downloaded you can decompress the image using bzip2:

bzip2 -d 4mb-spiflash-latest.dd.bz2

Some of this series contains a 4MB SPIflash embedded on the board that can be written to by specifying lun 0, or "-l 0" which will use that chip select. The offboard flash found on various baseboards, or console boards like the TS-9448 or TS-9449 can be written to using lun 1, or "-l 1".

Backup

Backup the entire SPI flash containing the MBR, Kernel, and initrd

spiflashctl -l 1 -R 64 -z 65536 > spiflash.dd

Backup only the Kernel

spiflashctl -l 1 -R 4095 -z 512 -k part1 > /temp/zImage

Backup only the Initrd

spiflashctl -l 1 -R 32 -z 65536 -k part2 > /temp/initrd

Restore

Write the entire SPI flash containing the MBR, Kernel, and initrd

spiflashctl -l 1 -W 64 -z 65536 -i /path/to/4mb-spiflash-latest.dd

Write a new Kernel

spiflashctl -l 1 -W 4095 -z 512 -k part1 -i /temp/zImage

Write a new Initrd

spiflashctl -l 1 -W 32 -z 65536 -k part2 -i /temp/initrd

3.4 Fastboot Recovery Commands

Since the Aug 5 2010 release, scripts have been added to the bash subroutine to ease in saving, recovering, and moving around images from one flash device to another. Below is a brief list of the commands that are provided as well as what they do. See the file /ts7500.subr (or /initrd/ts7500.subr from full Debian) for more information on the commands and what they do.

 save - Copy current initrd ramdisk to the media that the SBC is booted from
 sdsave - Copy current initrd ramdisk to mSD card
 sd2nand - Copy mSD kernel and initrd to NAND
 sd2flash - Copy mSD kernel and initrd to on-board SPI flash
 sd2flash1 - Copy mSD kernel and initrd to off-board SPI flash
 flash2sd - Copy booted SPI flash kernel and initrd to mSD card
 flashsave - Copy current initrd ramdisk to on-board flash (TS-7500 only)
 flash1save - Copy current initrd ramdisk to off-board flash (TS-752 or TS-9448)
 flash2flash - Copy booted SPI flash kernel and initrd to opposing SPI flash device (on-board to off-board and vice versa)
 flashallsave - Copy current initrd ramdisk to all SPI flash (on-board and off-board)
 nand2sd - Copy NAND flash kernel and initrd to mSD card
 nandsave - Copy current initrd ramdisk to NAND
 nand2flash - Copy NAND flash kernel and initrd to off-board flash
 flash2nand - Copy booted SPI flash kernel and initrd to NAND
 recover - Attempt to copy booted kernel and initrd to all other available flash devices

3.5 Partition Layout Example

75XX Partition Layout

4 System Configuration

For development it is recommended to go boot to the full Debian where there is plenty of space for development work. Debian provides many more packages and a much more familiar environment for users already versed in Debian. Once here you can use apt-get to install/remove packages, configure the network, and perform other common tasks.

4.1 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
pump -i eth0
# Or if you're on a baseboard with a second ethernet port, you can use that as:
pump -i eth1

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

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.

4.2 Installing New Software

Debian provides the apt-get system which lets you manage prebuilt 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.

Debian Lenny has been moved to archive so you will need to update /etc/apt/sources.list to contain these two lines:

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

Now you can update the local cache of packages:

apt-get update

For example, if you wanted to install picocom you could use the apt-cache command to search the local cache of Debian's packages.

 root@ts7500:~# apt-cache search picocom
 picocom - minimal dumb-terminal emulation program
            

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 picocom
# You can also chain packages to be installed
apt-get install picocom nano vim

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

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

passwd root

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

4.4 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)
     /usr/local/bin/ts7500ctl --redledon
     ## If you are launching a daemon or other long running processes
     ## this should be started with
     # nohup /usr/local/bin/yourdaemon &
     ;;
   stop)
     /usr/local/bin/ts7500ctl --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 the required lines (no need for the Debian init syntax) to 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.

4.5 802.11 Wireless Network

This board optionally supports 802.11 through the #WIFI-N-USB module which will create the interface ra0 using the rt3070sta module. You can load this by running:

modprobe rt3070sta-7500

Scan for a network

ifconfig ra0 up
 
# Scan for available networks
iwlist ra0 scan

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

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

To connect to this open network:

iwconfig ra0 essid "default"

You can use the iwconfig command to determine if you have authenticated to an access point. Before connecting it will show something similar to this:

# iwconfig ra0
rausb0    RT73 WLAN  ESSID:off/any  Nickname:""
          Mode:Auto  Frequency=2.412 GHz  Bit Rate:54 Mb/s   
          RTS thr:off   Fragment thr:off
          Encryption key:off
          Link Quality=0/100  Signal level:-121 dBm  Noise level:-115 dBm
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

If you are connecting using WEP, you will need to define a network key:

iwconfig ra0 essid "default" key "yourpassword"

If you are connecting to WPA, you will need to use wpa_passphrase and wpa_supplicant:

wpa_passphrase the_essid the_password > /etc/wpa_supplicant_custom.conf

You will need to edit the /etc/wpa_supplicant_custom.conf file so the network block contains "proto=RSN". For example:

  network={
        ssid="default"                     
        proto=RSN
        #psk="yourpassword"
        psk=your-key-encoded                                                
  }

The default image contains a patched wpa_supplicant for an older device, but for the WIFI-N-USB you will need to remove this and use the version from Debian:

mv /usr/local/bin/wpa_supplicant /usr/local/bin/wpa_supplicant.old
apt-get update && apt-get install wpasupplicant #This assumes a proper internet connection is established
 
# reset the shell to find the new wpa_supplicant
exec bash
 
# Verify that it is the correct version (0.6.4):
wpa_supplicant -v

Now that you have the configuration file, you will need to start the wpa_supplicant daemon:

wpa_supplicant -irausb0 -Dralink -c/etc/wpa_supplicant_custom.conf -B

When you have successfully connected, it will list an "Access Point" bssid, and a "Link Quality" of greater than 0/100.

# iwconfig rausb0
rausb0    RT73 WLAN  ESSID:"default"  Nickname:""
          Mode:Managed  Frequency=2.417 GHz  Access Point: c0:ff:ee:c0:ff:ee  
          Bit Rate=11 Mb/s   
          RTS thr:off   Fragment thr:off
          Encryption key:off
          Link Quality=63/100  Signal level:-70 dBm  Noise level:-99 dBm
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

Now you are connected to the network, but this would be close to the equivilant of connecing a network cable. To connect to the internet or talk to your internal network you will need to configure the interface. See the #Configuring the Network for more information.

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

The most common method of development is directly on the SBC. Since debian has space available on the SD card, we include the gnu compiler collection package which comes with everything you need to do C/C++ development on the board. To get started, this is how you could build a hello world application:

nano hello.c

This will open a blank file with nano which is a very simplistic editor. Enter in your hello world code:

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

To save this in the editor, press "ctrl+x", type "y" to save and press enter to leave the editor. You you can use the gcc tools to compile this:

gcc hello.c -o hello
 
./hello

This should return your "Hello World!" text. There are far more tools you can learn to aid in your development as well:


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.

5.1 Cross Compiling

While the onboard tools are recommended for development, some applications can reach a size where the compile time is not feasible. An example of this is the Linux Kernel which will take 5-10 minutes to compile on a typical X86 workstation, but it can take 7-15 hours to compile on the SBC depending on several factors. A hello world application in comparison will take only a couple seconds on the board.

Cross compiling has a complication in that the onboard libraries do not exactly match the cross compiler environment. Debian has around 15,000 to 20,000 packages available in the apt repositories, and there is no way to feasibly build a cross compiler to account for all of these libraries. If you are cross compiling you will need to have your application entirely self contained and linking to any third party libraries in your build system.

There are two toolchains that can be used depending on your application. Most applications should use this toolchain which compiles applications to use Debian's glibc 2.7 libraries. You can compile using this toolchain by calling the version of gcc in the archive:

 usr/local/opt/crosstool/arm-linux/gcc-3.3.4-glibc-2.3.2/bin/arm-linux-gcc

The second toolchain is using the uClibc compiler here. uClibc has some limitations in order to reduce the binary size, but will also work for many simple C applications. All of our included ctl applications are built using this toolchain. Using this compiler also allows you to compile binaries that do not rely on the Debian filesystem. While this does have a g++ compiler, we do not include any c++ support in the initrd. You can compile with this toolchain by calling this version of gcc in the archive:

 arm-uclibc-3.4.6/bin/arm-linux-uclibc-gcc
Note: We do not support third party cross compilers.
Note: The provided cross compilers are only for C development.

5.2 Kernel Compile Guide

The TS kernel is built from the same Linux sources Cavium Networks has tested and used on their CPU evaluation boards. There are no Technologic Systems specific drivers or kernel support implemented. Instead, there has been userspace driver support implemented for the SPI NOR flash, MicroSD cards, XNAND drive, battery-backed real-time clock, XUART serial port channels, watchdog, and GPIO pins. This allows easy migration to newer kernels when either Cavium or the mainline Linux kernel community creates them. In the past, constant Linux-internal API redesign required rewriting and revisiting custom drivers with each new kernel revision, in effect locking customers in to whatever kernel version was released and tested during initial product release. Being free to update to newer kernels in the future allows easier support of the new USB devices as those drivers tend to only be developed for the newest kernel sources.

We provide Linux 2.6.24 as the supported kernel.

WARNING: Backup any important data on the board before replacing the kernel.

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 (OABI)from Technologic Systems:
wget ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/cross-toolchains/crosstool-linux-arm-uclibc-3.4.6.tar.gz
 
#Extract to current working directory:
tar xvf crosstool-linux-arm-uclibc-3.4.6.tar.gz
 
#Download the Cavium Sources
wget ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/linux-2.6.24-ts-src-aug102009.tar.gz
 
#Extract the Kernel Sources
gzip -dc linux-2.6.24-ts-src-aug102009.tar.gz | tar xf -
 
cd linux-2.6.24-cavium/
 
export ARCH=arm
export CROSS_COMPILE=../arm-uclibc-3.4.6/bin/arm-linux-
 
# This sets up the default configuration for the Cavium CPU
make ts7500_defconfig
Note: If you get the message "Make: *** mixed implicit and normal rules. Stop." Then you may need to downgrade your version of make.
make menuconfig

This will bring up a graphical menu where you can edit the configuration to include support for new devices. For Example, to include CIFS support, use the arrow and Enter keys to navigate to Filesystems -> Network File Systems -> CIFS Support. Press "y" to include CIFS support into the kernel (alternatively, you could modularize the feature with "m" so you can enable or disable the module on demand which will also enable you to simply copy/paste the cifs.ko into the correct path in the kernel instead of copying the entire kernel (outlined below in appendix)). Keep hitting "exit" until you're prompted to save changes, choose "yes".

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

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.

Now we need to install the modules.

mkdir newmodules
INSTALL_MOD_PATH=newmodules make modules_install
 
#Replace /dev/sdb with your sd card
mkdir /mnt/miniSD4
mount /dev/sdb4 /mnt/miniSD4/
 
#Remove existing modules:
rm -r /mnt/miniSD4/lib/modules/*
cp -r newmodules/* /mnt/miniSD4/
 
umount /mnt/miniSD4

After you install the new modules, you will need to boot the kernel and run "depmod -a" to rebuild the dependency map. You can them use modprobe to load the individual modules.

You can also copy individual modules to your existing kernel assuming the kernel is the exact same version as the installed one.

If you require functionality from a newer kernel, we also provide sources for the 2.6.36 kernel patched with support as-is. You can find the sources here. You will need to also use this toolchain. The rest of the steps for building the kernel are the same. This kernel should function the same as the other, however the USB device driver is not implemented. We strongly suggest using the 2.6.24 kernel unless you have a requirement for a later kernel as the 2.6.24 is supported and has gone through much more testing through various productions.

We also now have a copy of a 3.4.0 kernel source here. These same instructions are applicable but you will need to use this toolchain instead of the one used with 2.6.24.

6 Features

6.1 CPU

This board features a CNS2132 250MHz ARM9 processor. For more details see the CPU Datasheet.

6.2 I2C

The I2C_SCL and I2C_SDA pins bring out the I2C bus from the CNS2132 CPU. We do have an example for connecting to the I2C bus that uses the temperature sensor used on some of this series. You can find the C example here.

Please refer to the CNS2132 user's guide, page 55, 144, and 312 for more information on this I2C bus.

6.3 USB Host

The Cavium CPU supplies standard USB 2.0 ports. The power to the USB can also be toggled by setting a DIO.

# This is sourced in the initrd, but if you are running
# from Debian you will need to source the subroutine file.
source /initrd/ts7500.subr
 
# Power off USB
setdiopin 7 0
 
# Power on USB
setdiopin 7 1

6.4 FPGA

If you are accessing any registers here manually, you will need to acquire the SBUS lock.

Top Level Decode
SBUS Address Function
0x0 SD Card
0x10 NAND Flash
0x20 XUART memwindow
0x40 SPI Interface
0x50 DAQ core
0x60 Syscon

6.4.1 FPGA Programming

Note: We do not provide support for the opencores under our free support, however we do offer custom FPGA programming services. If interested, please contact us.

The opencore FPGA sources are available here.

We have prepared the opencore projects which gives you the ability to reprogram the FPGA while either preserving or removing our functionality as you choose. The code sources are in verilog, and we use Lattice Diamond to generate the JEDEC file. You can download Lattice Diamond from their site. You can request a free license, and it will run in either Windows or Linux (only Redhat is supported). In the sources you can find the functionality switches in the <boardname>_top.v file:

parameter sdcard_opt = 1'b1;
parameter spi_opt = 1'b1;
parameter nandflash_opt = 1'b1;
parameter can_opt = 1'b1; /*If CAN is enabled, only two XUARTs can be used*/
/* software currently requires these to be enabled/disabled contiguously. */
parameter xuart0_opt = 1'b1;
parameter xuart1_opt = 1'b1;
parameter xuart2_opt = 1'b0;
parameter xuart3_opt = 1'b0;
parameter xuart4_opt = 1'b0;
parameter xuart5_opt = 1'b0;
parameter xuart6_opt = 1'b0;
parameter xuart7_opt = 1'b0;

You can use these switches to enable and disable functionality. We do not enable everything at the same time because of space constraints on the FPGA. So for example, to disable CAN and enable the rest of the XUARTS:

parameter sdcard_opt = 1'b1;
parameter spi_opt = 1'b1;
parameter nandflash_opt = 1'b1;
parameter can_opt = 1'b0; /*If CAN is enabled, only two XUARTs can be used*/
/* software currently requires these to be enabled/disabled contiguously. */
parameter xuart0_opt = 1'b1;
parameter xuart1_opt = 1'b1;
parameter xuart2_opt = 1'b1;
parameter xuart3_opt = 1'b1;
parameter xuart4_opt = 1'b1;
parameter xuart5_opt = 1'b1;
parameter xuart6_opt = 1'b1;
parameter xuart7_opt = 1'b1;

For more advanced changes you may look to opencores.org which has many examples of FPGA cores. To build the FPGA with your new changes, go to the 'Processes' tab and double-click 'JEDEC File'. This will build a jedec file in the project directory. On a linux system, either x86 compatible or ARM, we provide an application called jed2vme.

jed2vme for x86

jed2vme for ARM (oabi)

We also have the sources here.

WARNING: Do not use the 'jed2vme' provided by Lattice. Their version writes to flash and as the opencores do not contain the bootrom so this will brick your board.

jed2vme can be used like this:

jed2vme bitstream.jed | gzip > bitstream.vme.gz

To execute this on your board run this:

ts7500ctl --loadfpga=bitstream.vme
# or
ts7500ctl --loadfpga=bitstream.vme.gz

As space is constrained in the initrd it is suggested to gzip the file as shown in the jed2vme example. To load this bitstream automatically you can place it in the root of the initrd and name it '/ts7500_bitstream.vme.gz'. The linuxrc script will by default load this bitstream immediately on startup (before the fastboot shell). You should first test it manually to make sure it loads ok.

The FPGA contains flash memory which contains Technologic System's default FPGA flash load. Using an SRAM bitstream generated by our "jed2vme" with "ts7500ctl --loadfpga" will not overwrite the flash memory of the FPGA and will only load the SRAM contents of the FPGA, making for an unbrickable system.

6.5 XUARTs

The XUARTs are userspace implemented seial devices. See the xuartctl page for more information on working with these UARTs.

6.6 Battery powered RTC

The RTC connects through I2C to the FPGA. Typically, the battery-backed real time clock is only set or read in the linuxrc bootup script by the ts7500ctl utility. It is only necessary to read the RTC once per bootup to initialize the Linux time of day. This is done with the command "ts7500ctl --getrtc". To set the RTC time, you simply set the Linux time of day (with e.g. the "date" utility) and then run ts7500ctl --setrtc. RTC's are already set before shipment to atomic UTC time and should hold time within 15 PPM while at room temperature.

WARNING: Be careful when handling board with a battery inserted -- the battery holder leads are through-hole and should the board be placed on a conductive surface and short the battery leads, the RTC will loose its track of time and need to be reset.

6.7 XNAND

The XNAND is our layer of software and an FPGA core 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 report their size as SIZE_MAX for more flexibility when using them with nandctl. If you are formatting a partition or using dd you will need to specify the size of the block device or partition.

For more information on the XNAND layer, see this page.

6.8 SD

This product contains our SD controller implemented in the FPGA. This will support both SD and SDHC cards, sizes up to 32GB are supported. The SD card access is implemented in userspace by acting as an NBD server. The sdctl page which will show more advanced usage and the linuxrc script will bring up the nbd-clients in this layout:

 /dev/nbd5 - whole disk device of microSD card
 /dev/nbd6 - 1st partition of SD card (Windows VFAT filesystem on devkit card)
 /dev/nbd7 - 2nd partition of SD card (kernel partition on devkit card)
 /dev/nbd8 - 3rd partition of SD card (EXT2 initrd partition on devkit card)
 /dev/nbd9 - 4th partition of SD card (Debian EXT3 filesystem on devkit card)
Note: NBD devices report their size as SIZE_MAX for more flexibility when using them with sdctl. If you are formatting a partition or using dd you will need to specify the size of the block device or partition.

6.9 SPI

This core is for high speed SPI with auto-CS#. Starts at offset 0x40 on the this series. Chip select #0 is typically used for onboard spiflash. Chip select #1 is used for offboard spiflash. The last 2 chip selects are always available on the Cavium series boards.

The SPI controller is an FPGA core which is accessed using spictl. The simplest method for communication is calling spictl through bash:

# Read 32 bytes from LUN1
spictl --lun=1 --readstream=32
 
# Write Hello (68:65:6c:6c:6f)
spictl --lun=1 --writestream=68:65:6c:6c:6f

Usage:

ts7500:~# spictl --help
Technologic Systems SPI controller manipulation.

General options:
-c | --clock=frequency    SPI clock frequency
-e | --edge=value         set clock edge (positive for > 0, negative for < 0)
-w | --writestream=data   write colon delimited hex octets to SPI
-d | --readwrite=data     write colon delimited hex octets to SPI while reading to stdout
-r | --readstream=bytes   read specified number of bytes from SPI to stdout
-o | --holdcs             don't de-assert CS# when done
-l | --lun=id             Talk to specified chip number
-s | --server=<port>      Daemonize and run as server listening on port
-p | --port=<host><:port> Talk to spictl server
hex octets are hexadecimal bytes. for example,
this command reads 32 bytes of CS#1 SPI flash from address 8192:
./spictl -l 1 -w 0B:00:20:00:00 -r 32

The spictl utility can also run as a TCP server which lets you easily access SPI in your application. To start the tcp server on port 7755:

spictl --server=7755

The data stream packet to a spictl server consists of opcodes and operands. Each opcode is one byte long and may encode part or all of the operand. Some opcodes specify that additional bytes of data follow to contain the remainder of the operands.

There are four opcodes encoded in the two msb of the opcode byte:

  • OPCODE 0 = CHIP SELECT
    • The chip number is encoded in the two LSB.
      • 00 = CS#0
      • 01 = CS#1
      • 10 = CS#2
      • 11 = CS#3
    • If Bit 5 is set, OPCODE = ASSERT CHIP SELECT.
    • Then If Bit 3 is set, Bit 2 is the new SPI edge to use (1 = positive edge, 0 = negative edge). Also, two additional bytes follow as operands. These two bytes are a big-endian encoded clock value. This value multiplied by 2048 is the SPI clock frequency to use. If Bit 5 is clear, OPCODE = DE-ASSERT CHIP SELECT
  • OPCODE 1 = READ
    • The number of bytes to read must be a power of two, encoded in the 6 lsb. These six bits represent the number to raise 2 to the power of to get the length. So,
      • 00_0000 = 1 byte
      • 00_0001 = 2 bytes
      • ...
      • 00_1100 = 4096 bytes
  • OPCODE 2 = WRITE
    • The number of bytes to write is encoded in the same manner as for a READ opcode. After the opcode byte, the number of bytes to write follows as the operands.
  • OPCODE 3 = READWRITE
    • This opcode encodes identically as the WRITE opcode. However it specifies that bytes are to be READ as well as written.

You can also use the spictl --server=<port> and run a second invokation of spictl with --port=<port> to have the second instance act as a client to the server. You can then use tcpdump to see the exact tcp packets being sent back and forth for various operations.

The table below is the register map for the SPI in the FPGA:

Offset Access Bit(s) Description
0x40 Read Only 15 SPI MISO state
Read/Write 14 SPI CLK state
Read/Write 13:10 Speed - 0 (highest), 1 (1/2 speed), 2 (1/4 speed)...
Read/Write 9:8 LUN (0-3 representing the 4 chip selects)
Read/Write 7 CS (1 - CS# is asserted)
N/A 6:1 Reserved
Read/Write 0 Speed
0x42 Read Only 15:0 Previous SPI read data from last write
0x44 N/A 15:0 Reserved
0x46 N/A 15:0 Reserved
0x48 Read/Write 15:0 SPI read/write with CS# to stay asserted
0x4a Read Only 15:0 SPI pipelined read with CS# to stay asserted
0x4c Read/Write 15:0 SPI Read/Write with CS# to deassert post-op
0x4e N/A 15:0 Reserved

The SPI clk state register should be set when CS# is deasserted. Value 0 makes SPI rising edge (CPOL=0), 1 is falling edge (CPOL=1). This only applies to speed >= 1. For speed == 0, SPI clock polarity/skew must be set from the PLL phase adjust registers in the syscon block.

Where the base clock is 75Mhz (extended temp alters this to 50Mhz), speed settings break down as follows:

 0 - 75Mhz (/1)
 1 - 37.5Mhz (/2)
 2 - 18.75Mhz (/4)
 3 - 12.5Mhz (/6)
 4 - 9.375Mhz (/8)
 5 - 7.5Mhz (/10)
 6 - 6.25Mhz (/12)
 7 - 5.36Mhz (/14)
 8 - 4.68Mhz (/16)
 9 - 4.17Mhz (/18)
 ...
 15 - 2.5Mhz (/30)
 ... 
 19 - 1.97MHz (/38)
 ...
 31 - 1.21MHz (/62)

Bits 10-15 were not present on TS-75XX FPGA prior to rev 4. On those TS-75XX's, SPI speed was hardcoded to 75Mhz and 75Mhz only.

The pipelined read register is for read bursts and will automatically start a subsequent SPI read upon completion of the requested SPI read. Reading from this register infers that another read will shortly follow and allows this SPI controller "a head start" on the next read for optimum read performance. This register should be accessed as long as there will be at least one more SPI read with CS# asserted to take place. This register is an appropriate target address for SBUS burst reads.

6.9.1 SPI Flash

The SPI flash is also implemented in userspace with NBD, however it is not mounted or running by default. Even when you are booted to SPI, it does not need to access it directly since the bootrom will load it into memory before the Linux kernel is even executing. If you want to mount any part of it see the spiflashctl page for usage.

6.10 DAQ Core

The DAQ core is a core in the FPGA that abstracts usage of the ADC, digital inputs, digital outputs, PWM, counters, and quadrature. These features are intended to be used with daqctl to access these I/O, or libdaqctl which can be used from C/C++.

The DAQ core includes 16 input channels including the following:

Number Name Description
0 ADC channel #0 [1] 3.3V * 43.2kohm/(43.2kohm + 47kohm)
1 ADC channel #1 [1] Voltage in * 43.2kohm/(43.2kohm + 221kohm)
2 ADC channel #2 [1] Ground
3 ADC channel #3 [1] 5V / 2
4 ADC channel #4 (AD1) External ADC channel #0
5 ADC channel #5 (AD2) External ADC channel #1
6 ADC channel #6 (AD3) External ADC channel #2
7 ADC channel #7 (AD4) External ADC channel #3
8 Quadrature counter delta #0 IN5 as A, IN6 as B
9 Quadrature counter delta #1 IN7 as A, IN8 as B
10 Current state of all inputs IN8(MSB)-IN1(LSB)
11 Counter delta #0 Counts posedges on IN1
12 Counter delta #1 Counts posedges on IN2
13 Counter delta #2 Counts posedges on IN3
14 Counter delta #3 Counts posedges on IN4
15 Glitch reg or timestamp [2]
  1. 1.0 1.1 1.2 1.3 Channels 0-3 can be used as reference voltages for additional calibration in your application.
  2. Channel 15 normally sets any bit as a one if it detects, during the course of the immediately preceeding sample period, any momentary change of a digital input. However, if the external trigger is enabled, this returns the latched value of a 12-bit up-counter that counts up at the rate of the sample period as programmed in register base + 0x4.

See the daqctl page for more details and code examples for libdaqctl.

6.10.1 ADC

The TS-7558 includes a single high speed 200ksps 12-bit SPI ADC is connected to a 8 channel analog mux. After the mux, there is an op-amp circuit with a FET connected under FPGA control that adds 2x gain stage before feeding to the SPI National Semiconductor ADC121S021 ADC chip. 4 channels are offboard, and 4 are connected to onboard rails. The ADC inputs can handle 0-10V, 0-5.5V, or 4-20mA. The ADC inputs are found on P2 and P4. See the DAQ section for more information about ADC channels.

To sample the ADC inputs:

daqctl --dumpcsv --chan=0-7 --speed=100hz

This will dump all of the ADC values to the console (stdout) at 100hz. Each channel is separated by a comma, and the output value is 0-4096 which represents 0-3.3V that comes in to the ADC itself. In order to calculate each channels voltages, please use the following equations:

All values are provided in whole integer numbers where possible

Channel Equation
CH0 Voltage=((3.3/4096)*(Value/Gain))/(43200/(43200+47000)) [1] [2] [3]
CH1 Voltage=((3.3/4096)*(Value))/(21600/(21600+221000)) [1] [2] [4]
CH2 Voltage=((3.3/4096)*(Value/Gain))[1] [2] [3]
CH3 Voltage=((3.3/4096)*(Value))*2 [1][2] [4]
CH4-7 Voltage=((3.3/4096)*(Value/Gain))/(22510/(22510+47000))[1] [2] [3]
CH4-7 Current=((3.3/4096)*(Value/Gain))/(22510/(22510+47000))/220 [5] [2] [3] [6]
  1. 1.0 1.1 1.2 1.3 1.4 Voltage=Voltage detected in Volts
  2. 2.0 2.1 2.2 2.3 2.4 2.5 Value=Value returned from daqctl
  3. 3.0 3.1 3.2 3.3 Gain=2 if using --gain2x, otherwise 1
  4. 4.0 4.1 Do not use --gain2x with this channel
  5. Current=Current detected in Amps
  6. Using --gain2x is recommended with this channel


The --gain2x option can be used to read the channels at 0-5.5V, or use --cloop to specify the channels that will read 4-20mA inputs.

# Reads all ADC channels at 200hz, but channel 6-7 are 4-20mA inputs,
# channel 4 is 0-5V and channel 5 is 0-10V
daqctl --dumpcsv --chan=4-7 --cloop=6,7 --gain2x=4 --speed=200hz

You can read more about the ADC implementation on the daqctl page which also includes code examples for working with libdaqctl.

6.10.2 Digital Inputs

The opto isolation will be the limitation toggling and sampling the inputs. The digital inputs can handle a maximum of 80khz. The opto-isolators have a typical rise time of 3µs, and a maximum of 18µs. The fall time is 4µs, and the maximum is 18µs. See the FOD817D datashsheet for more information. Using daqctl the inputs are all mapped to channel 10. To read all inputs:

daqctl --speed 100hz --channel=10 --dumpcsv

This will return a long integer where the state of these inputs is reflected in the lower 8 bits. See the daqctl page for more details and code examples for libdaqctl.

6.10.3 Digital Outputs

The daq core supports 7 output channels:

Number Name
0 OUT1
1 OUT2
2 OUT3
4 OUT4
5 DIO_23 from the #26 Pin Header
5 DIO_25 from the #26 Pin Header
6 DIO_21 from the #26 Pin Header

These are accessed using daqctl or libdaqctl. The simplest usage of logic 0 or 1 is set using:

#Set OUT1 and OUT2 to a logic high
daqctl --pwm 0-1:1
# Set OUT3 and OUT4 to a logic low
daqctl --pwm 2-3:0

You can also set the outputs to PWM using the same [[Daqctl#PWMSPEC|PWM specification]:

# Turn all 8 PWM channels to 30% at 5khz
daqctl --pwm=0-7:30%@5khz
# Use IN1 as the external trigger for the frequency
daqctl --pwm=6:30%@EXT0

6.10.4 DAQ Core Register Map

The DAQ core can be accessed through the SBUS manually at 0x50. The supported and recommended interface is using daqctl or libdaqctl which also allow simpler migration to new products with the DAQ core. The register map is provided for those who intend to implement their own software mechanism for accessing the I/O.

Offset Bits Access Description
0x0 15-0 Read/Write Channel enable #15 (MSB) through #0 (LSB) (1 is enabled)
0x2 15 Read/Write Sampling Enable
14 Read Only Overflow (clears after read)
13 Read/Write Interrupt mood (1 is interested)
12 N/A Reserved
11-0 Read Only Next buffer num to fill (0-4095 for 8kbyte total buffer)
0x4 15 Read/Write Sample period time scale (1 is ms, 0 is us)
14-0 Read/Write value (4096 is 4097µs period)
0x6 15 Read/Write External sample trigger enable
14-12 Read/Write External trigger input number (0-7) (triggers on posedge)
11-8 Read/Write Current loop enable on chans #3 (MSB) - #0 (LSB)
7-0 Read/Write Gain 2x enable on chans #7 (MSB) to #0 (LSB)
0x8 15 Read/Write When any digital input changes
14 Read/Write When any enabled counters change
13 Read/Write When a quadrature counter changes direction
12 Read/Write When a quadrature counter changes value
11 Read/Write When one particular digital input
10-9 Read/Write 0 - Changes State

1 - Glitches (a change >= 25ns but <= sample period)
2 - Is high
3 - Is low

8-5 Read/Write If bit 14 is enabled, which digital input? (0-7)
4-3 Read/Write 0 - 1 sample

1 - 4 samples
2 - 16 samples
3 - 64 samples

2 Read/Write Interrupt rate duration

0 - Until interest criteria is no longer met
1 - Forever (requires reset via write to bit 13, reg 0x2)

1-0 Read/Write Interrupt when not interested

0 - When buffer is half full
1 - Every 1ms
2 - Every 2ms
3 - Every 10ms

0xa 15-0 Read/Write Return core type (0x7558 or 0x1978)
0xc 15-0 PWM output controller Read/Write
0xe 15-8 Reserved Read Only
7-0 IN8-IN1 Read Only

6.11 Syscon

The Syscon is an FPGA core that presents various configuration registers for the board. These registers are accessed through the SBUS. For example, to read the "Model ID" register:

ts7500ctl --address=0x60 --peek16

See the SBUS page for more details on using the SBUS in your application.

Offset Bits Access Function
0x60 15-0 Read Only Model ID
0x62 15 Read/Write Green LED (1 = on)
14 Read/Write Red LED (1 = on)
13 Read/Write RTC SCL input
12 Read/Write RTC SDA input
11 Read/Write RTC SCL direction (1 - output)
10 Read/Write RTC SDA direction (1 - output)
9 Read/Write RTC SCL output
8 Read/Write RTC SDA output
7-4 Read Only Board submodel
3-0 Read Only FPGA revision
0x64 15-0 Read Only 16-bits of random data changed every 1 second.
0x66 15-12 Read Only DIO input for pins 40(MSB)-37(LSB)
11-8 Read/Write DIO output for pins 40(MSB)-37(LSB)
7-4 Read/Write DIO direction for pins 40(MSB)-37(LSB) (1 - output)
3 Read/Write Lattice tagmem clock
2 Read/Write Lattice tagmem serial-in (RW)
1 Read/Write Lattice tagmem CSn
0 Read Only Lattice tagmem serial-out (RO)
0x68 15-0 Read Only DIO input for pins 36(MSB)-21(LSB)
0x6a 15-0 Read Only DIO output for pins 36(MSB)-21(LSB)
0x6c 15-0 Read/Write DIO direction for pins 36(MSB)-21(LSB) (1 - output)
0x6e 15-0 Read/Write DIO input for pins 20(MSB)-5(LSB)
0x70 15-0 Read/Write DIO output for pins 20(MSB)-5(LSB)
0x72 15-0 Read/Write DIO direction for pins 20(MSB)-5(LSB) (1 - output)
0x74 15-0 Write Only #Watchdog feed register
0x76 15-11 N/A Reserved
10-6 Read/Write PLL phase (set by TS-BOOTROM)
5 Read Only mode3 latched bootstrap bit
4 Read/Write Reset switch enable (1 - auto reboot when dio_i[9] == 0)
3-2 Read/Write scratch reg
1 Read Only mode2 latched bootstrap bit
0 Read Only mode1 latched bootstrap bit

6.12 Watchdog

By default the watchdog is fed by ts7500ctl. This way if userspace, the kernel, or the FPGA communication has any issue the board will reboot. For many applications this may be enough, but 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:

Value Result
0 feed watchdog for another .338s
1 feed watchdog for another 2.706s
2 feed watchdog for another 10.824s
3 disable watchdog

Watchdog by default comes out of reset armed for .338 seconds. TS-BOOTROM firmware feeds for 10.824 and OS code has 10.824 seconds to take over. If you would like to run your own watchdog you will need to kill ts7500ctl when switching to your own application. You can feed the watchdog from your application by poking a register:

// Compile with gcc filename.c -o watchdog
#include <stdio.h>
#include <unistd.h>
#include "sbus.h"
 
int main(int argc, char **argv)
{
        // This is an example of feeding the watchdog for 10s
        for (;;) 
        {
                sbuslock();
                sbus_poke16(0x74, 2);
                sbusunlock();
                sleep(5); // Sleeping half of the 
                          // feeding time is usually a safe value
        }
 
        return 0;
}

6.13 CAN

The CAN controller on the TS-7558 is an optional core that emulates an SJA1000 CAN controller. Most applications will access this using CAN interface in tsctl.

Note: The CAN controller is not included in the default bitstream. For available bitstreams with CAN, see the #FPGA Bitstreams section.

The memory window to access the CAN controller is available at 0x18 over the SBUS.

Memory Window Register Map
Offset Bits Access Description
0x0 15:0 Read/Write Address
0x2 15:0 Read/Write 8-bit Data
0x4 15:0 Read/Write 16-bit Data
0x6 15:8 Write Only Address
7:0 Write Only Data

When the 8 or 16 bit data register is read or written, the address is automatically incremented by 1. In this way, contiguous reads/writes of address space is optimized. The 0x6 offset allows 8 bit address and data writes in a single register.

6.14 Random Number Generator

The FPGA has a random number generator. On startup, ts7500ctl is called with the --setrng option to seed Linux's random number generator from the hardware random number generator. Without a good source of entropy, Linux's random number generator will start up in a very predictable state which is undesirable for the security of many cryptography protocols.

6.15 External Reset

Driving the external reset pin (DIO 9) low will reset the CPU by default. You can disable this functionality by running:

ts7500ctl --resetswitchoff

6.16 Temperature Sensor

The TS-7558-BOX uses a temperature sensor that it communicates with over I2C. You can find a source code example here. Otherwise you can use 'ts7500ctl -T' to print the temperature.

7 External Interfaces

7.1 Terminal Blocks

The TS-7558 includes 4 removable terminal blocks:

TS-7558 removable connectors.png

These include all of the DIO, ADC, PWM, Counters, and quadrature.

TS-7558 Terminal Blocks.png
P1
Pin # Name Function
1 IN_P1 Digital Input 1 +
2 IN_N1 Digital Input 1 -
3 IN_P2 Digital Input 2 +
4 IN_N2 Digital Input 2 -
5 IN_P3 Digital Input 3 +
6 IN_N3 Digital Input 3 -
7 IN_P4 Digital Input 4 +
8 IN_N4 Digital Input 4 -
9 IN_P5 Digital Input 5 +
10 IN_N5 Digital Input 5 -
P3
Pin # Name Function
1 IN_P6 Digital Input 6 +
2 IN_N6 Digital Input 6 -
3 IN_P7 Digital Input 7 +
4 IN_N7 Digital Input 7 -
5 IN_P8 Digital Input 8 +
6 IN_N8 Digital Input 8 -
7 OUT_P1 Digital Output 1 +
8 OUT_N1 Digital Output 1 -
9 OUT_P2 Digital Output 2 +
10 OUT_N2 Digital Output 2 -
P2
Pin # Name Function
1 Power +
2 Power +
3 Power +
4 Power +
5 Power -
6 Power -
7 Power -
8 Power -
9 ADC_CH1 Analog to Digital Chan 1
10 GND
P4
Pin # Name Function
1 ADC_CH2 Analog to Digital Chan 2
2 GND
3 ADC_CH3 Analog to Digital Chan 3
4 GND
5 ADC_CH4 Analog to Digital Chan 4
6 GND
7 OUT_P3 Digital Output 3 +
8 OUT_N3 Digital Output 3 -
9 OUT_P4 Digital Output 4 +
10 OUT_N4 Digital Output 4 +

7.2 26 Pin Header

TS-7558-BOX also includes a .1" pin spacing external header for board to board interfacing.

Diagram

   ______________________________________ 
  | 2  4  6  8 10 12 14 16 18 20 22 24 26|
* | 1  3  5  7  9 11 13 15 17 19 21 23 25|
  \--------------------------------------/

Pinout

Pin # Name Function
1 JTAG_DOUT
2 JTAG_TMS 4.7k pull-up
3 GND Ground
4 JTAG_DIN 4.7k pull-up
5 MODE2 Latched boot up mode 2, 4.7k pull-up
6 JTAG_CLK 2.2k pull-up
7 CONSOLE_TXD Console TX, latched boot up mode 1, 4.7k pull-up
8 CONSOLE_RXD Console RX, 4.7k pull-up
9 SPI_MISO SPI master-in slave-out
10 3.3V 3.3V power
11 SPI_CS1 SPICS#1 output
12 SPI_MOSI SPI master-out slave-in
13 SDA I2C/DIO-driven by CPU, 2.2k pull-up
14 DIO_14 SPI clock output
15 SCL I2C/DIO-driven by CPU, 2.2k pull-up
16 WD_RESET Watchdog or system reset output
17 DIO_17 DIO,SPICS#0 output, weak FPGA pull-up
18 DIO_18 DIO,SPICS#2 output, weak FPGA pull-up
19 DIO_19 DIO, SPICS#3 output, weak FPGA pull-up, XUART#4 TX
20 DIO_20 DIO, weak FPGA pull-up, XUART#4 RX
21 DIO_21 DIO, weak FPGA pull-up, XUART#5 TX
22 DIO_22 DIO, weak FPGA pull-up, XUART#5 RX
23 DIO_23 DIO, weak FPGA pull-up, XUART#6 TX
24 DIO_24 DIO, weak FPGA pull-up, XUART#6 RX
25 DIO_25 DIO, weak FPGA pull-up, XUART#7 TX
26 VDC +5V

None of the DIO pins are 5V tolerant. They are 3.3V LVCMOS I/O buffers with approximately 12mA current drive capability. The XUARTs listed here are not included in the default FPGA bitstream. To use these ports you will have to rebuild the opencore excluding some other functionality to make room for all 8 XUARTs. The default bitstream only contains XUART0-2.

7.3 DB9 Port

DB9 Connector

Pinout

Pin # Name Function
1 RS485_0+ RS485 serial TX/RX + (XUART #2)
2 XUART#0_RX RS232 serial RXD for XUART #0
3 XUART#0_TX RS232 serial TXD for XUART #0
4 CAN_H CAN bus high
5 GND Ground
6 RS485_0- RS485 serial TX/RX - (XUART #2)
7 XUART#1_TX RS232 serial TXD for XUART #1
8 XUART#1_RX RS232 serial RXD for XUART #1
9 CAN_L CAN bus low

The CAN bus has optional termination resistor enabled by JP2 jumper. The termination resistor is 124 ohms across the CAN_H and CAN_L pins.

7.4 COM Ports

The XUART ports will be controlled with xuartctl. By default they will not have devices in /dev/.

Name Type Location
XUART0 RS232 pins 3 (TX) and 2 (RX) of the #DB9 Port.
XUART1 RS232 pins 7 (TX) and 8 (RX) of the #DB9 Port.
XUART2 RS485 pins 1 (TX/RX +) and 6 (TS/RX -) of the #DB9 Port.

8 Enclosures

The TS-7558-BOX is only compatible with the enclosure it ships with. This measures 5.01"x1.8"x7.5".

TS-7558 Enclosure

9 Errata

9.1 Cavium PHY Ethernet Link Loss

Synopsis Link drop with certain cable lengths/switches on 100Mb/s networks
Severity Normal
Class Kernel Bug
Affected All TS-75XX/TS-4500 Boards
Status Workarounds available

Description:

The Cavium STR8100 integrated PHY in some circumstances can drop connection to the network. You can see this in dmesg as:

 star_nic_shutdown: stoping patch check.

The issue appears to correspond to the length of cable used as well as the network device connected to the board.

Workaround:

You can force the cavium PHY to 10MB/s which drastically improves reliability, and in most cases eliminates the issue. This needs to be run each time the interface is brought back up. If link is lost you would need to reset the interface (ifconfig eth0 up && ifconfig eth0 down) and run the devmem command again.

# From the initrd:
devmem 0x70000004 32 0x43075
 
# From Debian
busybox devmem 0x70000004 32 0x43075

This will disable the link speed auto-negotiation and force the PHY to communicate at 10Mb/s.

9.2 Ethernet driver can cause kernel delays

Synopsis 160ms Delay with ETH0 Disconnected
Severity Minor
Class Kernel Bug
Affected All TS-75XX/TS-4500 Boards
Status Workarounds available

Description:

The Cavium STR8100 NIC driver was programmed with 160ms delays when Ethernet is physically disconnected (see function static void internal_phy_patch_check(int init) of .../drivers/net/str8100/star_nic.c). This causes delayed responses in real-time applications such as canctl. When Ethernet is physically connected, the issue is nonexistent.

Workaround:

TS-75XX/TS-4500 users wanting to utilize real-time responses without Ethernet plugged in will need to either:

1. Bring the eth0 interface down with the command:

ifconfig eth0 down

2. Recompile the kernel without the Ethernet driver from Cavium (.../drivers/net/str8100/star_nic.c)

10 Product Notes

10.1 FCC Advisory

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

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

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

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

10.2 Limited Warranty

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

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

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

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