TS-7553: Difference between revisions

From embeddedTS Manuals
Line 780: Line 780:
   return 0;
   return 0;
}
}
<
</source>


= Backup / Restore =
= Backup / Restore =

Revision as of 20:39, 27 July 2011

TS-7553
TS-7553.jpg
Released Mar. 2010
Documentation
Schematic
Mechanical Drawing
FTP Path

Overview

The TS-7553 was released Mar. 2010 and is a smaller form factor and cost reduced version of the TS-7552 without the extra USB ports and 8-28V switching power supply. It was designed to be mated with an inexpensive plastic enclosure and serve as a standalone general purpose embedded server.

Getting Started

Get a console

If you have a TS-9448, you can connect that to the 26 pin header and use the 10 pin header (labelled "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 onboard COM port using the standard 8n1, no flow control, 115200 baud rate.

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

Fastboot/initrd

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.

Boot Process

This board uses the TS-BOOTROM implemented in our FPGA. When the board is powered on the FPGA checks the state of the boot jumpers, and then begins execution in the MBR of that storage device. By default any boot device will have a kernel, and a ramdisk with busybox. On the SD card and XNAND there is a copy of Debian.

Boot Selection With TS-9448

Switch Pos. SDBOOT Jumper Boot Behavior
Down Off XNAND
None On Offboard SPI Flash
Up Off MicroSD
 Note: JP1 will cause the bootloader to only boot to SPI Flash

Boot Selection Without TS-9448

SDBOOT Jumper Boot Behavior
Off XNAND
On MicroSD

Operating System

Our boards boot a standard Debian installation which provides a large amount of software that you can install with relatively little effort. See the Debian page for more general information on installing/removing software, and further documentation.

For this series we provide Debian Etch and Debian Lenny. Further Debian releases have switched to EABI binaries (see EABI vs OABI), so we will not release Debian Squeeze or later for this board. The Cavium CNS2132 CPU supports the calls needed for EABI, but the Debian EABI binaries require thumb support which the Cavium does not support. If you require any specific software to be newer, you will have to manually build a later version.

We provide our distributions separate from the disk images. You can find them on this folder on the ftp. You will need a linux system to extract it:

# Replace the mmcblk0p4 device with the SD card
# on your workstation
mount /dev/mmcblk0p4 /mnt/sd/
cd /mnt/sd/
tar --numeric-owner -xvf /path/to/debian-lenny-arm-latest.tar.gz
cd ../
umount /mnt/sd/

You can download the Debian Etch and Debian Lenny minimal install for x86 from here and install it on a PC or virtual machine to become more familiar with a debian environment.

Note: As of March 27th 2012 Debian Lenny has moved to archive. To use apt-get your will need to edit /etc/apt/sources.list to contain only the line "deb http://archive.debian.org/debian lenny main".

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

Cross Compiling

If your sources are large enough that compiling on the board is too encumbering, we provide toolchains that you can use from another Linux or Cygwin environment.

For these board you will want to use this toolchain. Extract it to the root of your filesystem, and run that version of gcc to prepare the ARM binary.

To Compile:

[user@localhost]$ /usr/local/arm-oabi-toolchain/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-gcc hello.c -o hello
[user@localhost]$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), for GNU/Linux 2.6.26, not stripped

Transfer the file to the board (scp, nfs, smb, etc) and execute it:

ts7500:~# ./hello 
Hello world!

When compiling for c++, you must add in the compile option '-mhard-float'. This will make floating point operations throw an exception to the kernel which will properly handle the floating operations in a software FPU. Compiling without this option will result in a floating point error.

If you receive an error in a natively compiled application containing ILLEGAL INSTRUCTION, remove '-mcpu=arm9' if you have it and use '-mcpu=arm7'. Even though this is an ARM9 CPU, gcc will sometimes generate instructions that aren't covered by arm9 itself (like thumb instructions even when specifying -mno-thumb-interwork).

