TS-4900
Known issues
This is a product still in the sample period, and so it has a few issues before it enters full production.
- FPGA bitstream is under development
- When this is fixed all that will be needed is a "/boot/ts4900-fpga.bin" update.
- Currently some of the UARTs are unavailable.
- Muxbus is not implemented yet
- Bluetooth is currently non functional. This will be fixed in PCB rev B.
- This will be fixed with an FPGA and kernel update which will correctly cycle reset
- The second ethernet on the 8390/8900/8100 using the smsc95xx, and the WIFI currently use random mac addresses
- Our production process allocates additional sequential MAC addresses, so WIFI will be eth0's mac plus one, and the smsc95xx plus two.
- REV A boards include a mod to connect CN2_34 and CN2_54 to fix the audio clock.
If you would like to be notified when any of these issues are resolved, please send an email to support@embeddedarm.com with information on the issue you would like updates on.
Product Page | |||
Documentation | |||
---|---|---|---|
Schematic | |||
Mechanical Drawing | |||
FTP Path | |||
Processor | |||
Freescale i.MX6 Quad core, or Solo | |||
1GHz Commercial, 800MHz Industrial | |||
ARMv7 Cortex-A9 | |||
i.MX6 Quad Product Page | |||
i.MX6 Solo Product Page | |||
IMX6Q Reference Manual | |||
IMX6S Reference Manual | |||
RAM | |||
2GB DDR3 (1GB on Solo) | |||
FPGA | |||
Lattice ICE40 | |||
External Interfaces | |||
USB 2.0 1 host, 1 OTG (host or device) | |||
1x 10/100/1000 Ethernet | |||
802.11BGN | |||
1x I2C/TWI | |||
2x SPI | |||
4x | |||
2x CAN | |||
MUXBUS | |||
Internal Storage Media | |||
1x MicroSD | |||
1x eMMC 4GB | |||
External Storage Media | |||
1x SATA | |||
Power Requirements | |||
5VDC | |||
Operates around TBD | |||
Operating Temperature (Industrial) | |||
| |||
| |||
Operating Temperature (Commercial) | |||
| |||
| |||
Mechanical | |||
75.00mm X 55.00mm | |||
Height 9.75mm (approx without baseboard) | |||
Weight 20.4 (approx) |
Overview
The TS-4900 is a TS-Socket Macrocontroller Computer on Module designed for high performance applications.
Getting Started
A Linux PC is recommended for development, and will be assumed for this documentation. For users in Windows or OSX we recommend virtualizing a Linux PC. Most of our platforms run Debian and if there is no personal distribution preference this is what we recommend for ease of use.
Virtualization
Suggested Linux Distributions
It may be possible to develop using a Windows or OSX system, but this is not supported. Development will include accessing drives formatted for Linux and often Linux based tools.
Booting up the board
WARNING: | Be sure to take appropriate Electrostatic Discharge (ESD) precautions. Disconnect the power source before moving, cabling, or performing any set up procedures. Inappropriate handling may cause damage to the board. |
If you are using one of our off the shelf baseboards you will need to refer to that baseboard's manual here. Different baseboards use different power connectors, voltage ranges, and may have different power requirements.
The System-on-Module (SoM) only requires a 5V rail from the baseboard which may be regulated from other voltage ranges. Refer to the #TS-Socket Connector section for the POWER pins. The TS-4900 draws from 0.85W to 6W depending on how idle the processor is, and if you are using a solo, dual, or quad core. A typical power supply for just the SoM will allow around 1.5 A @ 5 V, but a larger power supply may be needed depending on your peripherals.
Once you have applied power to your baseboard you should look for console output. The next section of the manual provides information on getting the console connected. The first output is from U-Boot:
U-Boot 2013.10-00049-g311750c (Jul 10 2014 - 10:37:04) CPU: Freescale i.MX6Q rev1.2 at 792 MHz Reset cause: POR Board: TS-4900 DRAM: 2 GiB MMC: FSL_SDHC: 0, FSL_SDHC: 1 SF: Detected N25Q64 with page size 256 Bytes, erase size 4 KiB, total 8 MiB *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Net: using phy at 7 FEC [PRIME] Hit any key to stop autoboot: 0
The default U-Boot will check for USB updates, and then will check the "SD Boot" jumper. If the SD boot jumper is set, it will boot to the Linux on the SD card. If it is not set, it will boot to the eMMC.
Note: | The "*** Warning - bad CRC, using default environment" can be safely ignored. If you "env save" this will use your environment on the disk, but on new boards the SPI flash is erased so it just doesn't have a modifed env saved. |
Get a Console
The console UART (ttymxc0) is a TTL UART at 115200 baud, 8n1 (8 data bits 1 stop bit), and no flow control. On the macrocontroller this is CN2_93 (TX), CN2_95 (RX). Various baseboards bring this out using different methods. The TS-8550 and TS-8200 baseboards bring out a DB9 connector with the console as RS232. Other baseboards have a jumper to switch between the console port and another serial port. Some baseboards require an adapter board like the TS-9449. Refer to the baseboard model you are using [Main_Page#Baseboards|here]] for more information on any specific jumpers or ports to connect to for console.
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.
U-Boot
The TS-4900 includes u-boot as the bootloader to launch the full operating system. When the i.MX6 processor starts it loads u-boot from the onboard 8MB SPI flash. This allows you to include your boot image on either the SD, eMMC, SATA, NFS, or USB. U-boot is a general purpose bootloader that is capable of booting into common Linux distributions, Android, QNX, or others.
On a normal boot you should see something similar to this:
U-Boot 2013.10-00034-ga8a4e60 (May 02 2014 - 12:19:18) CPU: Freescale i.MX6Q rev1.2 at 792 MHz Reset cause: POR Board: TS-4900 DRAM: 2 GiB MMC: FSL_SDHC: 0, FSL_SDHC: 1 SF: Detected N25Q64 with page size 256 Bytes, erase size 4 KiB, total 8 MiB In: serial Out: serial Err: serial Net: using phy at 7 FEC [PRIME] Hit any key to stop autoboot: 5
By default the board will boot to SD or eMMC depending on the status of CN1_98/MODE2 on startup. On our off the shelf baseboards this pin is brought out as the "SD Boot" jumper. This can be customized further in u-boot as described below.
U-Boot Environment
The eMMC flash contains both the U-Boot executable binary and U-Boot environment. Our default build has 2 MiB of environment space which can be used for variables and boot scripts. The following commands are examples of how to manipulate the U-Boot environment:
# Print all environment variables
env print -a
# Sets the variable bootdelay to 5 seconds
env set bootdelay 5;
# Variables can also contain commands
env set hellocmd 'led red on; echo Hello world; led green on;'
# Execute commands saved in a variable
env run hellocmd;
# Commit environment changes to the SPI flash
# Otherwise changes are lost
env save
# Restore environment to default
env default -a
# Remove a variable
env delete emmcboot
U-Boot Commands
# The most important command is
help
# This can also be used to see more information on a specific command
help i2c
# This is a command added to U-Boot by TS to read the baseboard ID on our
# System on Module devices
bbdetect
echo ${baseboard} ${baseboardid}
# The echo will return something similar to:
# TS-8390 2
# Boots into the binary at $loadaddr. The loaded file needs to have
# the U-Boot header from mkimage. A uImage already contains this.
bootm
# Boots into the binary at $loadaddr, skips the initrd, specifies
# the FDT addrress so Linux knows where to find the device tree
bootm ${loadaddr} - ${fdtaddr}
# Boot a Linux zImage loaded at $loadaddr
bootz
# Boot in to a Linux zImage at $loadaddr, skip initrd, specifies
# the FDT address to Linux knows where to find the device tree
bootz ${loadaddr} - ${fdtaddr}
# Get a DHCP address
dhcp
# This sets ${ipaddr}, ${dnsip}, ${gatewayip}, ${netmask}
# and ${ip_dyn} which can be used to check if the dhcp was successful
# These commands are used for scripting:
false # do nothing, unsuccessfully
true # do nothing, successfully
# This command can set fuses in the processor
# Setting fuses can brick the unit, will void the warranty,
# and should not be done in most cases
fuse
# GPIO can be manipulated from U-Boot. Keep in mind that the IOMUX
# in U-Boot is only setup enough to boot the device, so not all pins will
# be set to GPIO mode out of the box. Boot to the full operating system
# for more GPIO support.
# GPIO are specified in bank and IO in this manual. U-Boot uses a flat numberspace,
# so for bank 2 DIO 25, this would be number (32*1)+25=89
# The formula thus being (32*(bank-1)+dio)=flattened_dio
# Note that on some products, bank 1 is the first bank
# Set 2_25 low
gpio clear 83
# Set 2_25 high
gpio set 83
# Read 2_25
gpio input 83
# Control LEDs
led red on
led green on
led all off
led red toggle
# This command is used to copy a file from most devices
# Load kernel from SD
load mmc 0:1 ${loadaddr} /boot/uImage
# Load Kernel from eMMC
load mmc 1:1 ${loadaddr} /boot/uImage
# Load kernel from USB
usb start
load usb 0:1 ${loadaddr} /boot/uImage
# Load kernel from SATA
sata init
load sata 0:1 ${loadaddr} /boot/uImage
# View the FDT from U-Boot
load mmc 0:1 ${fdtaddr} /boot/imx6q-ts4900.dtb
fdt addr ${fdtaddr}
fdt print
# It is possible to blindly jump to any memory location
# This is similar to bootm, but it does not require
# the use of the U-Boot header
load mmc 0:1 ${loadaddr} /boot/custombinary
go ${loadaddr}
# Browse fat, ext2, ext3, or ext4 filesystems:
ls mmc 0:1 /
# Access memory like devmem in Linux, read/write arbitrary memory
# using mw and md
# write
mw 0x10000000 0xc0ffee00 1
# read
md 0x10000000 1
# Test memory.
mtest
# Check for new SD card
mmc rescan
# Read SD card size
mmc dev 0
mmcinfo
# Read eMMC Size
mmc dev 1
mmcinfo
# The NFS command is like 'load', but used over the network
dhcp
env set serverip 192.168.0.11
nfs ${loadaddr} 192.168.0.11:/path/to/somefile
# Test ICMP
dhcp
ping 192.168.0.11
# Reboot
reset
# SPI access is through the SF command
# Be careful with sf commands since
# this is where U-Boot and the FPGA bitstream exist
# Improper use can render the board unbootable
sf probe
# Delay in seconds
sleep 10
# Load HUSH scripts that have been created with mkimage
load mmc 0:1 ${loadaddr} /boot/ubootscript
source ${loadaddr}
# Most commands have return values that can be used to test
# success, and HUSH scripting supports comparisons like
# test in Bash, but much more minimal
if load mmc 1:1 ${fdtaddr} /boot/uImage;
then echo Loaded Kernel
else
echo Could not find kernel
fi
# Commands can be timed with "time"
time sf probe
# Print U-Boot version/build information
version
Update u-boot
WARNING: | Installing your own u-boot is not recommended and may cause the board to fail to boot. |
U-boot requires a different build for Quad/Dual and Solo/Duallite. Flashing the wrong u-boot will cause the board to fail to properly boot. Recovery in this case would require a TS-8550, or submitting an RMA.
On your current u-boot, type "env print imx_type" and this will return the u-boot build you should use. Copy the u-boot.imx to the SD card, and run:
mmc dev 0
load mmc 0:1 ${loadaddr} /u-boot.imx
sf probe
sf erase 0 0x50000
sf write ${loadaddr} 0x400 $filesize
Modify Linux Kernel cmdline
The Linux kernel cmdline can be customized by modifying the cmdline_append variable. The variable contents are clobbered when set, so be sure to specify the full desired cmdline string.
env set cmdline_append console=ttymxc0,115200 init=/sbin/init quiet
env save
The kernel command line can also be modified from from the on-board Linux. Debian (and other distributions) provide a U-Boot utilities package that contains the tools necessary to create a U-Boot script:
apt-get update && apt-get install u-boot-tools -y
echo "env set cmdline_append console=ttymxc0,115200 init=/sbin/init quiet" > /boot/boot.scr
mkimage -A arm -T script -C none -n 'tsimx6 boot script' -d /boot/boot.scr /boot/boot.ub
The boot.scr includes the plain text commands to be run in U-Boot on startup. The mkimage tool adds a checksum and header to this file which can be loaded by U-Boot. The .ub file should not be edited directly.
Linux NFS Boot
U-Boot's NFS support can be used to load a kernel, device tree binary, and root filesystem. The default scripts include an example NFS boot script.
# Set this to your NFS server ip
env set serverip 192.168.0.11;
# Set this to your NFS root path. The server root should be accessible at this path.
env set nfsroot /path/to/nfs/rootfs/
env save
To boot your NFS root:
# Boot to NFS once
run nfsboot;
# To make the NFS boot the persistent default
env set bootcmd run nfsboot;
env save
Yocto
Getting Started with Yocto
Yocto itself is a set of scripts and tools used to build a custom Distribution. In our default images we try to include all of the common utilities requested by users so rebuilding Yocto should not be necessary in many cases. Our Yocto rootfs is available here:
Yocto Image | Quad | Solo |
ts-x11-image | Download | Download |
These images are similar, but the Quad and Solo include different OpenGLES libraries. To write this to an SD card, first partition the SD card to have one large ext4 partition. See the guide here for more information. Once it is formatted, extract this tar with:
# Assuming your SD card is /dev/sdc
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar -jxf ts-x11-image-ts4900-quad.rootfs.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync
Yocto Networking
Our Yocto image uses systemd which stores its network files in /etc/systemd/network/
. Yocto will automatically enable DHCP on its wired interfaces. This can be overridden to set a static IP or enable other options for DHCP. The only requirement is that this file is named /etc/systemd/network/XX-wired.network
Where "XX" is a number smaller than 80, e.g. /etc/systemd/network/79-wired.network
This format must be used for all eth*
and en*
named network interfaces. The lower file names will take priority.
An example of a static configuration would be:
/etc/systemd/network/42-wired.network
[Match]
Name=eth0
[Network]
Address=192.168.0.50/24
Gateway=192.168.0.1
DNS=192.168.0.1
DNS will be loaded from /etc/resolv.conf. To make this use a static DNS:
rm /etc/resolv.conf
echo "nameserver 8.8.8.8" > /etc/resolv.conf
echo "nameserver 8.8.4.4" >> /etc/resolv.conf
To use the DNS assigned by DHCP, run:
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
For more information on what options are available to configure the network, see the systemd network documentation.
Yocto Application Development
Yocto provides a cross toolchain including the native tools and required ARM libraries. The cross toolchain is only available for 64bit Linux host PCs. Download the toolchain by saving the following link:
In order to install the toolchain, use the following commands to run the installation script:
chmod a+x poky-*.sh
sudo ./poky-*.sh
In order to use the toolchain, the environment for it must be sourced to the current terminal before it can be used to build applications: To build an application first source the environment for the toolchain:
source /opt/poky/3.0.2/environment-setup-cortexa9t2hf-neon-poky-linux-gnueabi
# This command sets up paths for the shell along with a number of other
# environment variable. For example:
$ echo $CC
arm-poky-linux-gnueabi-gcc -march=armv7-a -marm -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/opt/poky/2.2.2/sysroots/cortexa9hf-vfp-neon-poky-linux-gnueabi
# Cross compiling a simple hello world program:
$CC hello.c -o hello
It is also possible to develop applications directly on the device via serial console or ssh. Yocto includes development tools such as vim, gcc, g++, gdb, make, autoconf, binutils, etc. See the next sections for using the cross toolchain with IDEs.
Yocto with Eclipse IDE
Configure QT Creator IDE
Note: | This guide is intended for our stock Yocto image using systemd. On custom images, the same instructions should apply if a cross toolchain is built. This can be built through Yocto with bitbake meta-toolchain-qt5 . Be sure to update the paths if using a different distribution.
|
Install the qtcreator tool on a host Linux PC. Any recent version from a modern Linux distribution should be sufficient and work without issue. On a Debian/Ubuntu desktop, run:
sudo apt-get update && sudo apt-get install qtcreator -y
The SDK which includes the Qt support will also need to be downloaded. The cross toolchain is only available for 64-bit Linux host PCs:
In order to install the toolchain, use the following commands to run the installation script:
chmod a+x poky-*.sh
sudo ./poky-*.sh
These instructions assume the installation path will be the default at /opt/poky/3.0.2/
Note: | An environment script has to be sourced before every execution of qtcreator. Without this, builds will fail. |
source /opt/poky/3.0.2/environment-setup-cortexa9t2hf-neon-poky-linux-gnueabi
qtcreator
Qt Creator needs to be configured to build using this toolchain. Once Qt Creator is launched, select Tools->Options->Devices
Click Add
, select Generic Linux Device
, and then click Start Wizard
On the next page specify the IP address or hostname of the device running Yocto. In this example, the unit has an IP address of 192.168.2.45
obtained via DHCP. The default Yocto image will use the user root
with no password to connect. Set the name to TSIMX6
It will then verify connectivity. Click close and continue.
Note: | The paths given in the images below may not match the latest toolchain, but are meant to show where these values would go. Follow the text appropriate to the architecture of your host PC for the correct values |
In the left column of the Options
menu, select Build & Run
. On the Qt Versions
tab, click Add
in the upper right to configure the TS Kit. Qt Creator may see the qmake
binary added to your path from the sourced environment script. If this is detected, add in the string TSIMX6
to the title as shown in the photo below. If it is not autodetected, add the full path and ensure the version name is set to TSIMX6 Qt 5.13.2
. This will allow it to be recognized when setting the right binary for the kit.
/opt/poky/3.0.2/sysroots/x86_64-pokysdk-linux/usr/bin/qmake
On the Compilers
tab click Add
, select GCC
then C
. Set the Name to TSIMX6 GCC
. For the Compiler Path
use the following:
/opt/poky/3.0.2/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc
Repeat the above steps for the g++ compiler; click Add
, select GCC
then C++
. Set the name to TSIMX6 G++
. And for the Compiler Path
use the following:
/opt/poky/3.0.2/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++
On the Debuggers
tab click Add
. For name, specify TSIMX6 GDB
. For the path, specify the location of gdb with the following:
/opt/poky/3.0.2/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gdb
On the Kits
tab click Add
. For Name
, enter TSIMX6
. Set device type to Generic Linux Device
. Set the device to TSIMX6 (default for Generic Linux)
. Set Qt mkspec
to the following (make sure there is no space at the end):
/opt/poky/3.0.2/sysroots/cortexa9t2hf-neon-poky-linux-gnueabi/usr/lib/mkspecs/linux-oe-g++
Set C Compiler
to TSIMX6 GCC
and C++ Compiler
to TSIMX6 G++
. Set Debugger
to TSIMX6 GDB
. Set the Qt version
to TSIMX6 QT 5.13.2
. Finally, click Apply.
Note: | If there is a red exclamation point over the kits icon, it indicates that the compiler ABI does not match. In this case, you will need to revisit the "Compiler", "Debugger", and "Qt Versions" tabs, and browse the host PC for these files manually rather than copy/pasting the paths from these instructions. This is a bug in Ubuntu 16.04's Qt Creator, and may be in later versions as well. |
At this point Qt Creator is set up to begin a hello world project.
QT Creator Hello World
Open the Qt Creator IDE and click New Project
.
Qt provides multiple templates for application development. For this example select the default Qt Widgets Application
.
Specify the location for your project. Keep in mind that the compile process will create more build paths in the Create In:
path.
Next, select the kit. The TSIMX6
is the kit we set up in the last section, but you may have other kits pre-installed on your system. These can be used for testing graphical development on your PC. Keep in mind distribution versions may contain different functionality.
Next select the class and filename information. This example will use the defaults.
Select any version control for the project. The example will use none and finish the wizard. This will generate the new project.
Click the button under Help
on the left column, and select TSIMX6
debug. If there is only one kit selected, this will be default.
Now return to edit, and open the Qt project file, qt5-helloworld.pro
. Add in these lines anywhere after the target is specified:
linux-* {
target.path = /home/root
INSTALLS += target
}
Last, the DISPLAY
must be selected. This is done by setting a run environment variable that will be set when the application is run on the board.
At this point click the green allow in the bottom left to run the application. This can also be launched from the menu at Build->Run
.
From here, you can begin customizing your application. Refer to the official Qt documentation for more information
Custom Build Yocto (Advanced)
We have tried to include all of the common requests in our default images. If there is a package missing from the default image, it may be simpler to build that individual package using the cross compiler rather than rebuilding the image. Rebuilding an image can take hours, or days depending on build pc and the complexity of the image. If you have a case where rebuilding yocto is required for your project, you can find our build instructions here:
Debian
Debian is a community run distribution that provides tens of thousands of precompiled packages. This distribution is known for stability and has a large community contributing and providing support. This distribution does not have all of the same patches necessary for OpenGL ES or Gstreamer, but it works very well for 2D interfaces such as simple QT or GTK windows without animation. Debian also will work very well for headless applications.
Getting Started with Debian
Debian Networking
Debian Onboard development
Backup / Restore
MicroSD Card
These instructions assume you have an SD card with one partition. Most SD cards ship this way by default. If the card has had its partition table modified this can be corrected with a tool like 'gparted' or 'fdisk'.
Plug the SD card into a USB reader and connect it to a linux workstation PC. Newer distributions include a utility called 'lsblk' which lists all block devices like a USB SD card reader:
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sdY 8:0 0 400G 0 disk ├─sdY1 8:1 0 398G 0 part / ├─sdY2 8:2 0 1K 0 part └─sdY5 8:5 0 2G 0 part [SWAP] sr0 11:0 1 1024M 0 rom sdX 8:32 1 3.9G 0 disk ├─sdX1 8:33 1 7.9M 0 part ├─sdX2 8:34 1 2M 0 part ├─sdX3 8:35 1 2M 0 part └─sdX4 8:36 1 3.8G 0 part
In this case the SD card is 4GB, so sdX is the target device. Note that on your system, sdX will not be a real device, it could be sda, sdb, mmcblk0, etc. Technologic Systems is not responsible for any damages cause by using the improper device node for imaging an SD card.
After plugging in the device after Linux has booted you can use dmesg to print out the kernel log. When the USB drive is added it will append to the end of that file. Try running:
dmesg | tail -n 100
scsi 54:0:0:0: Direct-Access Generic Storage Device 0.00 PQ: 0 ANSI: 2 sd 54:0:0:0: Attached scsi generic sg2 type 0 sd 54:0:0:0: [sdX] 3862528 512-byte logical blocks: (3.97 GB/3.84 GiB)
Make sure the partition table is using the MBR scheme and not GPT.
In this case, sdXc is shown as a 3.97GB card. Note that on your system, sdX will not be a real device, it could be sda, sdb, mmcblk0, etc. Technologic Systems is not responsible for any damages cause by using the improper device node for imaging an SD card.
The following commands will reformat the first partition of the SD card, and unpack the latest filesystem on there:
# Verify nothing else has this mounted
sudo umount /dev/sdX1
sudo mkfs.ext3 /dev/sdX1
sudo mkdir /mnt/sd
sudo mount /dev/sdX1 /mnt/sd/
wget https://files.embeddedTS.com/ts-socket-macrocontrollers/ts-4900-linux/distributions/debian/debian-armhf-bullseye-latest.tar.bz2
sudo tar --numeric-owner -xf debian-armhf-bullseye-latest.tar.bz2 -C /mnt/sd
sudo umount /mnt/sd
sync
Note: | The ext4 filesystem can be used instead of ext3, but it may require additional options. U-Boot does not support the 64bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options "-O ^64bit,^metadata_csum" must be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed nor are they needed for ext3. |
Once written, the files on disk can be verified to ensure they are the same as the source files in the archive. Reinsert the disk to flush the block cache completely, then run the following commands:
mount /dev/sdX1 /mnt/sd
cd /mnt/sd/
sudo md5sum --quiet -c md5sums.txt
cd -
umount /mnt/sd
sync
The md5sum command will report what differences there are, if any, and return if it passed or failed.
eMMC
Write the image:
These commands assume the unit is booted from SD and eMMC is set up with a single partition:
# Verify nothing else has this mounted
umount /dev/mmcblk2p1
mkfs.ext3 /dev/mmcblk2p1
mkdir /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
wget https://files.embeddedTS.com/ts-socket-macrocontrollers/ts-4900-linux/distributions/debian/debian-armhf-bullseye-latest.tar.bz2
tar --numeric-owner -xf debian-armhf-bullseye-latest.tar.bz2 -C /mnt/emmc
umount /mnt/emmc
sync
Note: | The ext4 filesystem can be used instead of ext3, but it may require additional options. U-Boot does not support the 64bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options "-O ^64bit,^metadata_csum" must be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed nor are they needed for ext3. |
After the tarball is unpacked, the data on disk can be verified with md5sum:
# Drop any block cache
echo 3 > /proc/sys/vm/drop_caches
mount /dev/mmcblk2p1 /mnt/emmc
cd /mnt/emmc/
sudo md5sum -c md5sums.txt
umount /mnt/emmc
sync
The md5sum command will report what differences there are, if any, and return if it passed or failed.
Backup the image:
First boot the device to any compatible bootable SD card. The SD needs have enough free space for the compressed image of the data on the eMMC. Our default image eMMC image is ~500MB when compressed. A tarball of the eMMC can be created on the SD card with the following commands:
mkdir /mnt/emmc/
mount /dev/mmcblk2p1 /mnt/emmc/
cd /mnt/emmc/
tar --numeric-owner -cjf /root/emmc-backup.tar.bz2 *
cd /
umount /mnt/emmc/
Compile the Kernel
To add additional driver support, reduce the size of our stock kernel kernel, or to write custom kernel drivers the kernel can be compiled from our sources. The following steps walk through the kernel build process; they are compatible with most of our Linux distributions.
This device has multiple kernels released and available in our git repository:
Newer kernels are released on the linux-tsimx
repository:
- embeddedTS/linux-tsimx
- The "ts-imx_4.9.11_1.0.0_ga" branch is the only one that should be used with our i.MX6 series.
For legacy kernels:
- embeddedTS/linux-3.10.17-imx6
- The "master" branch is 3.10.17 and is largely outdated and replaced with later kernels. This is used with the old Yocto Dora builds.
- The "imx_3.10.53_1.1.0_ga" kernel is a stable branch. Use this with Yocto Dizzy, Fido, or compatible with Debian Jessie.
- The "imx_3.14.52_1.1.0_ga" branch is compatible with Yocto Jethro, and Debian.
- The "imx_4.1.15_1.0.0_ga" branch is compatible with Yocto Jethro, Yocto Morty and Debian. Includes recent fixes not in older branches. This is recommended for most users.
The kernel can be rebuilt by cross compiling from an x86 or x86_64 Linux workstation. Our stock kernels are built with the toolchains built by Yocto. The appropriate cross toolchain for your Linux workstation can be downloaded here:
Note: | Older kernels will require older toolchains. For older Yocto kernels use a matching Yocto toolchain. For Debian, the latest toolchain and kernel is recommended. |
chmod a+x poky*.sh
sudo ./poky*.sh
This will ask for the install directory for the toolchain. A custom location can be chosen, however the following instructions will assume the default installation location.
This process will also require several applications for the install/build process. These can be installed on an Ubuntu/Debian workstation with the following command:
sudo apt-get install git build-essential lzop u-boot-tools libncursesw5-dev fakeroot bc
Once those are installed:
git clone https://github.com/embeddedTS/linux-tsimx.git -b ts-imx_4.9.11_1.0.0_ga linux-tsimx6 --depth 1
# For legacy kernels instead:
# git clone https://github.com/embeddedTS/linux-3.10.17-imx6.git -b imx_4.1.15_1.0.0_ga linux-tsimx6 --depth 1
# If it is already cloned, the "git pull" command will download and merge the latest changes
# For WiFi support, download qcacld-2.0:
# This is only compatible with 4.1.15 or 4.9.11 kernels
git clone https://github.com/embeddedTS/qcacld-2.0.git -b caf-wlan/CNSS.LEA.NRT_3.1
cd linux-tsimx6
# These export commands must be run every time before any make commands
export ARCH=arm
# For 64-bit
export CROSS_COMPILE=/opt/poky/2.2.2/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-
# For 32-bit
#export CROSS_COMPILE=/opt/poky/2.2.2/sysroots/i686-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-
export LOADADDR=0x10008000
export TEMPDIR=$(mktemp -d)
make ts4900_defconfig
## Make any changes in "make menuconfig" or driver modifications, then compile
make -j8 all uImage zImage
mkdir "$TEMPDIR"/boot/
cp arch/arm/boot/uImage "$TEMPDIR"/boot/uImage
cp arch/arm/boot/zImage "$TEMPDIR"/boot/zImage
cp arch/arm/boot/dts/imx6*-ts*.dtb "$TEMPDIR"/boot/
INSTALL_MOD_PATH="$TEMPDIR" make modules_install
make headers_install INSTALL_HDR_PATH="$TEMPDIR"
# Compile wifi driver:
cd ../qcacld-2.0/
export KERNEL_SRC="../linux-tsimx6/"
make clean
CONFIG_CLD_HL_SDIO_CORE=y make -j8
INSTALL_MOD_PATH="$TEMPDIR" make modules_install
fakeroot sh -c "chmod 755 $TEMPDIR;
chown -R root:root $TEMPDIR;
tar cjvf kernel.tar.bz2 -C $TEMPDIR .;
rm -rvf $TEMPDIR"
This will generate "kernel.tar.bz2" which contains the kernel and necessary modules. It can be installed to the device by copying it to a running unit and executing:
# Only run this on a device! Not on a workstation!
tar -xf kernel.tar.bz2 -C /
This can also be extracted over existing images from a workstation, or removable media like SD cards. For example, assuming the SD card on a workstation is "/dev/sdc":
mkdir /mnt/sd/
mount /dev/sdc1 /mnt/sd/
tar -xf kernel.tar.bz2 -C /mnt/sd/
umount /mnt/sd/
Change Kernel Splash Screen
The kernel splashscreen allow for a 224 color image, up to the full screen resolution. For the fastest boot speed, it should be kept as small as possible. The image will be centered around a black background.
To convert an image, for example, "mylogo.png":
convert mylogo.png mylogo.ppm
ppmquant 224 mylogo.ppm > mylogo-224.ppm
pnmnoraw mylogo-224.ppm > logo_user_clut224.ppm
cp logo_user_clut224.ppm <kernel build sources>/drivers/video/logo/
Recompile the kernel following the guide in the previous section to have the splashscreen appear on all future boots.
Add to the kernel cmdline in U-Boot, "logo.nologo" in order to completely disable the splash screen.
Features
CPU
The i.MX6 is an armv7a Cortex-A9 by NXP. The CPU itself is available in 792MHz, 996MHz, and 1.2GHz with a solo, dual, or quad core processor.
Refer to NXP's documentation for in depth documentation on these CPU cores:
MicroSD Card Interface
The i.MX6 SDHCI driver supports MicroSD (0-2GB), MicroSDHC (4-32GB), and MicroSDXC(64GB-2TB). The cards available on our website on average support up to 16MB/s read, and 22MB/s write using this interface. The linux driver provides access to this socket at /dev/mmcblk1 as a standard Linux block device.
See chapter 67 of the i.MX6 reference manual for the specific CPU variant for more information on the mmc controller.
We have performed compatibility testing on the Sandisk MicroSD cards we provide. We do not suggest switching brands/models without your own qualification testing. While SD cards specifications are standardized, in practice cards behave very differently. We do not recommend ATP or Transcend MicroSD cards due to known compatibility issues.
Our testing has shown that on average microSD cards will last between 6-12TB. After this cards can begin to experience corruption, or stop being recognized by the host PC. This may be enough storage for many applications to write for years without problems. For more reliable storage consider using the eMMC. Our endurance testing showed a write lifetime on average of about 123 TiB.
MicroSD cards should not have power removed during a write or they will have disk corruption. Keep the filesystem mounted read only if this is a possibility. It is not always possible for fsck to recover from the types of failures that will be seen with SD power loss. Consider using the eMMC for storage instead which is far more resilient to power loss.
Interrupts
The i.MX6 CPU GPIO are also able to function as interrupts on rising and falling edges. This is accessible from the kernel as well as userspace. Userspace IRQs are exposed through the sysfs gpio mechanism. This example will trigger on a falling edge for GPIO 48:
echo "48" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio48/direction
echo "falling" > /sys/class/gpio/gpio48/edge
From here, an application can poll() or select() on the "/sys/class/gpio/gpio48/value" file and will return when the edge setting has been triggered:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char **argv)
{
char gpio_irq[64];
int ret, irqfd = 0, i = 0;
fd_set fds;
FD_ZERO(&fds);
int buf;
if(argc < 2) {
printf("Usage: %s <gpio number>\n", argv[0]);
return 1;
}
snprintf(gpio_irq, sizeof(gpio_irq), "/sys/class/gpio/gpio%d/value", atoi(argv[1]));
irqfd = open(gpio_irq, O_RDONLY, S_IREAD);
if(irqfd == -1) {
printf("Could not open IRQ %s\n", argv[1]);
printf("Make sure the GPIO is already exported", argv[1]);
return 1;
}
// Read first since there is always an initial status
ret = read(irqfd, &buf, sizeof(buf));
while(1) {
FD_SET(irqfd, &fds);
// See if the IRQ has any data available to read
ret = select(irqfd + 1, NULL, NULL, &fds, NULL);
if(FD_ISSET(irqfd, &fds))
{
FD_CLR(irqfd, &fds); //Remove the filedes from set
printf("IRQ detected %d\n", i);
fflush(stdout);
i++;
/* The return value includes the actual GPIO register value */
read(irqfd, &buf, sizeof(buf));
lseek(irqfd, 0, SEEK_SET);
}
//Sleep, or do any other processing here
usleep(100000);
}
return 0;
}
This example can be run as "./irqtest 48" which will echo every time the pin changes but not consume any CPU time while waiting for an edge to occur.
RTC
We include the Intersil ISL12020 RTC onboard. This provides a long RTC battery life, as well as a built in temperature sensor to provide ±5 ppm across -40 to 85 C. The RTC appears at "/dev/rtc0" in our images, and is accessed using the standard hwclock command.
NVRAM
The RTC includes 120 bytes of NVRAM which can be used for custom applications. The utility 'nvramctl' can be used to read/write the NVRAM. The source for this utility is available from our ts4900-utils github.
The utility reads/writes a byte at a time, and returns the value in hex.
nvramctl --addr 10 --set 0x40
nvramctl --addr 10 --get
# Returns "nvram10=0x40".
# This can also be used with eval
eval $(nvramctl --addr 10 --get)
echo $nvram10
# Returns "0x40"
The NVRAM code can be included in your application by using these two files:
LEDs
The kernel provides access to control the LEDs using the sysfs:
# Set Red led on
echo 1 > /sys/class/leds/red-led/brightness
# Set Red led off
echo 0 > /sys/class/leds/red-led/brightness
# Set Green led on
echo 1 > /sys/class/leds/green-led/brightness
# Set Green led off
echo 0 > /sys/class/leds/green-led/brightness
The kernel provides various triggers that can be useful for debugging purposes. The trigger for a given LED is in its directory:
echo "heartbeat" > /sys/class/leds/red-led/trigger
Trigger value | LED toggles on |
---|---|
none | Default, no action |
mmc0 | MicroSD card activity |
mmc1 | eMMC activity |
mmc2 | WIFI SDIO activity |
timer | 2hz blink |
oneshot | Blinks after delay. [1] |
heartbeat | Similar to timer, but varies the period based on system load |
backlight | Toggles on FB_BLANK |
gpio | Toggle based on a specified gpio. [2] |
cpu0 | Blink on CPU core 0 activity |
cpu1 | Blink on CPU core 1 activity |
cpu2 | Blink on CPU core 2 activity |
cpu3 | Blink on CPU core 3 activity |
default-on | Only turns on by default. Only useful for device tree. |
transient | Specify on/off with time to turn off. [3] |
flash/torch | Toggle on Camera activation. Not currently used. |
- ↑ See the Kernel documentation for more details
- ↑ When this trigger is set, a "gpio" file appears in the same directory which can be used to specify what GPIO to follow when it blinks
- ↑ See the Kernel documentation for more details
LCD Interface
The TS-4900 provides an RGB24 parallel display, and LVDS outputs. Most user applications access this using the toolkits like QT or GTK which write to /dev/fb0 to access the LCD. See this section for an example on user interface programming.
For custom baseboards using LCDs you will need to specify the LCD timing. The timing is added in drivers/video/mxc/mxc_lcdif.c. The mode string "OKAYA-WVGA" in this case is then referenced in your baseboard's device tree. See this example for the TS-TPC-8390 for the device tree block.
See this section for further detail on which device tree file to use.
Ethernet Port
The i.MX6 includes a 10/100/1000 Ethernet. In Linux this is the eth0 interface. The MAC address uses the Technologic Systems 00:d0:69:00:00:00, and the last 3 octets are assigned from our pool. The MAC address is burned into the CPU's fuses during production, and will be read back automatically by software in Linux or U-Boot. Each board is also assigned 1 additional sequential mac address which is used on some carrier boards that add a second ethernet.
Freescale has a published erratum regarding the maximum Ethernet speed. The default kernel can achieve about 400 Mb/s.
Note: | Ethernet Magnetics should be placed as close to CN2 as possible on the base board. |
GPIO
Note: | It is possible to use memory mapped CPU registers as documented in the CPU reference manual to control GPIO. When using this, be aware that the kernel may attempt to also access these registers for various reasons. Also note that each register represents a bank of GPIO pins. Use a read-modify-write operation to avoid disturbing other GPIO pins. We strongly recommend using the sysfs interface as described below. |
The i.MX6 GPIO are available using the kernel sysfs interface. See the kernel's documentation here for more detail. This interface provides a set of files and directories for interacting with GPIO. This allows GPIO to be accessed from any language that can read and write files. For example, to toggle CN1_89/EIM_A22, the kernel maps this to GPIO 48 (See the table below for the full I/O mapping).
To interact with this pin, first export it to userspace:
echo "48" > /sys/class/gpio/export
If the command returns with a permission denied on a GPIO that means it is claimed by another kernel driver. If it succeeds, the kernel will create the "/sys/class/gpio/gpio48/" directory. The relevant files in this directory are:
direction - "in", "high", "low", or "out". Out is equivalent to low value - write "1" or "0", or read "1" or "0" if direction is in edge - write with "rising", "falling", or "none"
# Set GPIO 48 high
echo "out" > /sys/class/gpio/gpio48/direction
echo "1" > /sys/class/gpio/gpio48/value
# Set GPIO 48 low
echo "0" > /sys/class/gpio/gpio48/value
# Read the value of GPIO 48
echo "in" > /sys/class/gpio/gpio48/direction
cat /sys/class/gpio/gpio48/value
As an output, the "value" file can be written with "0" for low (GND), or "1" for high (3.3V). As an input the GPIO will have a 100k pullup. The GPIO pins from the i.MX6 processor support an absolute maximum voltage range of -0.5 to 3.6V. It is also possible to use any processor GPIO as an interrupt. This is done by writing the "edge" file and using select() or poll() on the "value" file to watch for changes. See the Interrupts section for more details.
The GPIO numbers in the table below are relevant to how the Linux references these numbers. The CPU documentation refers to bank and IO while Linux flattens this out to one number space.
CPU PAD [1] | GPIO Number | Common Functions [2] | Location |
---|---|---|---|
SD4_DAT1 | 41 | LCD_PWM[3], #GPIO | CN1_57 |
KEY_COL2 | 106 | CAN_1_TXD, #GPIO | CN2_97 |
KEY_ROW2 | 107 | CAN_1_RXD, #GPIO | CN2_99 |
KEY_COL0 | 102 | UART4_TXD | CN2_86, #FPGA Muxed |
KEY_ROW0 | 103 | UART4_RXD | CN2_88, #FPGA Muxed |
KEY_COL1 | 104 | UART5_TXD | CN2_90 |
KEY_ROW1 | 105 | UART5_RXD | CN2_92 |
KEY_COL3 | 108 | I2C_2_CLK | CN2_28 |
KEY_ROW3 | 109 | I2C_2_DAT | CN2_30 |
KEY_COL4 | 110 | CAN_2_TXD, #GPIO | CN1_71 |
KEY_ROW4 | 111 | CAN_2_RXD, #GPIO | CN1_69 |
GPIO_0 | 0 | AUD_MCLK | CN2_54 |
GPIO_1 | 1 | USB_OTG_ID | CN2_74 |
GPIO_2 | 2 | Red LED | Onboard |
CSI0_DAT17 [4] | 163 | #GPIO | CN2_56 |
SD4_DAT7 [5] | 47 | #GPIO | CN2_58 |
GPIO_7 | 7 | UART2_TXD | CN2_78, #FPGA Muxed |
GPIO_8 | 8 | UART2_RXD | CN2_80, #FPGA Muxed |
SD3_RST [6] | 200 | #GPIO | CN2_60 |
GPIO_16 | 203 | #GPIO | CN2_62 |
GPIO_17 | 204 | #GPIO | CN2_64 |
GPIO_19 | 101 | #GPIO | CN2_68 |
CSI0_MCLK | 147 | #GPIO | CN2_70 |
CSI0_PIXCLK | 146 | #GPIO | CN2_72 |
CSI0_DAT4 | 150 | AUD_CLK, #GPIO | CN2_36 |
CSI0_DAT5 | 151 | AUD_TXD, #GPIO | CN2_40 |
CSI0_DAT6 | 152 | AUD_FRM, #GPIO | CN2_38 |
CSI0_DAT7 | 153 | AUD_RXD, #GPIO | CN2_42 |
CSI0_DAT8 | 154 | SPI_2_CLK | CN2_71 |
CSI0_DAT9 | 155 | SPI_2_MOSI | CN2_67 |
CSI0_DAT10 | 156 | SPI_2_MISO | CN2_69 |
CSI0_DAT11 | 157 | SPI_2_CS# | CN2_65 |
CSI0_DAT12 | 158 | #GPIO | CN2_52 |
CSI0_DAT13 | 159 | #GPIO | CN2_66 |
DI0_DISP_CLK | 112 | LCD_CLK, #GPIO | CN1_49 |
DI0_PIN2 | 114 | LCD_HSYNC, #GPIO | CN1_51 |
DI0_PIN3 | 115 | LCD_VSYNC, #GPIO | CN1_53 |
DI0_PIN15 | 113 | LCD_DE, #GPIO | CN1_55 |
DISP0_DAT0 | 117 | LCD_D00, #GPIO | CN1_24 |
DISP0_DAT1 | 118 | LCD_D01, #GPIO | CN1_26 |
DISP0_DAT2 | 119 | LCD_D02, #GPIO | CN1_28 |
DISP0_DAT3 | 120 | LCD_D03, #GPIO | CN1_30 |
DISP0_DAT4 | 121 | LCD_D04, #GPIO | CN1_32 |
DISP0_DAT5 | 122 | LCD_D05, #GPIO | CN1_34 |
DISP0_DAT6 | 123 | LCD_D06, #GPIO | CN1_38 |
DISP0_DAT7 | 124 | LCD_D07, #GPIO | CN1_40 |
DISP0_DAT8 | 125 | LCD_D08, #GPIO | CN1_19 |
DISP0_DAT9 | 126 | LCD_D09, #GPIO | CN1_21 |
DISP0_DAT10 | 127 | LCD_D10, #GPIO | CN1_23 |
DISP0_DAT11 | 133 | LCD_D11, #GPIO | CN1_25 |
DISP0_DAT12 | 134 | LCD_D12, #GPIO | CN1_27 |
DISP0_DAT13 | 135 | LCD_D13, #GPIO | CN1_31 |
DISP0_DAT14 | 136 | LCD_D14, #GPIO | CN1_33 |
DISP0_DAT15 | 137 | LCD_D15, #GPIO | CN1_35 |
DISP0_DAT16 | 138 | LCD_D16, #GPIO | CN1_37 |
DISP0_DAT17 | 139 | LCD_D17, #GPIO | CN1_39 |
DISP0_DAT18 | 140 | LCD_D18, #GPIO | CN1_41 |
DISP0_DAT19 | 141 | LCD_D19, #GPIO | CN1_43 |
DISP0_DAT20 | 142 | LCD_D20, #GPIO | CN1_45 |
DISP0_DAT21 | 143 | LCD_D21, #GPIO | CN1_42 |
DISP0_DAT22 | 144 | LCD_D22, #GPIO | CN1_44 |
DISP0_DAT23 | 145 | LCD_D23, #GPIO | CN1_46 |
EIM_LBA | 59 | #GPIO, BUS_ALE# | CN1_96 |
EIM_OE | 57 | #GPIO [7] | CN1_83 |
EIM_RW | 58 | #GPIO,BUS_DIR | CN1_98 |
EIM_CS0 | 55 | #GPIO, BUS_CS# | CN1_100 |
EIM_CS1 | 56 | Green LED | Onboard |
EIM_A16 | 54 | #GPIO EN_USB_5V [8] | CN1_04 |
EIM_A17 | 53 | #GPIO OFF_BD_RESET# [9] | CN1_09 |
EIM_A18 | 52 | #GPIO | CN1_81 |
EIM_A19 | 51 | #GPIO EN_LCD_3.3V [10] | CN1_48 |
EIM_A20 | 50 | #GPIO | CN1_85 |
EIM_A21 | 49 | #GPIO | CN1_77 |
EIM_A22 | 48 | #GPIO | CN1_89 |
EIM_A23 | 166 | #GPIO | CN1_91 |
EIM_A24 | 132 | #GPIO [7] | CN1_93 |
EIM_D16 | 80 | SPI_1_CLK | CN1_60 |
EIM_D17 | 81 | SPI_1_MISO | CN1_56 |
EIM_D18 | 82 | SPI_1_MOSI | CN1_58 |
EIM_D19 | 83 | SPI_1_CS# [11] | Onboard |
EIM_D21 | 85 | I2C_1_CLK [12] | Onboard |
EIM_D28 | 92 | I2C_1_DAT [12] | Onboard |
EIM_D24 | 88 | UART3_TXD | CN2_82 |
EIM_D25 | 89 | UART3_RXD | CN2_84 |
EIM_EB1 | 61 | BUS_BHE#, #GPIO | CN1_99 |
EIM_BCLK | 191 | #GPIO | CN1_79 |
EIM_WAIT | 128 | BUS_WAIT#, #GPIO [7] | CN1_97 |
EIM_D31 | 95 | #GPIO | CN1_65 |
EIM_DA0 | 64 | MUX_AD_00, #GPIO | CN1_94 |
EIM_DA1 | 65 | MUX_AD_01, #GPIO | CN1_92 |
EIM_DA2 | 66 | MUX_AD_02, #GPIO | CN1_90 |
EIM_DA3 | 67 | MUX_AD_03, #GPIO | CN1_88 |
EIM_DA4 | 68 | MUX_AD_04, #GPIO | CN1_86 |
EIM_DA5 | 69 | MUX_AD_05, #GPIO | CN1_84 |
EIM_DA6 | 70 | MUX_AD_06, #GPIO | CN1_82 |
EIM_DA7 | 71 | MUX_AD_07, #GPIO | CN1_80 |
EIM_DA8 | 72 | MUX_AD_08, #GPIO | CN1_78 |
EIM_DA9 | 73 | MUX_AD_09, #GPIO | CN1_76 |
EIM_DA10 | 74 | MUX_AD_10, #GPIO | CN1_74 |
EIM_DA11 | 75 | MUX_AD_11, #GPIO | CN1_72 |
EIM_DA12 | 76 | MUX_AD_12, #GPIO | CN1_70 |
EIM_DA13 | 77 | MUX_AD_13, #GPIO | CN1_68 |
EIM_DA14 | 78 | MUX_AD_14, #GPIO | CN1_66 |
EIM_DA15 | 79 | MUX_AD_15, #GPIO | CN1_64 |
- ↑ The pad name does not often correspond with the functionality of the IO we use, but can be used to reference the pad in the CPU manual.
- ↑ This does not contain all of the functions possible for a pin, but the common functions as they are used on our off the shelf basebords. Consult the i.MX6 CPU Reference manual for a complete list.
- ↑ This pin is used to tune the LCD backlight through the PWM controller. On our baseboards where there is an LCD present this is connected to provide a sysfs tunable backlight. On other baseboards this is usable as a GPIO.
- ↑ This pin changed during the sampling program for the REV C boards. On rev A this was linux gpio #5, or pad "GPIO_5".
- ↑ This pin changed during the sampling program for the REV C boards. On rev A this was linux gpio #6, or pad "GPIO_6"
- ↑ This pin changed during the sampling program for the REV C boards. On rev A this was linux gpio #9, or pad "GPIO_9"
- ↑ 7.0 7.1 7.2 This GPIO stays LOW when power is applied and defaults to a low state until modified by software
- ↑ On our off the shelf baseboards this pin typically controls the 5V rail for USB peripherals. For custom designs this can optionally be connected to a FET to control USB peripherals power.
- ↑ This pin is dedicated to resetting offboard peripherals during a full reboot.
- ↑ On our off the shelf baseboards this is normally used to toggle power to the LCD if the baseboard uses an LCD.
- ↑ Used for onboard flash
- ↑ 12.0 12.1 Used for communication with RTC and FPGA
FPGA GPIO
The FPGA GPIO can also be accessed through the sysfs API. These are available at GPIOs 224 to 255. Not all of the reserved pins are used on this design, but they will be reserved by the kernel.
FPGA PAD | GPIO Number |
---|---|
CN1_63 | 224 |
CN1_67 | 225 |
CN1_87 | 226 |
CN1_64/MUX_AD_15 [1] | 227 |
CN2_54 [1] | 228 |
CN2_78 | 229 |
CN2_80 | 230 |
CN2_86 | 231 |
CN2_88 | 232 |
CN2_94 | 233 |
CN2_96 | 234 |
CN2_98 | 235 |
CN2_100 | 236 |
CN1_73/PUSH_SW | 255 |
Baseboard ID
All of our off the shelf baseboards contain a hard wired 3-state 8-input multiplexers. This is not required to implement in custom baseboards, with the TS-4900 it is used to pick the device tree. If a baseboard ID is not present, the default device tree would be loaded. During startup in u-boot, 4 DIO are used to obtain the baseboard model id using the bbdetect command. The red LED (CN2_06) is state 0, green LED (CN2_08) is state 1, BUS_DIR (CN1_98) is state 2, and BD_ID_DATA (CN1_83) is used for data.
The first 6 lines are used as the six bits that define the baseboard. The last two lines (Y6 & Y7 in the schematic image below) define the bits to indicate the board revision.
For custom baseboards we have reserved the address 42 which will never be used by our standard products.
ID | Baseboard |
---|---|
0 | TS-8200 |
1 | Reserved, do not use |
2 | TS-TPC-8390 |
4 | TS-8500 |
5 | TS-8400 |
6 | TS-8160 |
7 | TS-8100 |
8 | TS-8820-BOX |
9 | TS-8150 |
10 | TS-TPC-8900 |
11 | TS-8290 |
13 | TS-8700 |
14 | TS-8280 |
15 | TS-8380 |
16 | TS-AN20 |
17 | TS-TPC-8920 |
19 | TS-8550 |
20 | TS-TPC-8950 |
22 | TS-8551 |
42 | Reserved for customer use, never used by us |
63 | TS-8200 |
USB
USB OTG
Depending on which baseboard the TS-4900 is used with, the OTG port may be usable as host, or it may be brought out to a MicroAB port allowing it to be host or device. Several devices are compiled into the default kernel. Additional devices can be compiled into the kernel by following the section here.
USB Serial
modprobe g_serial use_acm=1
This will create a /dev/ttyGS0. See the kernel documentation for more information:
USB Ethernet
modprobe g_ether
This provides a usb0 network interface which simulates an ethernet network connection between the host pc and the i.MX6.
USB Host
The TS-4900 provides a standard USB 2.0 host supporting 480Mb/s. Typically this is interfaced with by using standard Linux drivers, but low level USB communication is possible using libusb.
Many of our off the shelf baseboards provide a GPIO to toggle power to USB devices. This can be used to save power, or to reset USB devices that get stuck in a bad state.
# Power disabled
echo 1 > /sys/class/leds/en-usb-5v/brightness
sleep 2 # let any devices reset
# Enable power
echo 0 > /sys/class/leds/en-usb-5v/brightness
Note: | The USB OTG which can act as a host does not always use the same controllable 5V supply. Refer to the schematic's EN_USB_5V/USB_5V for more information on this control. |
PCIe
The i.MX6 includes one PCIe 2.0 bus which is brought out to the baseboard on CN2. See the CPU reference manual for more information on the bus, or see the Linux Kernel menuconfig for more information on supported PCIe devices.
TWI
The i.MX6 supports standard I2C at 100khz, or using fast mode for 400khz operation. The CPU has 2 I2C buses used on the TS-4900.
I2C 1 is internal to the TS-4900 and connects to the RTC and FPGA.
Address | Device |
---|---|
0x28-0x2f | #FPGA |
0x57 | #NVRAM |
0x6f | #RTC |
The second I2C bus is brought out on CN2_28 (SCL) and CN2_30 (SDA). This bus has no devices except those added by the baseboard.
Note: | It is also possible to request the kernel to bitbang additional I2C buses as needed. See an example here. |
The kernel makes the I2C available at /dev/i2c-#. You can use the i2c-tools (i2cdetect, i2cget, i2cset), or you can write your own client.
I2S Audio
The TS-4900 supports an I2S output, but to be usable for most audio applications it must be connected to an audio codec. Our off the shelf baseboards use the Freescale SGTL5000 codec. This provides a standard alsa driver which most Linux applications will support.
For integrating audio into your application, gstreamer is in our default image and provides bindings for most common programming languages.
The Yocto image includes several utilities which can be used to test gstreamer.
SPI
The CPU has 2 SPI controllers which are accessible through either specific kernel drivers, or userspace using the /dev/spi interface. To utilize SPI, most projects will end up with a customized device tree, so setting up the kernel build environment will be necessary. See the kernel compile guide here for more details.
Open the device tree source file such as arch/arm/boot/dts/imx6qdl-ts4900-reve.dtsi or arch/arm/boot/dts/imx6qdl-ts4900.dtsi, or find the device tree that matches your baseboard. The kernel requires a spidev device be added to the relevant ECSPI controller. For example:
&ecspi2 {
fsl,spi-num-chipselects = <2>;
cs-gpios = <&gpio6 2 0>, <&gpio5 29 0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi2>;
status = "okay";
serial1: max3100-1@0 {
compatible = "max3100-ts";
reg = <0>;
interrupt-parent = <&gpio1>;
interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
spi-max-frequency = <10000000>;
loopback = <0>;
crystal = <1>;
poll-time = <100>;
};
spidev: spi@1 {
compatible = "spidev";
reg = <1>;
spi-max-frequency = <18181818>;
};
};
In this case ECSPI2 is configured with a spidev at 18.181818MHz which will be available at /dev/spidev1.1 (<bus counting from 0>.<chipselect>). This example adds the spidev device for the offboard chip select. The above example uses GPIO 5 29 which is SPI_2_CS#/CN2_65. The line "reg = <1>;" must be declared to select which chip select in the "cs-gpios" array will be asserted when communicating to your device. After this is configured rebuild the kernel and install your new device tree.
On this board ECSPI1 is used for the boot flash. If this bus is expanded care must be taken to limit trace lengths, and make sure the chip selects are not asserted out of boot. If another device attempts to drive MISO on startup, or the trace lengths are long enough to cause signal integrity issues these will prevent boot.
The SPI max speed is varied between CPU, pins, and if the SPI transaction is read/write:
Bus | CPU | Read | Write |
---|---|---|---|
ECSPI1 | IMX6Q | 40 ns (25.00 MHz) | 15 ns (66.66 MHz) |
IMX6DL | 43 ns (23.25 MHz) | 15 ns (66.66 MHz) | |
ECSPI2 | IMX6Q | 55 ns (18.18 MHz) | 15 ns (66.66 MHz) |
IMX6DL | 43 ns (23.25 MHz) | 15 ns (66.66 MHz) |
See the i.MX6 datasheet for further details on SPI timing such as setup, hold, and propagation delays.
Once you have a /dev/spidev device, you can open this file and use the standard Linux SPI API. For more information see the documentation and sample code:
Video Acceleration
FPGA
The Lattice ICE40 FPGA provides auto TX enable for RS-485 half duplex, a few more DIO, the UART MUX, and it can generate clocks for use on a baseboard. Most of these registers are controlled using tshwctl in the ts4900-utils repository. The DIO can be accessed using the sysfs GPIOs 224 to 255 using the "ts4900gpio" driver. See the #GPIO section for more information on the recommended GPIO access. The below examples will communicate directly over i2c.
Usage: tshwctl [OPTIONS] ... Technologic Systems i.mx6 FPGA Utility -m, --addr <address> Sets up the address for a peek/poke -v, --poke <value> Writes the value to the specified address -t, --peek Reads from the specified address -i, --mode <8n1> Used with -a, sets mode like '8n1', '7e2', etc -x, --baud <speed> Used with -a, sets baud rate for auto485 -a, --autotxen <uart> Enables autotxen for supported CPU UARTs Uses baud/mode if set or reads the current configuration of that uart -c, --dump Prints out the crossbar configuration -g, --get Print crossbar for use in eval -s, --set Read environment for crossbar changes -q, --showall Print all possible FPGA inputs and outputs. -h, --help This message
On every poweron the FPGA is programmed using the file in /boot/ts4900-fpga.bin. U-boot copies this into memory, and runs the "ice40" command to reprogram the FPGA. Without this file the FPGA will not do anything. This FPGA interfaces to the i.MX6 using the first CPU I2C bus. You can use the "tshwctl --addr <addr>" with the "--peek" or "--poke <val>" to access these registers.
Addr | Bits | Function |
---|---|---|
00 | 7:3 | CN1_63 Crossbar |
2 | CN1_63 Input Data | |
1 | CN1_63 Output Data | |
0 | CN1_63 Output Enable | |
01 | 7:3 | CN1_67 Crossbar |
2 | CN1_67 Input Data | |
1 | CN1_67 Output Data | |
0 | CN1_67 Output Enable | |
02 | 7:3 | CN1_87 Crossbar |
2 | CN1_87 Input Data | |
1 | CN1_87 Output Data | |
0 | CN1_87 Output Enable | |
03 | 7:3 | ttymxc3 rxd Crossbar |
2 | ttymxc3 rxd Input Data | |
1 | ttymxc3 rxd Output Data | |
0 | ttymxc3 rxd Output Enable | |
04 | 7:3 | ttymxc1 CTS Crossbar |
2 | ttymxc1 CTS Input Data | |
1 | ttymxc1 CTS Output Data | |
0 | ttymxc1 CTS Output Enable | |
05 | 7:3 | CN2_78 Crossbar |
2 | CN2_78 Input Data | |
1 | CN2_78 Output Data | |
0 | CN2_78 Output Enable | |
06 | 7:3 | CN2_80 Crossbar |
2 | CN2_80 Input Data | |
1 | CN2_80 Output Data | |
0 | CN2_80 Output Enable | |
07 | 7:3 | CN2_86 Crossbar |
2 | CN2_86 Input Data | |
1 | CN2_86 Output Data | |
0 | CN2_86 Output Enable | |
08 | 7:3 | CN2_88 Crossbar |
2 | CN2_88 Input Data | |
1 | CN2_88 Output Data | |
0 | CN2_88 Output Enable | |
09 | 7:3 | CN2_94 Crossbar |
2 | CN2_94 Input Data | |
1 | CN2_94 Output Data | |
0 | CN2_94 Output Enable | |
10 | 7:3 | CN2_96 Crossbar |
2 | CN2_96 Input Data | |
1 | CN2_96 Output Data | |
0 | CN2_96 Output Enable | |
11 | 7:3 | CN2_98 Crossbar |
2 | CN2_98 Input Data | |
1 | CN2_98 Output Data | |
0 | CN2_98 Output Enable | |
12 | 7:3 | CN2_100 Crossbar |
2 | CN2_100 Input Data | |
1 | CN2_100 Output Data | |
0 | CN2_100 Output Enable | |
13 | 7:2 | Reserved |
1 | BT_EN Output Enable | |
0 | Reserved | |
14 | 7:2 | Reserved |
1 | WL_EN Output Enable | |
0 | Reserved | |
15 | 7:3 | Reserved |
2 | BT_RTS Input value | |
1:0 | Reserved | |
16 | 7:3 | BT_CTS Crossbar |
2 | BT_CTS Input value | |
1 | BT_CTS Output value | |
0 | BT_CTS Output Enable | |
17 | 7:3 | BT_RXD Crossbar |
2:0 | Reserved | |
18 | 7:3 | ttymxc1 RXD Crossbar |
2:0 | Reserved | |
29 | 7:2 | Reserved |
1 | Push sw reboot enable [1] | |
0 | Reserved | |
30 | 7:2 | Reserved |
1 | Reset (on 1) | |
0 | Reserved | |
31 | 7:3 | Reserved |
2 | Push SW Input value | |
1:0 | Reserved | |
32 | 7:0 | RS485_CNT0 bits 23:16 |
33 | 7:0 | RS485_CNT0 bits 15:8 |
34 | 7:0 | RS485_CNT0 bits 7:0 |
35 | 7:0 | RS485_CNT1 bits 23:16 |
36 | 7:0 | RS485_CNT1 bits 15:8 |
37 | 7:0 | RS485_CNT1 bits 7:0 |
38 | 7:0 | RS485_CNT2 bits 23:16 |
39 | 7:0 | RS485_CNT2 bits 15:8 |
40 | 7:0 | RS485_CNT2 bits 7:0 |
41 | 7:0 | RS485_CNT3 bits 23:16 |
42 | 7:0 | RS485_CNT3 bits 15:8 |
43 | 7:0 | RS485_CNT3 bits 7:0 |
44 | 7:3 | SPIUART0 RX Crossbar |
2:0 | Reserved | |
45 | 7:3 | SPIUART1 RX Crossbar |
2:0 | Reserved | |
46 | 7:3 | SPIUART2 RX Crossbar |
2:0 | Reserved | |
51 | 7:4 | FPGA Revision |
3 | B1 Strapping input value | |
2 | G1 Strapping input value | |
1 | L14 Strapping input value | |
0 | N14 Strapping input value | |
53 | 7:3 | SPIUART0 CTS Crossbar |
2:0 | Reserved | |
54 | 7:3 | SPIUART1 CTS Crossbar |
2:0 | Reserved | |
55 | 7:3 | SPIUART2 CTS Crossbar |
2:0 | Reserved |
- ↑ Set 1 to enable hardware reset on PUSH_SW low
The FPGA crossbar allows almost any of the FPGA pins to be rerouted on the carrier board. All of the above registers that have a crossbar mux value can be written with these values to change the output value. When using the crossbar pins that are outputs, bit 1 should also be set to allow output enables.
Crossbar Value | Selected Function |
---|---|
0 | Do not change |
1 | BT_RTS |
2 | BT_TXD |
3 | CN1_63 |
4 | CN1_67 |
5 | CN2_100 |
6 | ttymxc1 RTS# |
7 | CN2_78 |
8 | CN2_80 |
9 | CN2_86 |
10 | CN2_88 |
11 | CN2_94 |
12 | CN2_96 |
13 | CN2_98 |
14 | ttymxc3 TXD |
15 | ttymxc1 TXD |
16 | SPIUART0_TX |
17 | SPIUART0_TXEN |
18 | SPIUART0_RTS |
19 | SPIUART1_TX |
20 | SPIUART1_TXEN |
21 | SPIUART1_RTS |
22 | SPIUART2_TX |
23 | SPIUART2_TXEN |
24 | SPIUART2_RTS |
25 | ttymxc1 TXEN |
26 | ttymxc3 TXEN |
27 | 12MHz clock |
28 | 14MHz clock |
29 | 24MHz clock |
30 | 28.88MHz clock |
31 | GPIO |
On startup these are the default values:
Pad | Default Mapping | FGPA Addr | Crossbar Reset Value |
---|---|---|---|
CN1_63 | SPIUART1_TXEN | 0 | 0xa1 |
CN1_67 | SPIUART0_TXEN | 1 | 0x89 |
CN1_87 | GPIO 226 | 2 | 0xf8 |
ttymxc3 RXD | CN2_88 | 3 | 0x80 |
ttymxc1 CTS | BT_RTS | 4 | 0x8 |
CN2_78 | SPIUART0_TXD | 5 | 0x81 |
CN2_80 | GPIO [1] | 6 | 0xf8 |
CN2_86 | ttymxc3 txd | 7 | 0x71 |
CN2_88 | GPIO [2] | 8 | 0xf8 |
CN2_94 | SPIUART1_TXD | 9 | 0x99 |
CN2_96 | GPIO | 10 | 0xf8 |
CN2_98 | SPIUART2_TXD | 11 | 0xb1 |
CN2_100 | GPIO [3] | 12 | 0xf8 |
BT_CTS | ttymxc1 RTS | 16 | 0x31 |
BT_RXD | ttymxc1 TXD | 17 | 0x78 |
ttymxc1 RXD | BT_TXD | 18 | 0x10 |
SPIUART0 RX | CN2_80 | 44 | 0x40 |
SPIUART1 RX | CN2_96 | 45 | 0x60 |
SPIUART2 RX | CN2_100 | 46 | 0x28 |
SPIUART0 CTS | GPIO [4] | 53 | 0xf8 |
SPIUART1 CTS | GPIO [5] | 54 | 0xf8 |
SPIUART2 CTS | GPIO [6] | 55 | 0xf8 |
Watchdog
The kernel provides an interface to the watchdog driver at /dev/watchdog. Refer to the kernel documentation for more information:
MUXBUS
CAN
The i.MX6 includes 2 CAN controllers which support the SocketCAN interface. Before proceeding with the examples, see the Kernel's CAN documentation here.
This board comes preinstalled with can-utils. These can be used to communicate over a CAN network without writing any code. The candump utility can be used to dump all data on the network
## First, set the baud rate and bring up the device:
ip link set can0 type can bitrate 250000
ip link set can0 up
## Dump data & errors:
candump can0 &
## Send the packet with:
#can_id = 0x7df
#data 0 = 0x3
#data 1 = 0x1
#data 2 = 0x0c
cansend can0 -i 0x7Df 0x3 0x1 0x0c
## Some versions of cansend use a different syntax. If the above
## commands gives an error, try this instead:
#cansend can0 7DF#03010C
The above example packet is designed to work with the Ozen Elektronik myOByDic 1610 ECU simulator to read the RPM speed. In this case, the ECU simulator would return data from candump with:
<0x7e8> [8] 04 41 0c 60 40 00 00 00 <0x7e9> [8] 04 41 0c 60 40 00 00 00
In the output above, columns 6 and 7 are the current RPM value. This shows a simple way to prove out the communication before moving to another language.
The following example sends the same packet and parses the same response in C:
#include <stdio.h>
#include <pthread.h>
#include <net/if.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int main(void)
{
int s;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
struct iovec iov;
struct msghdr msg;
char ctrlmsg[CMSG_SPACE(sizeof(struct timeval)) + CMSG_SPACE(sizeof(__u32))];
char *ifname = "can0";
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("socket");
return -2;
}
/* For the ozen myOByDic 1610 this requests the RPM guage */
frame.can_id = 0x7df;
frame.can_dlc = 3;
frame.data[0] = 3;
frame.data[1] = 1;
frame.data[2] = 0x0c;
nbytes = write(s, &frame, sizeof(struct can_frame));
if(nbytes < 0) {
perror("write");
return -3;
}
iov.iov_base = &frame;
msg.msg_name = &addr;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = &ctrlmsg;
iov.iov_len = sizeof(frame);
msg.msg_namelen = sizeof(struct sockaddr_can);
msg.msg_controllen = sizeof(ctrlmsg);
msg.msg_flags = 0;
do {
nbytes = recvmsg(s, &msg, 0);
if (nbytes < 0) {
perror("read");
return -4;
}
if (nbytes < (int)sizeof(struct can_frame)) {
fprintf(stderr, "read: incomplete CAN frame\n");
}
} while(nbytes == 0);
if(frame.data[0] == 0x4)
printf("RPM at %d of 255\n", frame.data[3]);
return 0;
}
See the Kernel's CAN documentation here. Other languages have bindings to access CAN such as Python, Java using JNI.
In production use of CAN we also recommend setting a restart-ms for each active CAN port.
ip link set can0 type can restart-ms 100
This allows the CAN bus to automatically recover in the event of a bus-off condition.
External Interfaces
TS-Socket
The TS-SOCKET System-on-Modules (SoMs) all use two high density 100 pin connectors for power and all I/O. These follow a common pinout for various external interfaces so new modules can be dropped in to lower power consumption or use a more powerful processor. The male connector is on the baseboard, and the female connector is on the SoM. You can find the datasheet for the baseboard's male connector here. This can be ordered from the TS-Socket SoM product page as CN-TSSOCKET-M-10 for a 10 pack, or CN-TSSOCKET-M-100 for 100 pieces, or from the vendor of your choice, the part is an FCI "61083-102402LF".
We have an Eaglecad library available for developing a custom baseboard here. We also provide the entire PCB design for the TS-8200 baseboard here which you can modify for your own design.
In our schematics and our table layout below, we refer to pin 1 from the male connector on the baseboard.
- ↑ EXT_RESET# is an open-drain input used to reboot the CPU.
- ↑ This is an output which can be manipulated in the #Syscon. This pin can optionally be connected to control a FET to a separate 5V rail for USB to allow software to reset USB devices.
- ↑ 3.0 3.1 3.2 3.3 3.4 3.5 This SD interface is the same one used by the MicroSD on the TS-4900. Only one can be used at a time.
- ↑ OFF_BD_RESET# is an output from the System-on-Module (SoM) that automatically sends a reset signal when the unit powers up or reboots. It can be connected to any IC on the base board that requires a reset.
- ↑ 5.0 5.1 5.2 5.3 The 5V power pins should each be connected to a 5V source.
- ↑ This is used during production to boot to an offboard SPI flash. This pin should typically be left unconnected.
- ↑ 7.0 7.1 The TS-4900 regulates a 3.3V rail which can source up to 700mA. Designs should target a 300mA max if they intend to use other SoMs.
- ↑ This pin is used as a test point to verify the RAM has a correct voltage for debugging
- ↑ This pin is used as a test point for debugging
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.