TS-7500
Product Page | |
Product Images | |
Specifications | |
Documentation | |
---|---|
Schematic | |
Mechanical Drawing | |
FTP Path | |
Processor | |
Cavium CNS2312 250MHz Arm®v4T ARM922 (Arm9™-compatible) | |
CPU Datasheet |
Overview
The TS-7500 was released Jul. 2009 is a small embedded board with a CNS2132 250Mhz ARM9 CPU, Lattice XP2 5k FPGA, 64MB DDR SDRAM, and 4MByte SPI NOR flash chip.
Getting Started
A Linux workstation is recommended and assumed for development using this documentation. For users in Windows or OSX, we recommend virtualizing Linux. Most of our platforms run Debian, which is recommended for ease of use if there is no personal distribution preference.
Virtualization
Suggested Linux Distributions
Development using a Windows or OSX system may be possible but is not supported. Development will include accessing drives formatted for Linux and often Linux-based tools.
Development Kit and Accessories
The KIT-7500 includes the items that are necessary for development with the TS-7500.
The other options include:
Item | Description |
---|---|
The CN-PC104-40PIN-F is the mating connector for the 44 pin male header on the SBC. The 4 omitted pins are the JTAG pins which are only used for factory programming. The pins on this header are a very common 0.100" pitch. | |
The WIFI-N-USB is an ASUS 802.11N adapter. See the WIFI-N-USB page for more details. | |
The TS-ENC750 provides both the TS-752 and a metal enclosure. | |
The TS-ENC750-DIN is the TS-ENC750 with a DIN rail mount. | |
The TS-752 demonstrates the flexibility of a Technologic Systems SoM by connecting FPGA driven IO pins to relays, buffered digital inputs, buffered digital outputs, and RS-485 drivers. It also provides an RS-232 driver for the serial console. A TS-ENC750 with a TS-7500 or TS-7550 can provide a complete solution for many embedded applications. |
Get a Console
With the development kit you should have the TS-752 which brings out the debug console ttyS0 from the ARM processor as RS232. Custom baseboards should emulate the TS-752 for bringing out console. See the schematics available on the TS-752 page. The console from the UART will use 115200 baud, 8n1 (8 data bits 1 stop bit), and no flow control.
Console from Linux
There are many serial terminal applications for Linux, three common used applications are picocom
, screen
, and minicom
. These examples demonstrate all three applications and assume that the serial device is "/dev/ttyUSB0" which is common for USB adapters. Be sure to replace the serial device string with that of the device on your workstation.
picocom
is a very small and simple client.
sudo picocom -b 115200 /dev/ttyUSB0
screen
is a terminal multiplexer which happens to have serial support.
sudo screen /dev/ttyUSB0 115200
Or a very commonly used client is minicom
which is quite powerful but requires some setup:
sudo minicom -s
- Navigate to 'serial port setup'
- Type "a" and change location of serial device to "/dev/ttyUSB0" then hit "enter"
- If needed, modify the settings to match this and hit "esc" when done:
E - Bps/Par/Bits : 115200 8N1 F - Hardware Flow Control : No G - Software Flow Control : No
- Navigate to 'Save setup as dfl', hit "enter", and then "esc"
Console from Windows
Putty is a small simple client available for download here. Open up Device Manager to determine your console port. See the putty configuration image for more details.
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-7500 has 2 ways that it can be powered. The TS-7500 has a 5V line on the #44 Pin Header which can be used to supply power. The TS-752 baseboard can power the 5V rail through the terminal blocks with the PS-5VDC-REG-8PG. The second option is to use the USB Device port which can provide 500mA at 5V.
WARNING: | Do not use multiple power connections simultaneously or you may damage the board. |
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 power is first applied to the unit, the logic values on the MODE1 and MODE2 pins are latched. These signals decide if you boot from the MicroSD, on-board flash, or off-board 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 SD, USB drive, or an NFS root regardless of your initially booted media. Most common cases will boot from only one media.
If you are using the TS-752 the MODE1 and MODE2 pins are controlled by JP1 and JP2. Connecting the jumper will pull these to 0. The MODE1 and MODE2 signals both have 4.7k pull-ups. For a logic 0 on a custom baseboard these should be pulled to ground with a 680ohm resistor.
Booot Device | MODE1 | MODE2 |
---|---|---|
Onboard Flash | 1 | 1 |
SD Card | 0 | 1 |
Offboard Flash | 1 | 0 |
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. On newer units, "Offboard SPI" and "Onboard SPI" flashes may show "unknown" for the type. This is purely cosmetic and is no cause for concern. The SPI flash can be queried with the 'spiflashctl' tool which will return a proper manufacturer and device ID. |
This is a busybox shell which presents you with a very minimalistic system. While this has access to many Debian applications, it is important to note that this is not Debian. This environment will allow very fast boot times closer to 2-4 seconds, while Debian takes closer to 30-45 seconds but provides an init system and a more standard environment. As described in the previous section, the kernel and initrd are copied into RAM so any changes to this filesystem are temporary. You can commit changes using the "save" command.
For most development you will want to boot to the Debian filesystem which can be reached by typing "exit" through the serial console, or by relinking the linuxrc script to make the board automatically boot to Debian:
rm linuxrc; ln -s /linuxrc-sdroot /linuxrc; save
The linuxrc-sdroot script will actually mount and boot to the Debian filesystem on the SD or XNAND depending which device you used to boot. You can boot to a different Debian partition by using one of the other linuxrc scripts:
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 media the SBC was booted from. |
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. |
Once you have booted to Debian you can force the boot process to stop in the fastboot shell/initd on next bootup with:
touch /fastboot
The small default initrd is only 2Mbyte but there is space for approximately 800 Kbyte of additional user applications. This constraint is important if you are running your application without Debian, but only from the initrd. If you have the Debian partition available you can access that partition under /mnt/root/ to run your application.
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()
To use these functions you must source the subr file:
. /ts7500.subr
## or from Debian
# . /initrd/ts7500.subr
tshelp
Debian 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.
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.
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.
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.
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.
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.
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.
MicroSD Card
Click to download the latest 2GB SD card image. |
Once downloaded you can decompress the image using bzip2:
bzip2 -d 2gbsd-noeclipse-latest.dd.bz2
The resulting file will be "2gbsd-noeclipse-latest.dd".
For imaging the SD card we recommend using a Linux or similar operating system that allows you to access a block device using dd. We do not support rewriting the SD card from Windows.
If you are reprogramming the SD card from your workstation you will also need to determine the SD card device. Once you have connected the SD card to your workstation you can usually find the correct block device in the output of "dmesg". For example:
[ 309.498834] sd 8:0:0:0: [sdb] 3862528 512-byte logical blocks: (1.97 GB/1.84 GiB) [ 309.519814] sd 8:0:0:0: [sdb] Write Protect is off [ 309.519818] sd 8:0:0:0: [sdb] Mode Sense: 03 00 00 00 [ 309.519819] sd 8:0:0:0: [sdb] Assuming drive cache: write through [ 309.536025] sd 8:0:0:0: [sdb] Assuming drive cache: write through [ 309.536029] sdb: sdb1 sdb2 sdb3 [ 309.559672] sd 8:0:0:0: [sdb] Assuming drive cache: write through [ 309.559676] sd 8:0:0:0: [sdb] Attached SCSI removable disk
On this system my SD card block device is /dev/sdb, but your system will likely be different. The block devices are allocated in order by the letter so the next USB drive connected would be /dev/sdc. 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.
WARNING: | Many distributions will name your hard drive something like /dev/sda or /dev/hda which will have the same naming scheme as an SD card or a USB drive. Make sure you are aware which device is which before writing the disk. Technologic Systems is not responsible for any data lost/destroyed because of improper command execution. |
WARNING: | If you are working with the SD card from your workstation, keep in mind that most Linux distributions will mount the partitions that they can as soon as the drive is inserted. This is desirable if you want to open the filesystem, but for dealing directly with the block device for performing backups or restoring an image this is dangerous to your data. |
To verify if your workstation has mounted the block device on insertion:
cat /proc/mounts
# look for your SD card block device to see if this is already mounted.
If the block device did automatically mount, you will need to refer to your distribution's documentation for disabling automounting. For example, this is Ubuntu's documentation on disabling automounting. If you are not using a graphical Linux system this should not be a concern, but make sure no filesystems are mounted read only or read write while writing or reading an image.
For backing up or restoring any images from the board you will need to make sure you do not have any partitions mounted. On the default configuration you can write an image from the initrd after unmounting /mnt/root:
umount /mnt/root/
Restore from Workstation
To write the latest image or restore to stock you would use the dd command. This will perform a byte for byte copy from our image. This contains the MBR boot code with the partition tables, the kernel, initrd, and Debian filesystem. No other formatting or partitioning is needed.
Write an image to the entire SD card:
dd if=/path/to/backup.dd of=/dev/mmcblk0 bs=4M conv=fsync
If you want to write a new kernel, but not an entire image you can rewrite the second partition:
dd if=/path/to/zImage bs=4M of=/dev/mmcblk0p2 conv=fsync
Backup from Workstation
To backup an entire SD card image:
dd if=/dev/mmcblk0 of=/path/to/backup.dd bs=4M
This will create a dd file the size of the card.
Note: | A MicroSD card from one manufacturer will likely not be the exact same size as another manufacturer's MicroSD card of the same size. Our partition layouts by default leave the last 10% of the images unallocated to account for the size difference of various manufacturers MicroSD cards. As long as you use our partition layout you should not need to be concerned with this, but if you create your own layout we strongly recommend leaving 10% of the disk unallocated. |
Once you have the disk image you will want to trim this to the last partition so the image doesn't contain the free space at the end of the disk. To get the last sector you would use fdisk:
fdisk -ucl /dev/sdb Disk /dev/sdb: 1977 MB, 1977614336 bytes 61 heads, 62 sectors/track, 1021 cylinders, total 3862528 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Device Boot Start End Blocks Id System /dev/sdb1 512 8703 4096 83 Linux /dev/sdb2 8704 15871 3584 da Non-FS data /dev/sdb3 16896 20991 2048 da Non-FS data /dev/sdb4 25088 3170815 1572864 83 Linux
On this SD card the end of the partition is 3170815 sectors. As the sectors each contain 512B the image is 1623457280 bytes. You can use the truncate command to correct the image size:
# This is an example - check your image with fdisk
truncate backup.dd --size=1623457280
Keep in mind these numbers are an example and are not necessarily representative of your image.
If you would like to backup just the Kernel partition, you would grab partition 2.
dd if=/dev/mmcblk0p2 of=/path/to/zImage bs=32k
Restore From the SBC
To write the latest image or restore to stock you would use the dd command. This will perform a byte for byte copy from our image. This contains the MBR boot code with the partition tables, the kernel, initrd, and Debian filesystem. No other formatting or partitioning is needed.
Write an image to the entire SD card:
dd if=/path/to/image-latest.dd of=/dev/nbd9 conv=fsync
Kernel
dd if=/mnt/root/zImage of=/dev/nbd7 conv=fsync
Backup From the SBC
To backup an entire SD card image:
# Determine the block size
eval $(sdctl)
dd if=/dev/nbd5 of=/path/to/backup.dd bs=512 count=$cardsize_sectors conv=sync && sync
This will create an image file the size of the card.
Note: | A MicroSD card from one manufacturer will likely not be the exact same size as another manufacturer's MicroSD card of the same size. Our partition layouts by default leave the last 10% of the images unallocated to account for the size difference of various manufacturers MicroSD cards. As long as you use our partition layout you should not need to be concerned with this, but if you create your own layout we strongly recommend leaving 10% of the disk unallocated. |
Once you have the disk image you will want to trim this to the last partition so the image doesn't contain the free space at the end of the disk. To get the last sector you would use fdisk:
fdisk -ucl /dev/sdb Disk /dev/sdb: 1977 MB, 1977614336 bytes 61 heads, 62 sectors/track, 1021 cylinders, total 3862528 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Device Boot Start End Blocks Id System /dev/sdb1 512 8703 4096 83 Linux /dev/sdb2 8704 15871 3584 da Non-FS data /dev/sdb3 16896 20991 2048 da Non-FS data /dev/sdb4 25088 3170815 1572864 83 Linux
On this SD card the end of the partition is 3170815 sectors. As the sectors each contain 512B the image is 1623457280 bytes. You can use the truncate command to correct the image size:
# This is an example - check your image with fdisk
# truncate is a Debian command and will not be available from busybox
truncate backup.dd --size=1623457280
Keep in mind these numbers are an example and are not necessarily representative of your image.
If you would like to backup just the kernel partition, you would grab partition 2.
dd if=/dev/mmcblk0p2 of=/path/to/zImage bs=32k
SPI Flash
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
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
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.
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. |
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.embeddedTS.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.embeddedTS.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.
Features
CPU
This board features a CNS2132 250MHz ARM9 processor. For more details see the CPU Datasheet.
FPGA
This board features a Lattice LFXP2 FPGA. The CPU connects to the FPGA using SPI, and since access to SPI is not atomic we have implemented the SBUS as a safe way for multiple processes to access FPGA registers.
FPGA Bitstreams
The FPGA has the capability to be reloaded on startup and reprogram itself with different configurations. The default bitstream is hardcoded into the FPGA, but the soft reloaded bitstreams can be placed in /ts7500_bitstream.vme.gz on the initrd root to make the board load the bitstream on startup. You can also load the bitstream manually using ts7500ctl:
ts7500ctl --loadfpga bitstream.vme
# or
ts7500ctl --loadfpga bitstream.vme.gz
A list of our pre-built bitstreams can be found on our FTP site
If we do not have a configuration you need, you can build a new bitstream, or contact us for our engineering services.
Bitstream | Revision | SD controller | SPI | XNAND | CAN | XUARTs |
---|---|---|---|---|---|---|
Default | 5 | On | On | On | Off | 0-7 |
The released FPGA has undergone minor bug fixes throughout the product liftime.
Revision | Changes |
---|---|
0 | Initial Release |
1 | Added 5-bit PLL phase shift register for SPI to increase temperature margin. |
2 | * Improved GPIO performance by putting the syscon block on its own clock domain synchronous to the SPI clock.
|
3 | Corrected XUART0 RX line |
4 | * Added improved SPI controller and extra CS2# and CS3#
* Optional CAN controller added * Fixed IRQ output |
5 | * Updated SPI controller with extra slower speeds (1.2Mhz) and CS# bit in control reg.
* USB Device fixes |
6 | CAN Fixes |
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.
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.
XUARTs
The XUART controller is a core we have included in the FPGA, as well as a userspace application called xuartctl for accessing these UARTs. Rather than using a kernel driver with the standard serial interface, we have implemented the XUARTs with features to simplify application development. The XUARTs allow you to easily use arbitrary baud rates, nonstandard modes such as DMX or 9n1, and they allow a very low latency operation. The XUART layer also uses the very low overhead TCP layer which allows you to transport serial over the network without writing any code.
The simplest example to get started is to define the port with:
xuartctl --server --port=1 --speed=115200
This will return "ttyname=/dev/pts/0", or a higher pts number. You can use this /dev/pts/# device to access the UART, but note that the pts device number can change based on other ssh, telnet or other processes. See this section for a sample script to setup the XUARTs with a predictable device name.
For more information and detailed usage, see the xuartctl page.
The XUARTs like many other standard UARTs poll the RX buffers by default. The XUARTs have large RX FIFOs so polling at 100hz is the best choice for many applications. At the expense of more CPU time you can use an IRQ to achieve a much lower latency. This board uses IRQ 29 for the XUART IRQ. You can edit the linuxrc script and change the xuartctl server to start with:
xuartctl --irq=29 --server
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. |
COM Ports
The XUART ports will be controlled with xuartctl. By default they will not have devices in /dev/.
Name | Type | Location |
---|---|---|
ttyS0 (console) | TTL | pins 7 (TX) and 8 (RX) of the #44 Pin Header. |
XUART0 | TTL | pins 5 (TX) and 6 (RX) of the #44 Pin Header. |
XUART1 | TTL | pins 19 (TX), 20 (RX), and 27 (TXEN) of the #44 Pin Header. |
XUART2 | TTL | pins 21 (TX), 22 (RX), and 28 (TXEN) of the #44 Pin Header. |
XUART3 | TTL | pins 23 (TX) and 24 (RX) of the #44 Pin Header. |
XUART4 | TTL | pins 25 (TX) and 26 (RX) of the #44 Pin Header. |
XUART5 | TTL | pins 31 (TX), 32 (RX), and 29 (TXEN) of the #44 Pin Header. |
XUART6 | TTL | pins 34 (TX), 33 (RX), and 30 (TXEN) of the #44 Pin Header. |
XUART7 | TTL | pins 36 (TX) and 35 (RX) of the #44 Pin Header. |
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. |
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.
CAN
Note: | The default TS-7500 bitstream does not include CAN. See the #FPGA Bitstreams section for more information on bitstreams including CAN. |
The FPGA contains a SJA1000C compatible CAN controller that can be accessed using canctl which provides a CAN network service. Any application on the network can make use of this service to send or receive CAN packets using the API defined by canctl. Thus, it is possible to develop code written in other languages (java, python, etc.) and/or to run this code under other operating systems.
The canctl server is started by running:
Note: | Due to a bug in some releases, daqctl will grab the IRQ before canctl. If CAN is unable to take the IRQ you can stop the daqctl process to reclaim it:
killall daqctl
canctl --server
|
The easiest interface to CAN is calling "canctl" through the command line:
canctl --port=127.0.0.1 --txdat=01:02:03:04:05:06
# canctl --help Technologic Systems CAN controller manipulation. -a | --address=ADR CAN register address -b | --baud=BAUD CAN baud rate (7500 to 1000000) -R | --peek8r CAN register read -W | --poke8w=VAL CAN register write -i | --txid=ID CAN TX packet ID -T | --txrtr TX RTR packet -d | --txdat=DAT TX packet with data DAT -s | --server==<port> Daemonize and run as server -D | --dump Receive and print all CAN packets -0 | --btr0=BTR0 SJA1000 BTR0 bus timing reg val -1 | --btr1=BTR1 SJA1000 BTR1 bus timing reg val -t | --txtest Send TX test pattern -r | --rxtest Do RX test -p | --port=<host><:port> Talk to canctl server -S | --std Send standard frame (not extended) -v | --recover Automatically recover from bus-off
The canctl application implements network CAN functionality using the can_rx_remote() and can_tx_remote() functions. These functions which read and write one fixed-size packet of struct canmsg to a TCP socket descriptor. Writing your own canctl client in the language of your choice is as simple as doing the same thing. The format of the each CAN packet sent or received via the network interface is described below. The terms "Rx" and "Tx" are relative to the client, so "Rx" would describe packets read from CAN over the network and "Tx" would describe packets written to CAN over the network.
UINT32 flags: bit 7 - set on Tx if packet is a control packet control packets are intercepted by the canctl server to allow control functionality. bit 6 - set if message originates locally (unused) bit 5 - set if CAN message has extended ID bit 4 - set if remote transmission request (RTR) bit 3 - set on Rx if CAN error warning condition occurred bit 2 - set on Rx if CAN bus had a data overrun bit 1 - set on Rx if CAN bus went error passive bit 0 - set on Rx if a CAN bus error occurred Error conditions are reported for informational purposes. The server normally handles these errors and recovers from them. control information present (reserved for future use) message originates from this node (unused) UINT32 CAN id UINT32 timestamp_seconds UINT32 timestamp_microseconds UINT32 bytes of CAN data which are valid if bit 7 of flags is set, this byte is instead interpreted as a command number: 0 = set acceptance filter if the acceptance filter has been set, then only CAN packets which pass the filter will be received. to pass the filter, all bits in the acceptance filter which are to be checked (specified by a 1 in the corresponding bit of the mask) are compared (filter id compared to corresponding bit in received id). only if all bits to be checked do match will the packet be received. UINT8[8] CAN data if bit 7 of flags is set, this byte is instead interpreted as follows: cmd 0: UINT32 acceptance filter id UINT32 acceptance filter mask
UINT32 values are sent in little-endian format.
So for example, to send a standard CAN packet of length 6 with contents 01:02:03:04:05:06 and CAN id 55 it would be necessary to open a TCP connection to port 7552 on the device with the canctl server running, and the write the following packet to the socket:
00 00 00 00 55 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 01 02 03 04 05 06 00 00
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 |
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;
}
DIO
This board brings out only FPGA DIO. Since the FPGA is connected to the processor using SPI which is not atomic, we have created the SBUS which allows safe access from multiple processes. The SBUS mechanism of locking as well as it being a serial bus to the FPGA does put a limit on how fast the DIO can be read or set. Depending on the needs of the application the code can be structured to provide a bit of flexibility in speeds.
The "ts7500.subr" file provides the simplest method for accessing these DIO, but not the fastest:
# If you're in the initrd:
source /ts7500.subr
# If you're in Debian:
source /initrd/ts7500.subr
#Usage: setdiopin <pin> <1,0,Z> <b>
setdiopin 20 0
#Usage: getdiopin <pin>
getdiopin 21
You can also interface with this DIO in C using the example here.
...
sbuslock();
setdiopin(21, (getdiopin(21) ^ 0x01));
sbusunlock();
...
Using this method of an atomic read-modify-write will achieve about a 20KHz wave with a 50% duty cycle.
...
sbuslock();
setdiopin(21, 1);
setdiopin(21, 0);
sbusunlock();
...
Using this method of atomic writes will achieve about a 30KHz wave with about a 20% duty cycle.
The SBUS link between the FPGA and CPU is SPI with a 16-bit data frame per bus cycle. When setting and reading one pin at a time, a whole 16-bit cycle is used to accomplish the needed goal. If multiple pins need to be set or read at once, a performance gain can be had from reading/writing entire 16bit registers at a time as opposed to iterating through each pin sequentially.
Other factors can contribute to speeds of the SBUS. Since the SBUS is shared across multiple peripherals there could be bus contention. It may also be that there are very few other applications wanting access to the bus, it all depends on usage. There is more overhead in doing a sbuslock() and sbusunlock() after every transaction than there would be to queue up transactions, lock the bus, and then do them all at once. There is also another function provided in sbus.c that is a smarter version of sbusunlock(), it is called sbuspreempt(). sbuspreempt() will check to see if any other applications are blocked in acquiring the lock, if there are, the SBUS is unlocked, giving other applications access to it. If there are no other applications waiting for the lock, the current application retains the lock. The benefit of this, is next time sbuslock() is called, the function returns almost instantly because the lock is already held. This greatly reduces overhead.
It may be necessary to "tune" an application with locking, unlocking, and preempting the SBUS to find what works best if speed is a factor.
The DIO registers are described in the #Syscon section. This board has 40 logical DIO registers on the FPGA to remain consistant with the series, but not all of the pins are brought out. DIO 9 by default is an external reset which is pulled high, and when it is set to 0 the board will reboot. You can disable this functionality by clearing bit 4 of 0x76 in the #Syscon.
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.
Interrupts
This board does not bring out any CPU DIO directly, so to access any IRQs you would require an FPGA customization. There are 2 IRQs connected to the FPGA which are typically used for CAN or the XUART core. The XUARTs by default will poll at 100hz which will be acceptable for most applications accessing the UARTs so this IRQ may not be required. See the #FPGA Programming section for more details.
We include a userspace IRQ patch in our kernels. This allows you to receive interrupts from your applications where you would normally have to write a kernel driver. This works by creating a file for each interrupt in '/proc/irq/<irqnum>/irq'. The new irq file allows you to block on a read on the file until an interrupt fires.
The original patch is documented here.
This example below will work with any of our TS-Socket boards running Linux. This opens the IRQ number specified in the first argument and prints when it detects an IRQ.
#include <stdio.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char **argv)
{
char proc_irq[32];
int ret, irqfd = 0;
int buf; // Holds irq junk data
fd_set fds;
if(argc < 2) {
printf("Usage: %s <irq number>\n", argv[0]);
return 1;
}
snprintf(proc_irq, sizeof(proc_irq), "/proc/irq/%d/irq", atoi(argv[1]));
irqfd = open(proc_irq, O_RDONLY| O_NONBLOCK, S_IREAD);
if(irqfd == -1) {
printf("Could not open IRQ %s\n", argv[1]);
return 1;
}
while(1) {
FD_SET(irqfd, &fds); //add the fd to the set
// See if the IRQ has any data available to read
ret = select(irqfd + 1, &fds, NULL, NULL, NULL);
if(FD_ISSET(irqfd, &fds))
{
FD_CLR(irqfd, &fds); //Remove the filedes from set
printf("IRQ detected\n");
// Clear the junk data in the IRQ file
read(irqfd, &buf, sizeof(buf));
}
//Sleep, or do any other processing here
usleep(10000);
}
return 0;
}
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.
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
- The chip number is encoded in the two LSB.
- 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
- 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,
- 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.
The SPI pins on the TS-7500 are available on the #44 Pin Header. DIO_11 is CS1, DIO_37 is CS2, and DIO_39 is CS3.
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
Temperature Sensor
The TS-752 baseboard has a temperature sensor, which the TS-7500 and TS-7550 speak to via SPI. Information on how this is done is contained in the ts7500.subr script thus:
gettemp() {
# Determine the board model
# If 7500 or 7550, use local function
# For all other boards, use "ts7500ctl --gettemp"
local model=`ts7500ctl -i | grep "^model=" | cut -d= -f2 | cut -c3-`
if [ "$model" -ne 7500 -a $model -ne 7550 ]; then
eval `ts7500ctl --gettemp`
echo $temperature
return
fi
local n x val
setdiopin 22 0
setdiopin 12 Z
n=0
while [ $n -lt 13 ]; do
setdiopin 14 0
setdiopin 14 1
x=`getdiopin 12`
if [ "$x" -eq 0 ]; then
let val="val << 1"
else
let val="(val << 1) | 1"
fi
let n="n + 1"
done
setdiopin 22 Z
setdiopin 14 Z
if [ $((val & 0x1000)) -ne 0 ]; then
val=$(((~(val & 0xfff) & 0xfff) + 1))
val=$((val * 62500))
printf "-%d." $((val / 1000000))
printf "%d\n" $(((val % 1000000) / 100000))
else
val=$((val * 62500))
printf "%d." $((val / 1000000))
printf "%d\n" $(((val % 1000000) / 100000))
fi
return $val
}
External Interfaces
44 Pin Header
The 44 pin header contains almost all of the I/O on the TS-7500. On the baseboard, typically the 4 JTAG pins are left hanging:
The CN-PC104-40PIN-F is available as a mating connector to this header.
|
|
Note: | Use of the JTAG pins for programming the board is not supported or recommended. |
None of the DIO are tolerant to 5V. The FPGA DIO all support up to 3.3V with 12mA drive capability.
TS-752
See the TS-752 page for more information on the other available connectors.
COM Ports
The XUART ports will be controlled with xuartctl. By default they will not have devices in /dev/. Keep in mind these will be brought out in different locations when using a TS-752.
Name | Type | Location | TX Enable |
---|---|---|---|
ttyS0 | TTL | pins 7 (TX) and 8 (RX) of the ##44 Pin Header. | N/A |
XUART0 | TTL | pins 5 (TX) and 6 (RX) of the #44 Pin Header. | N/A |
XUART1 | TTL | pins 19 (TX) and 20 (RX) of the #44 Pin Header. | pin 27 of the #44 Pin Header |
XUART2 | TTL | pins 21 (TX) and 22 (RX) of the #44 Pin Header | pin 28 of the #44 Pin Header |
XUART3 | TTL | pins 23 (TX) and 24 (RX) of the #44 Pin Header | N/A |
XUART4 | TTL | pin 25 (TX) and 26 (RX) on the #44 Pin Header | N/A |
XUART5 | TTL | pin 31 (TX) and 32 (RX) on the #44 Pin Header | pin 29 of the #44 Pin Header |
XUART6 | TTL | pin 34 (RX) and 33 (TX) on the #44 Pin Header | pin 30 of the #44 Pin Header |
XUART7 | TTL | pin 36 (RX) and 35 (TX on the #44 Pin Header | N/A |
Tips
SD Best Practices
Disk corruption is a common issue in embedded development and considerations must be made for a robust system. When used correctly, the Sandisk SD cards we include should provide a total write lifetime of around 8TB.
Counterfit cards, or bad media
It's been quoted from a Sandisk engineer that a third of the Sandisk branded flash cards on the planet are fake. We recommend Sandisk SD cards as that is what we use for our testing, but make sure you use a reputable source for acquiring any flash media.
We recommend avoiding ATP flash media as well as "Industrial SD cards". We have experienced corruption with Industrial Cards, though they seem to work if multiwrite is disabled but this makes the card extremely slow to write.
Interrupting a Write
Most issues are caused by interrupting a write to the storage media by disconnecting power. In a normal Linux environment for a server or desktop the start up and shutdown sequences should be very predictable, but on an embedded system a safe shutdown cannot always be guaranteed.
The most common issue is when powering off SD cards in the middle of a write. SD cards usually use MLC NAND flash for storage coupled with a manufacturer and model specific firmware. The NAND flash has a limitation where in order to perform a single byte write it must first read about 128KB to 256KB (or more) containing that byte into memory and erase that sector on the NAND chip. This is the erase block size and can vary based on the card. It takes the block in memory, changes the single byte in that copy, erases the intended location on the flash and then commits it back to the disk.
Most SD card firmwares also contain a wear leveling mechanism where they maintain a logical to physical mapping. This means that writing a contiguous file may actually end up in different areas in the NAND chip. If you interrupt a write cycle where it has erased a block, but not yet committed changes to the disk it will have lost data seemingly randomly across the card. There are several strategies you can adopt to avoid or limit your chance of corruption.
The most safe method is possible if you do not need to perform any writes that need to persist across reboots. If you are designing a data logger this is certainly not a good option, but if you're only responding to outside I/O this is your best choice. Once you get your application developed and ready for deployment you should try running from the initrd. This is already a read only filesystem which will never write to the disk. Powering off in the middle of a read is still safe. You can still write data to /tmp/ which will go to memory, but it will be lost on a poweroff. If you require the full Debian filesystem you could use the linuxrc-sdroot-readonly startup script. This will mount the Debian filesystem on the SD card as read only, but will commit any attempted writes to a ramdisk using unionFS. The downside to this configuration while booting to Debian is that you have to manage all writes to the system or risk filling up your memory and causing a crash.
The next best method is to use a battery backup. Most UPS backup solutions, or one you build yourself should contain a method to see the battery level. Once you reach lower levels you can simply run a "shutdown -h now". When power is available the board will boot back up, but you may want to check in the initrd while it is read only if the battery is back to an acceptable level before making the SD card read/write.
The last option is to limit your writes to reduce the chance of corruption. Make all of your writes to a ramdisk like /tmp/ and copy them to the physical media periodically or when you know power will be safe. This is the option many consumer electronics choose. You can make writes more predictable by mounting with the options "sync" which will stop linux from buffering writes in RAM, and "noatime" which will prevent linux from writing access times when reading a file.
If your application is losing power from users disconnecting it or powering it off you may want to consider using an LED to indicate when it is not safe to turn off. Most people have seen cameras or video games that say "Do not remove power while X is displaying" which is usually a graphic of a disk or an LED like on floppy drives to indicate that there is a write that should not be interrupted. You can implement this very simply with a system call:
system("ts7500ctl --redledon");
usleep(350000);
int ret = write(...);
system("ts7500ctl --redledoff");
The usleep allows the user time to react to a new write. Most people should be able to react to an LED in about 215ms, but to be safe I would use a higher number.
You may also want to consider using the XNAND which from our testing has proven to be much more reliable with sudden power loss.
Other Resources
Production Procedure
The stock boards contain a hook in the startup procedure that can be used to easily replicate an image from a thumb drive. The default linuxrc script will:
- Check for a USB drive
- Turn on red LED
- If detected load USB and ethernet modules
- Mount the first partition of the drive
- Execute tsinit which should contain any blasting mechanism
- Turn off red LED
To prepare the USB drive, erase any existing partitions and replace them with a single FAT32 or EXT2/EXT3 partition. The script will attempt to mount /dev/sda1. The linuxrc script will execute a file on the drive named "tsinit". Make sure the script is marked as executable.
This example expects an xnand-image.dd and/or an sd-image.dd in the root of the flash drive. If you exclude either, it will still run while only programming one. Normally, it will begin programming both and wait for them both to finish executing. When the script exits, the red LED will turn off automatically.
#!/bin/sh
# The linuxrc file will mount the USB drive in /mnt/usbdev/, so any
# files you access must use that path.
## Program Nand ##
killall nandctl
nandctl -XW 2048 -z 131072 -i /mnt/usbdev/xnand-image.dd &
## Program SD ##
dd if=/mnt/usbdev/sd-image.dd bs=32k conv=sync of=/dev/nbd5 &
## Program Onboard and Offboard SPI flash ##
spiflashctl -l 0 -W 64 -z 65536 -i /mnt/usbdev/spiflash-image.dd &
spiflashctl -l 1 -W 64 -z 65536 -i /mnt/usbdev/spiflash-image.dd &
wait
You could also mount a network drive and write the image from NFS rather than keeping the image on the USB drive.
Errata
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
/initrd/bin/busybox devmem 0x70000004 32 0x43075
This will disable the link speed auto-negotiation and force the PHY to communicate at 10Mb/s.
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)
Incorrect DDR-RAM timing
Synopsis | Incorrect DDR-RAM timing causing RAM corruption |
Severity | High |
Class | Hardware bug |
Affected | TS-7500 FPGA rev 0x04 and below
TS-7550 FPGA rev 0x03 and below TS-7552 FPGA rev 0x02 and below TS-7553 FPGA rev 0x00 TS-4500 FPGA rev 0x02 and below |
Status | Workarounds available |
Description:
One of the RAM timing registers has a value that is not completely compatible with our hardware layout. This bug has the ability to manifest single bit-flips at various temperatures and yet work correctly in another temperature range. This can cause issues with USB read/write (due to heavy DMA use), system instability, or system hangs (which by default results in a reboot due to the WDT). You can query your FPGA revision with the following command:
ts7500ctl -i
Workaround:
The permanent fix is to send back your SBC to us for reprogramming. There is a way however to modify the RAM timing register once the SBC is booted up and operational. The command:
devmem 0x72000030 32 0x22
Will put the correct timing value in the timing register, however, this leaves the SBC vulnerable to this corruption until the command is issued.
SPI Flash Vendor Change
Synopsis | Due to an EOL notice, the SPI flash on this product has changed. |
Severity | Low |
Class | EOL part |
Affected | TS-7500 |
Status | Software updates |
Description:
Due to an EOL notice, the SPI flash on this product is changing. The old part is a Micron N25Q064A13ESE40F. Two new parts were qualified to reduce the impact of any potential EOL in the future. The new parts are the Microchip's SST26VF064BA, and ISSI's IS25LP064A.
Most applications will not be affected by this change unless a custom kernel and initramfs are being written to the SPI flash. In those cases some updates will be required.
Changes Required:
The tool 'spiflashctl' in the initramfs needs to be updated in order to support the new SPI parts. This is most easily done with a full image update. However it is possible to update just the binary itself which is located on the initramfs partition.
Product Notes
FCC Advisory
This equipment generates, uses, and can radiate radio frequency energy and if not installed and used properly (that is, in strict accordance with the manufacturer's instructions), may cause interference to radio and television reception. It has been type tested and found to comply with the limits for a Class A digital device in accordance with the specifications in Part 15 of FCC Rules, which are designed to provide reasonable protection against such interference when operated in a commercial environment. Operation of this equipment in a residential area is likely to cause interference, in which case the owner will be required to correct the interference at his own expense.
If this equipment does cause interference, which can be determined by turning the unit on and off, the user is encouraged to try the following measures to correct the interference:
Reorient the receiving antenna. Relocate the unit with respect to the receiver. Plug the unit into a different outlet so that the unit and receiver are on different branch circuits. Ensure that mounting screws and connector attachment screws are tightly secured. Ensure that good quality, shielded, and grounded cables are used for all data communications. If necessary, the user should consult the dealer or an experienced radio/television technician for additional suggestions. The following booklets prepared by the Federal Communications Commission (FCC) may also prove helpful:
How to Identify and Resolve Radio-TV Interference Problems (Stock No. 004-000-000345-4) Interface Handbook (Stock No. 004-000-004505-7) These booklets may be purchased from the Superintendent of Documents, U.S. Government Printing Office, Washington, DC 20402.
Limited Warranty
See our Terms and Conditions for more details.
Trademarks
Arm9 is a trademark, and Arm is a registered trademark, of Arm Limited (or its subsidiaries) in the US and/or elsewhere.