CPU Functionality

Any functionality here will have much more in depth technical documentation in the datasheet for the CPU. Unfortunately, we cannot redistribute this. You can go to www.cnusers.org and register to get a free copy of the datasheet.

USB

The Cavium supplies full USB 2.0 host support, as well as USB gadget support. You can find documentation on the kernel's USB gadget driver here.

Interfacing with a custom USB device is typically implemented using libusb which is documented here.

WIFI-N-USB

The WIFI-N-USB kernel module is included in the Debian modules.

WIFI-G-USB-2

Notice: The WIFI-G-USB-2 USB adapter both went end of life in June 2011 It has been replaced by the WIFI-N-USB adapter.

The WIFI-G-USB-2 kernel module is included in the Debian modules.

WIFI-G-USB

Notice: The WIFI-G-USB USB adapter both went end of life in June 2011 It has been replaced by the WIFI-N-USB adapter.

The WIFI-G-USB kernel module is included in the Debian modules.

FPGA Functionality

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

FPGA Top Level Decode:

Address Range Description
0x00-0x0f SD card core
0x10-0x1f Reserved
0x20-0x3b XUART core
0x3c-0x3f XUART memwindow
0x40-0x4f SPI interface (for NOR flash)
0x50-0x5f reserved
0x60-0x7f syscon (GPIO/LEDs/revision/etc...)

XUARTSs

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

XNAND

The XNAND access is implemented in userspace in conjunction with NBD (network block device). You may want to refer to the sdctl 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.

SD

Similar to the XNAND, the SD card access is implemented in userspace in conjunction with NBD (network block device). The sdctl page which will show more advanced usage and the linuxrc script will bring up the NBD devices 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 do not report size correctly.  If you are formatting a partition or using dd you will need to specify the size.

The SD card core is a black box serviced by the OS independent C API (sdcore2.c) for reading/writing SD cards. This source code is available, but not recommended for modification. Since this core instance not cannot use memory based register access, the generic peek/poke routines need to be overloaded with SBUS specific register access. This happens automatically in the sdctl utility.and sdctl.c source code from the TS FTP site ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7500-linux/sources/ may be consulted as the reference.

SPI Flash

The SPI flash is also implemented in userspace with NBD, however it is not mounted 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.

This core is for high speed SPI with auto-CS#. Starts at offset 0x40 on the TS-7500. LUN#0 goes to onboard SPI NOR flash chip (TS-7500 only) and LUN#1 goes to offboard SPI (TS-752 or TS-9448 flash chip).

SPI interface register map:

Address Range Access Description Notes
0x40 Read/Write LUN register
Bits Access Notes
15 Read Only SPI MISO state
14 Read/Write SPI CLK state
13-10 Read/Write speed (0- highest, 1- 1/2 speed, 2- 1/4, 3- 1/6, etc..)
9-8 Read/Write LUN (0-3 representing the 4 CS# signals)
7-0 N/A Reserved
0x42 Read Only Previous SPI read data from last write
0x44 N/A Reserved
0x46 N/A Reserved
0x48 Read/Write SPI read/write with CS# to stay asserted
0x4a Read Only SPI pipelined read with CS# to stay asserted
0x4c Read/Write SPI read/write with CS# to deassert post-op
0x4e N/A 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.

For the TS-75xx/TS-4500 where the base clock is 75Mhz, 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)

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.

IO Window Core

This core is a simple core to allow access to an up to 64Kbyte WISHBONE 8-bit address space via a 4 16-bit register window.

IO Window Core Register Map:

Address Range Access Description Notes
0x50 Read/Write IO window address reg
0x52 Read/Write 8-bit IO data reg with auto-increment
0x54 Read/Write 16-bit IO data reg with auto-increment
0x56 Write Only Combo IO address/data write reg
Bits Notes
15-8 address bits 7-0 of bus write
7-0 data bits of bus write cycle.

When the 8bit data reg is read or written, the address is automatically incremented by 1. In this way, contiguous reads/writes of address space is optimized. When the 16-bit data reg is read or written, 2 read or write 8-bit bus cycles are performed and the address is incremented by 2. The Combo IO address/data register is only meaningful write-only. It encodes the 8 LSBs of the address as the 8 MSBs of the written data word.

IO window address map:

Address Range Description
0x0-0xff optional SJA1000C compatible CAN controller
0x100-0xffff Reserved

Syscon Core

Address Range Access Description Notes
0x60 Read Only Model ID reg Returns model (0x7500, 0x7553, etc)
0x62 Read/Write submodel, fpga revision, RTC and LED control
Bits Access Notes
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 - 0x0 on production board
3-0 Read Only FPGA revision
0x64 Read Only 16-bits of random data changed every 1 second.
0x66 Read Write DIO and tagmem control
Bits Access Notes
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 Read Only DIO input for pins 36(MSB)-21(LSB)
0x6a Read Only DIO output for pins 36(MSB)-21(LSB)
0x6c Read/Write DIO direction for pins 36(MSB)-21(LSB) (1 - output)
0x6e Read/Write DIO input for pins 20(MSB)-5(LSB)
0x70 Read/Write DIO output for pins 20(MSB)-5(LSB)
0x72 Read/Write DIO direction for pins 20(MSB)-5(LSB) (1 - output)
0x74 Write Only Watchdog feed register
Value Notes
0x0 feed watchdog for another .338s
0x1 feed watchdog for another 2.706s
0x2 feed watchdog for another 10.824s
0x3 disable watchdog
0x76 Read/Write SPI PLL phase, latched mode bits, scratch reg
Bits Access Notes
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

Watchdog

The watchdog is also manipulated via the ts7500ctl utility. The default INITRD linuxrc autofeeds the watchdog by daemonizing and feeding it in the background via userspace. It can be armed in 3 modes (0 - .4s, 1- 2.7s, 2 - 10.8s). It can be either auto-fed from a background process that continually feeds the watchdog while running (--autofeed option), or via a /dev/watchdog UNIX named pipe which receives single ASCII characters which are written to feed it from another application: '0' - feed for another .4s, '1' - feed for another 2.7s, '2' - feed for another 10.8s, or '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.

You can feed the watchdog from your application by poking a register:

#include <stdio.h>
#include <unistd.h>
#include "sbus.h"

int main(int argc, char **argv)
{
        // This is an example of the 10s watchdog
        for (;;) 
        {
                sbuslock();
                sbus_poke16(0x74, 2);
                sbusunlock();
                sleep(5);
        }

        return 0;
}

DIO

For interacting with the DIO we have developed dioctl. This allows a simple and standard way to control DIO throughout multiple series of our boards. See the dioctl page for more information.

While dioctl will provide the simplest interface, it is not necessarily the fastest method. This example accesses the the FPGA DIO directly.

#include "sbus.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define DIO_Z 2

/*******************************************************************************
* setdiopin: accepts a DIO register and value to place in that DIO pin.
*   Values can be 0 (low), 1 (high), or 2 (z - high impedance).
*******************************************************************************/
void setdiopin(int pin, int val)
{
   int pinOffSet;
   int dirPinOffSet; // For Register 0x66 only
   int outPinOffSet; // For Register 0x66 only

   // First, check for the high impedance case
   if (val == 2)
   {
      if (pin <= 40 && pin >= 37)
      {
         dirPinOffSet = pin - 33;
         sbus_poke16(0x66, sbus_peek16(0x66) & ~(1 << dirPinOffSet));
      }
      else if (pin <= 36 && pin >= 21)
      {
         pinOffSet = pin - 21;
         sbus_poke16(0x6c, sbus_peek16(0x6c) & ~(1 << pinOffSet));
      }
      else if (pin <= 20 && pin >= 5)
      {
         pinOffSet = pin - 5;
         sbus_poke16(0x72, sbus_peek16(0x72) & ~(1 << pinOffSet));
      }
   }

   /******************************************************************* 
   *0x66: DIO and tagmem control (RW)
   *  bit 15-12: DIO input for pins 40(MSB)-37(LSB) (RO)
   *  bit 11-8: DIO output for pins 40(MSB)-37(LSB) (RW)
   *  bit 7-4: DIO direction for pins 40(MSB)-37(LSB) (1 - output) (RW)
   ********************************************************************/
   else if (pin <= 40 && pin >= 37)
   {
      dirPinOffSet = pin - 33; // -37 + 4 = Direction; -37 + 8 = Output
      outPinOffSet = pin - 29;

      // set bit [pinOffset] to [val] of register [0x66] 
      if(val)
         sbus_poke16(0x66, (sbus_peek16(0x66) | (1 << outPinOffSet)));
      else
         sbus_poke16(0x66, (sbus_peek16(0x66) & ~(1 << outPinOffSet)));

      // Make the specified pin into an output in direction bits
      sbus_poke16(0x66, sbus_peek16(0x66) | (1 << dirPinOffSet)); ///

   }

   /********************************************************************* 
   *0x68: DIO input for pins 36(MSB)-21(LSB) (RO)    
   *0x6a: DIO output for pins 36(MSB)-21(LSB) (RW)
   *0x6c: DIO direction for pins 36(MSB)-21(LSB) (1 - output) (RW)
   *********************************************************************/
   else if (pin <= 36 && pin >= 21)
   {
      pinOffSet = pin - 21;

      // set bit [pinOffset] to [val] of register [0x6a] 
      if(val)
         sbus_poke16(0x6a, (sbus_peek16(0x6a) | (1 << pinOffSet)));
      else
         sbus_poke16(0x6a, (sbus_peek16(0x6a) & ~(1 << pinOffSet)));

      // Make the specified pin into an output in direction register
      sbus_poke16(0x6c, sbus_peek16(0x6c) | (1 << pinOffSet)); ///
   }

   /********************************************************************* 
   *0x6e: DIO input for pins 20(MSB)-5(LSB) (RO)    
   *0x70: DIO output for pins 20(MSB)-5(LSB) (RW)
   *0x72: DIO direction for pins 20(MSB)-5(LSB) (1 - output) (RW)
   *********************************************************************/
   else if (pin <= 20 && pin >= 5)
   {
      pinOffSet = pin - 5;

      if(val)
         sbus_poke16(0x70, (sbus_peek16(0x70) | (1 << pinOffSet)));
      else
         sbus_poke16(0x70, (sbus_peek16(0x70) & ~(1 << pinOffSet)));

      // Make the specified pin into an output in direction register
      sbus_poke16(0x72, sbus_peek16(0x72) | (1 << pinOffSet));
   }

}


/*******************************************************************************
* getdiopin: accepts a DIO pin number and returns its value.  
*******************************************************************************/
int getdiopin(int pin)
{
   int pinOffSet;
   int pinValue = 99999;

   /******************************************************************* 
   *0x66: DIO and tagmem control (RW)
   *  bit 15-12: DIO input for pins 40(MSB)-37(LSB) (RO)
   *  bit 11-8: DIO output for pins 40(MSB)-37(LSB) (RW)
   *  bit 7-4: DIO direction for pins 40(MSB)-37(LSB) (1 - output) (RW)
   ********************************************************************/
   if (pin <= 40 && pin >= 37)
   {
      pinOffSet = pin - 25; // -37 to get to 0, + 10 to correct offset

      // Obtain the specific pin value (1 or 0)
      pinValue = (sbus_peek16(0x66) >> pinOffSet) & 0x0001;
   }

   /*********************************************************************   
   *0x68: DIO input for pins 36(MSB)-21(LSB) (RO)  
   *0x6a: DIO output for pins 36(MSB)-21(LSB) (RW)
   *0x6c: DIO direction for pins 36(MSB)-21(LSB) (1 - output) (RW)
   *********************************************************************/
   else if (pin <= 36 && pin >= 21)
   {
      pinOffSet = pin - 21; // Easier to understand when LSB = 0 and MSB = 15

      // Obtain the specific pin value (1 or 0)
      pinValue = (sbus_peek16(0x68) >> pinOffSet) & 0x0001;
   }

   /*********************************************************************   
   *0x6e: DIO input for pins 20(MSB)-5(LSB) (RO)  
   *0x70: DIO output for pins 20(MSB)-5(LSB) (RW)
   *0x72: DIO direction for pins 20(MSB)-5(LSB) (1 - output) (RW)
   *********************************************************************/
   else if (pin <= 20 && pin >= 5)
   {
      pinOffSet = pin - 5;  // Easier to understand when LSB = 0 and MSB = 15

      // Obtain the specific pin value (1 or 0)
      pinValue = (sbus_peek16(0x6e) >> pinOffSet) & 0x0001;
   }
   return pinValue;
}



/*******************************************************************************
* Main: accept input from the command line and act accordingly.
*******************************************************************************/
int main(int argc, char **argv)
{
   int pin;
   int val;
   int returnedValue;
         
   // Check for invalid command line arguments
   if ((argc > 4) | (argc < 3))
   {
       printf("Usage: %s <get|set> <pin#> <set_value (0|1|2)>\n", argv[0]);
       return 1;
   }
   
   // We only want to get val if there are more than 3 command line arguments
   if (argc == 3)
      pin = strtoul(argv[2], NULL, 0);
   else
   {
      pin = strtoul(argv[2], NULL, 0);
      val = strtoul(argv[3], NULL, 0);
   }
   
   // If anything other than pins 5 through 40, fail program
   assert(pin <= 40 && pin >= 5);

   // Parse through the command line arguments, check for valid inputs, and exec
   if (!(strcmp(argv[1], "get")) && (argc == 3))
   {
      sbuslock();
      returnedValue = getdiopin(pin);
      sbusunlock();
      
      printf("pin#%d = %d \n", pin, returnedValue);
   }
   else if(!(strcmp(argv[1], "set")) && (argc == 4) && (val <= 2))
   {
      sbuslock();
      setdiopin(pin, val);
      sbusunlock();
      
      printf("pin#%d set to %d\n", pin, val);
   }   
   else
   {
      printf("Usage: %s <get|set> <pin#> <set_value (0|1|2)>\n", argv[0]);
      return 1;
   }
   return 0;
}

Backup / Restore

MicroSD Card

These instructions for rewriting the SD card must be done either on the arm system, or on a linux workstation. We do not support any method using Windows to rewrite the cards, but many virtual machines offer USB redirection which will also work with the USB card reader supplied in the development kit. The methods using dd and sdctl to rewrite the SD card will completely erase everything on the card and set up our MBR, kernel, intird, and Debian filesystem. No prior formatting to the card is needed.

After plugging in the USB adapter to your PC you will need to determine the block 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.

You can find the latest SD card image here. Make sure you decompress the image first before writing. For example to decompress on most Linux workstations you can run:

bzip2 -d dblstorimg-4gbsd-latest.dd.bz2

To update to our latest image from your workstation:

dd if=/path/to/dblstorimg-4gbsd-latest.dd of=/dev/mmcblk0 bs=32k && sync && sync

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

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

If there is no /mnt/root/ directory then the system is still booted to Debian and you should not proceed with the backup/restore sections. The image that is written or read back will be corrupt.

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 create the image first connect a USB drive and then power the device on. Boot to the busybox environment and not the full Debian. The USB drive should be formatted with ext2/3 or fat32.

killall nandctl
mkdir /mnt/usb
mount /dev/sda1 /mnt/usb
nandctl -XR 2048 -z 131072 > /mnt/usb/backup.dd
umount /mnt/usb
sync

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 image first connect a USB drive with the image and then power the device on. Boot to the busybox environment and not the full Debian. The USB drive should be formatted with ext2/3 or fat32.

killall nandctl
mkdir /mnt/usb
mount /dev/sda1 /mnt/usb
nandctl -XW 2048 -z 131072 -i /mnt/usb/backup-image.dd
umount /mnt/usb
sync

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 -

Offboard SPI Flash (TS-9448)

This needs to be done directly on the SBC. You can find the latest SPI image here. Make sure you decompress the image first before writing.

Backup

Entire SPI flash

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

Kernel

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

Initrd

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

Restore

Entire SPI flash

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

Kernel

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

Initrd

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

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

Kernel Overview

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 2.6.24 as the supported kernel.

We also have 2.6.36, though USB device does not work (host does). This is provided as is.

Connectors

26 Pin Header

TS-7553 also includes a .1" pin spacing external header for board to board interfacing. The external interfaces uses a total of 26 pins.

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 DIO_26 DIO, weak FPGA pull-up, XUART#7; RX +5V
Note: As of Rev.A1 of TS-7553, Pin 26 (DIO_26) will permanently 
be +5V instead of "DIO, weak FPGA pull-up".

None of the DIO pins are 5V tolerant. They are 3.3V LVCMOS I/O buffers with approximately 12mA current drive capability.

DB9 Port

Diagram

 =============  
 \\1 2 3 4 5// 
  \\6 7 8 9//  
   =========    

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 (or second RS485 port +)
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 (or second RS485 port -)

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.

XBEE Connector

The dual in-line 10-pin headers are spaced for an XBee or XBee-PRO module. There is an XUART connected to this port as well as DIO pins. The XBee module can be communicated with through the provided UART and DIO pins. To bring up the XBee port, you must use xuartctl.

xuartctl --server --port 3 --speed 9600

See the XBee page for more information on programming details.

Diagram

----		----
| 1|		|20|
| 2|		|19|
| 3|		|18|
| 4|		|17|
| 5|		|16|
| 6|		|15|
| 7|		|14|
| 8|		|13|
| 9|		|12|
|10|		|11|
----		----

Pinout

Pin # Name Function
1 VCC 3.3V
2 DOUT XUART#3 RX
3 DIN XUART#3 TX
4 NC
5 RESET# CPU_RESET# line, pull low to reset TS-7553
6 NC
7 NC
8 NC
9 DTR# Connected to DIO_25
10 GND
11 DIO4 Connected to DIO_21
12 CTS XUART#3 CTS pin, use mode=hwcts in xuartctl to enable this
13 NC
14 NC
15 DIO5 Connected to DIO_22
16 RTS#/DIO6 Connected to DIO_26
17 DIO3 Connected to DIO_20
18 DIO2 Connected to DIO_19
19 DIO1 Connected to DIO_18
20 DIO0 Connected to DIO_17

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.
XUART3 RS232 pins 3 (TX) and 2 (RX) of the #XBEE Connector.
XUART4 TTL pin 20 (RX) and 19 (TX) on the #26 Pin Header
XUART5 TTL pin 22 (RX) and 21 (TX) on the #26 Pin Header
XUART6 TTL pin 24 (RX) and 23 (TX) on the #26 Pin Header

Enclosures

The TS-7553 supports the TS-ENC820.

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.

FPGA FAQ

Should I implement x in the FPGA or Linux?

The FPGA will allow you to do certain things very quickly with no overhead of the linux system. Debugging options are extremely limited. For ease of development, only implement functionality in the FPGA if you have to.

Can I implement more than 8 XUARTS?

The XUART core only supports 8. However if you have requirements that demand more there are other options for implementing more, but depend very much on your requirements. Please contact us for more information.

I made a change in X, and now Y is behaving strangely?

Make sure you check to make sure you meet timing restraints. When they are not met then any or all of the cores may not behave as expected.

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.