TS-7840

From Technologic Systems Manuals
WARNING: This is PRELIMINARY INFORMATION ONLY. It is certain to change while undergoing editing.
TS-7840
ts-7840.gif
Product Page
Product Images
Specifications
Documentation
Schematic
Mechanical Drawing
FTP Path
Processor
Marvell MV88F6820
Armada 385 ARM Cortex-A9 1.3-1.8 GHz Dual Core CPU

1 Overview

The TS-7840 is a Single Board Computer (SBC) based on a Marvell MV88F6820 1.3GHz Cortex-A9 Dual Core CPU. This board provides 3 independent gigabit Ethernet controllers, including one gigabit port that goes to an onboard switch providing 5 additional PoE capable RJ45 Ethernets that can be use for filtering or switching.

2 Getting Started

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

  • Linux filesystems on the microSD card can be accessed on the PC.
  • More ARM cross-compilers are available.
  • If recovery is needed, a bootable medium can be written.
  • A network filesystem can be served.

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

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

2.1 Connect USB Console

The board includes a USB Type B header connected to the onboard preprogrammed microcontroller. This acts as a USB serial device using the CP210x Virtual COM port. Most operating systems have built-in support for this device, however drivers are available here.


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.

picocom -b 115200 /dev/ttyUSB0


'screen' is a terminal multiplexer which happens to have serial support.

screen /dev/ttyUSB0 115200


Or a very commonly used client is 'minicom' which is quite powerful but requires some setup:

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


Console from Windows

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

Device Manager Putty Configuration

2.2 Powering up

The TS-7840 receives power through the 4 pin terminal block (CN4). If a power supply is ordered with the TS-7840 it will include the correct terminal block connected to the power supply. Otherwise the terminal block will ship with the unit.

Pin Description
1 10-48VDC
2 GND
3 POE 48VDC
4 POE GND

Once power is applied the device will output information via the built in USB console.

The first output is from U-Boot:

U-Boot SPL 2017.09-g2bce19ae53 (Aug 26 2019 - 17:13:17)
Detected Device ID 6820 (SAR1 0xCB00230F)
mv_ddr: mv_ddr-armada-17.10.3 
DDR3 Training Sequence - Switching XBAR Window to FastPath Window
DDR Training Sequence - Start scrubbing
DDR3 Training Sequence - End scrubbing
mv_ddr: completed successfully
Trying to boot from MMC1
force part -> 1


U-Boot 2017.09-g2bce19ae53 (Aug 26 2019 - 17:13:17 -0700)

SoC:   MV88F6820-A0 at 1332 MHz
I2C:   ready
DRAM:  2 GiB (666 MHz, ECC enabled)
MMC:   mv_sdh: 0
Model: Technologic Systems TS-7840
FPGA Base 0xE8000000
SCSI:  MVEBU SATA INIT
SATA link 0 timeout.
AHCI 0001.0000 32 slots 2 ports 6 Gbps 0x3 impl SATA mode
flags: 64bit ncq led only pmp fbss pio slum part sxs 
Net:   eth2: ethernet@30000, eth3: ethernet@34000, eth1: ethernet@70000
Press ESC twice to abort autoboot in 3 second(s)
Note: The "*** Warning - bad CRC, using default environment" can be safely ignored. This indicates that u-boot scripts are not being customized. Typing "env save" will hide these messages, but this is not needed.

This u-boot and its environment is loaded from the emmc boot partition 0 (/dev/mmcblk0boot0). This a hardware partition that is independent of the main flash on the emmc (/dev/mmcblk0). From here, u-boot will follow u-boots standard Distro boot command. This will check for boot files on the first USB mass storage, then the m.2 SATA, and will by default find a bootable image on eMMC. From here the board will boot to our default #Debian image.

2.3 First Linux Boot

When booting with the default settings, a shipped board will boot to the eMMC. The eMMC by default are pre-programmed with our default Debian 10 Buster image. After Linux boots it will ask the user to log in with a username and password. This uses "root" as the username with no password. This can be changed after logging in with the command "passwd" to set an account password.

From the Linux prompt you can now begin testing out hardware, or beginning your application development.

3 U-Boot

U-boot is a bootloader and comes preinstalled on this board. This is loaded in the eMMC hardware boot partitions in /dev/mmcblk0boot0. U-boot sets up the hardware, initializes ECC by scrubbing RAM, and then loads the OS from the available storage devices. Most users will not need to customize u-boot further, and can proceed to the #Debian sections for information on application development.

3.1 U-boot Distro Boot

U-boot by default uses u-boots distro bootcmd to determine how to boot. As shipped the board will boot to the preprogrammed eMMC with our #Debian image.

By default this will look at:

Order U-boot device name Description
1 usb0 First detected USB mass storage device
2 scsi0 M.2 SATA port
3 mmc0 Onboard eMMC storage
4 dhcp DHCP Option [1]
5 pxe PXE File [2]
  1. DHCP can advertise a TFTP server (next-path, root-path, and filename) to point to a u-boot script.
  2. DHCP can advertise a TFTP server (next-path, root-path, and filename) with a PXE file to control boot.

The default boot order can be left for most users, but boot can be optimized for one boot device by stopping at u-boot and running:

# Boot straight to mmc:
env set boot_targets 'mmc0';
env save

# Boot to usb, then mmc only
env set boot_targets 'usb0 mmc0';
env save

# Set back to default boot order
env set boot_targets 'usb0 scsi0 mmc0 dhcp pxe'
env save

U-boot will search the boot media on either the 1st partition, or if the disk is partitioned with GPT instead of MBR it will search the "bootable" partition. It will then search for these files:

Order Search for Paths Description
1 extlinux /extlinux/extlinux.conf, /boot/extlinux/extlinux.conf Menu conf file of kernels
2 U-boot script /boot.scr.uimg, /boot.scr, /boot/boot.scr.uimg, /boot/boot.scr u-boot script with instructions to load the OS
3 EFI Binary efi/boot/bootarm.efi EFI binary (such as grub)

Our Debian images use a u-boot script in /boot/boot.scr.uimg.

3.2 U-Boot Environment

The U-Boot environment on the TS-7840 is stored in the on-board eMMC flash in the /dev/mmcblk0boot0 partition.

# 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 env changes to the spi flash
# Otherwise changes are lost
env save

# Restore env to default
env default -a

# Remove a variable
env delete emmcboot

3.3 U-Boot Commands

# The most important command is 
help
# This can also be used to see more information on a specific command
help i2c

# Boots into the compressed binary at $loadaddr.  
bootz
# Boots into the compressed binary at $loadaddr, specifies the fdtaddr 
# so Linux knows where to find the board 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 is used to copy a file from most devices
# Load kernel from SD
load mmc 1:2 ${loadaddr} /boot/zImage
# Load Kernel from eMMC
load mmc 0:2 ${loadaddr} /boot/zImage

# You can view the fdt from u-boot with fdt
load mmc 0:2 $fdtaddr /boot/armada-38x.dtb
fdt addr ${fdtaddr}
fdt print

# You can blindly jump into any memory
# This is similar to bootm, but it does not use the 
# u-boot header
load mmc 0:2 ${loadaddr} /boot/custombinary
go ${loadaddr}

# Browse fat,ext2,ext3,or ext4 filesystems:
ls mmc 0:1 /

# Access memory like devmem in Linux, you can read/write arbitrary memory
# using mw and md
# write
mw 0x10000000 0xc0ffee00 1
# read
md 0x10000000 1

# Test memory.
mtest

# 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

# Delay in seconds
sleep 10

# You can load HUSH scripts that have been created with mkimage
load mmc 0:1 ${loadaddr} /boot/ubootscript.uimg
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/zImage;
	then echo Loaded Kernel
else
	echo Could not find kernel
fi

# Commands can be timed with "time"
time bdinfo

# Print U-boot version/build information
version

3.4 U-Boot Bootcount

TS-7840 U-boot bootcount

3.5 U-Boot Development

TS-7840 U-boot development

4 Backup / Restore

TODO

5 Debian 10

Debian is a community run Linux distribution. Debian provides tens of thousands of precompiled applications and services. This distribution is known for stability and large community providing support and documentation. The installation is specific to our board, but most Debian documentation applies:

5.1 Debian 10 - Getting Started

Once installed, the default user is "root" with no password.

Note: This is a shared image that supports the TS-7820, TS-7825 and TS-7840

This image can be written to a USB drive, or to the eMMC. For development, a USB thumbdrive will be simplest. If a bootable USB drive is connected this will take priority over other boot media. Plug in a USB drive and check the last output from "dmesg" to get the USB disk. For example, this may be /dev/sdc.

# Erase all older partitions
sudo sgdisk --zap-all /dev/sdc
# Create one GPT Linux partition
sudo sgdisk -n 0:0:0 -t 0:8300 /dev/sdc
# Create a filesystem and mount
sudo mkfs.ext4 /dev/sdc1
sudo mkdir /mnt/usb/
sudo mount /dev/sdc1 /mnt/usb/
# Extract downloaded image:
sudo tar --numeric-owner -xf ts7840-debian-buster-latest.tar.xz -C /mnt/usb/
sudo chmod 755 /mnt/usb/
sudo umount /mnt/usb/

These commands will also work while booted from a USB drive to rewrite the eMMC. Instead of /dev/sdc you would use /dev/mmcblk0, and instead of /dev/sdc1 you would use /dev/mmcblk0p1.

5.2 Debian 10 - Configuring Network

The network in Debian is configured /etc/network/interfaces.d/. For complete documentation, see Debian's documentation here

Some common examples are shown below.

DHCP on eth0:

tee /etc/network/interfaces.d/eth0 <<'EOF' >/dev/null
auto eth0
allow-hotplug eth0
iface eth0 inet dhcp
EOF

Static IP on eth0:

tee /etc/network/interfaces.d/eth0 <<'EOF' >/dev/null
auto eth0
iface eth0 inet static
    address 192.0.2.7/24
    gateway 192.0.2.254
EOF

5.3 Debian 10 - Installing New Software

Debian provides the apt-get system which allows management of pre-built applications. The apt tools require a network connection to the internet in order to automatically download and install new software. The update command will download a list of the current versions of pre-built packages.

apt-get update

A common example is installing Java runtime support for a system. Find the package name first with search, and then install it.

root@tsa38x:~# apt-cache search openjdk
default-jdk - Standard Java or Java compatible Development Kit
default-jdk-doc - Standard Java or Java compatible Development Kit (documentation)
default-jdk-headless - Standard Java or Java compatible Development Kit (headless)
default-jre - Standard Java or Java compatible Runtime
default-jre-headless - Standard Java or Java compatible Runtime (headless)
jtreg - Regression Test Harness for the OpenJDK platform
libreoffice - office productivity suite (metapackage)
openjdk-11-dbg - Java runtime based on OpenJDK (debugging symbols)
openjdk-11-demo - Java runtime based on OpenJDK (demos and examples)
openjdk-11-doc - OpenJDK Development Kit (JDK) documentation
openjdk-11-jdk - OpenJDK Development Kit (JDK)
openjdk-11-jdk-headless - OpenJDK Development Kit (JDK) (headless)
openjdk-11-jre - OpenJDK Java runtime, using Hotspot JIT
openjdk-11-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless)
openjdk-11-jre-zero - Alternative JVM for OpenJDK, using Zero
openjdk-11-source - OpenJDK Development Kit (JDK) source files
uwsgi-app-integration-plugins - plugins for integration of uWSGI and application
uwsgi-plugin-jvm-openjdk-11 - Java plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-jwsgi-openjdk-11 - JWSGI plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-ring-openjdk-11 - Closure/Ring plugin for uWSGI (OpenJDK 11)
uwsgi-plugin-servlet-openjdk-11 - JWSGI plugin for uWSGI (OpenJDK 11)
java-package - Utility for creating Java Debian packages

In this case, the wanted package will likely be the "openjdk-11-jre" package. Names of packages can be found on Debian's wiki pages or the packages site.

With the package name apt-get install can be used to install the prebuilt packages.

apt-get install openjdk-11-jre
# More than one package can be installed at a time.
apt-get install openjdk-11-jre nano vim mplayer

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

5.4 Debian 10 - Setting Up SSH

Openssh is installed in our default Debian image, but by default openssh does not permit root logins, and requires a password to be set. To allow remote root login:

sed --in-place 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
systemctl restart ssh.service
passwd root # Set any password

If you ssh to this system it will now support ssh as root.

5.5 Debian 10 - Starting Automatically

A systemd service can be created to start up headless applications. Create a file in /etc/systemd/system/yourapp.service

[Unit]
Description=Run an application on startup

[Service]
Type=simple
ExecStart=/usr/local/bin/your_app_or_script

[Install]
WantedBy=multi-user.target

If networking is a dependency add "After=network.target" in the Unit section. Once you have this file in place add it to startup with:

# Start the app on startup, but will not start it now
systemctl enable yourapp.service

# Start the app now, but doesn't change auto startup
systemctl start yourapp.service
Note: See the systemd documentation for in depth documentation on services.

5.6 Debian 10 - Cross Compiling

Debian only provides their cross compiler for their distribution. Our examples will set up a chroot for Debian to use for development. If using Debian 10 Buster directly, or through a VM, the schroot commands and debootstrap can be skipped.

First install the host system dependencies to use schroot and debootstrap:

# Ubuntu/Debian
sudo apt-get install debootstrap schroot
# Fedora
sudo dnf install debootstrap schroot
# Centos/redhat
sudo yum install debootstrap schroot

Use debootstrap to install a base Debian 10 for your host.

# Generate Debian Buster rootfs
sudo debootstrap buster /opt/chroots/buster-armdev/ http://deb.debian.org/debian

Then configure schroot to enter this rootfs. Replace "youruser" with your linux username.

sudo tee /etc/schroot/chroot.d/buster-armdev <<'EOF' >/dev/null
[buster-armdev]
description=Debian Buster for ARM development
directory=/opt/chroots/buster-armdev/
root-users=youruser
users=youruser
type=directory
EOF

Log into this schroot and install the armhf development tools (Skip if running a native Debian Buster host):

schroot -c buster-armdev

This will change your PS1 variable to indicate that you are in the Debian root. For example:

mark@mark-desktop:~$ sudo schroot -c buster-armdev
(buster-armdev)root@mark-desktop:/home/mark#

Install Debian's development tools for armhf:

# This workaround is required for Debian Buster
rm /var/lib/dpkg/statoverride

dpkg --add-architecture armhf
apt-get update
apt-get install -y build-essential gcc-arm-linux-gnueabihf bc \
  lzop u-boot-tools libncursesw5-dev file wget 
exit

At this point the Debian chroot is ready to compile armhf binaries. For example, create a hello world in your home folder at ~/Documents/hello.c

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

To compile this, you can enter the schroot as a normal user:

schroot -c buster-armdev

Keep in mind that when this is run as a normal user it does not modify your prompt. This will look like any other prompt, but will use your Debian applications instead. You can verify this is Debian with:

mark@mark-desktop:~/Documents$ cat /etc/issue
Debian GNU/Linux 10 \n \l

While logged into this schroot, run:

arm-linux-gnueabihf-gcc hello.c -o hello
exit

From here you can check "file hello" to verify the binary type:

mark@mark-desktop:~/Documents$ file hello
hello: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=8a8cee3341d3ef76ef6796f72d5722ae9d77c8ea, not stripped

This can also be used to develop against dynamic libraries from Debian. The armhf packages can be installed in the chroot. For example, to link against curl:

# Run as root to install dependencies
sudo schroot -c buster-armdev
apt-get install libcurl4-openssl-dev:armhf
exit
# Return to arm chroot as a normal user:
schroot -c buster-armdev
# Download curl's simple.c example
wget https://raw.githubusercontent.com/bagder/curl/master/docs/examples/simple.c
arm-linux-gnueabihf-gcc simple.c -o simple -lcurl

The "simple" binary is now built for armhf and links dynamically to curl.

6 Compile the 4.14.x Kernel

For 4.14 we recommend using Debian Busters toolchain to rebuild the kernel. Set up a chroot to cross compile for the kernel.

This process will generate a tar that can be extracted over an image to update the kernel.

git clone https://github.com/embeddedarm/linux-a38x.git -b linux-4.14.y linux-4.14
cd linux-4.14
# Enter the chroot
schroot -c buster-armdev

make tsa38x_defconfig

# Make any changes at this point to the config, or drivers.  

# This will compile and copy everything to a tar to install to the target.
export TEMPDIR=$(mktemp -d) && \
make all -j4 && \
mkdir "$TEMPDIR/boot/" && \
cp arch/arm/boot/zImage  "$TEMPDIR"/boot/zImage && \
cp arch/arm/boot/dts/armada-385-ts*.dtb "$TEMPDIR"/boot/ && \
INSTALL_MOD_PATH="$TEMPDIR" make modules_install && \
tar czf linux-tsa38x.tar.gz -C $TEMPDIR . && 
rm -rf $TEMPDIR

This will generate linux-tsa38x.tar.gz. Copy this to the target unit and run:

tar -xf linux-tsa38x.tar.gz -C /

This will extract the kernel/modules/firmware over the existing image. On the next boot, the system will use the new kernel.

7 Features

7.1 Battery Backed RTC

This board includes an onboard battery backed ST M41T00S using an external and replaceable coin cell battery. The RTC is connected to the CPU via I2C and is handled by the kernel, and is presented as a standard RTC device in linux (/dev/rtc0).

7.2 CAN

The FPGA includes a CAN controller that is compatible with the NXP SJA1000 register set. This driver is accessed using socketcan:

The can-utils package in Debian provides utilities that can be used for testing:

## 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 = 0x03
#data 1 = 0x01
#data 2 = 0x0c
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 using C-types, Java using JNI.

7.3 CPU

This board features the Marvell Armada 385 88F6820 CPU. This is a dual core Arm Cortex-A9 that runs at 1.33GHz.

7.4 DDR3 RAM

This board includes 5 onboard ram chips. Of these, 4 provide the 2GB of usable RAM for the OS, and the additional chip provides storage for ECC. ECC is always enabled on this system.

The CPU is capable of autocorrecting single bit failures, and detecting double bit failures. The mvebu_edac driver will report any failures to the kernel log. In the case of a single bit failure:

 EDAC MC0: 1 CE MVEBU on mc#0csrow#0channel#0 (csrow:0 channel:0 page:0xc8e offset:0xc8e000 grain:8 syndrome:0x5b99e5 - Single bit ECC Failure)

A double bit failure will print out this message, and also attempt a system reboot.

 EDAC MC0: 1 UE MVEBU on mc#0csrow#0channel#0 (csrow:0 channel:0 page:0x8e offset:0x8e000 grain:8 - Double bit ECC Failure)

To have the system not reboot in case of a double bit failure and just report change the kernel cmdline to include "mvebu_edac.edac_reboot_on_fail=0".

7.5 eMMC Controller

This board includes a Micron eMMC module. Our off the shelf builds are 4GiB, but up to 64GiB are available for larger builds. The eMMC flash appears to Linux as an SD card at /dev/mmcblk0. Our default programming will include one partition programmed with our Debian image.

The CPU boots out of the emmc's hardware boot partitions /dev/mmcblk0boot0 and /dev/mmcblk0boot1. These are both 16MB, and are separate from the mmcblk0 flash. Erasing or manipulating /dev/mmcblk0 and its partitions will not affect these hardware partitions. The board boots to /dev/mmcblk0boot0 by default, but boot1 can be selected if it has been written with a valid bootloader. This allows atomic updates in the field of u-boot, but should only be done with care as it can leave your board not booting if a bad image is written before switching the active boot partition.

WARNING: This may need a development board or RMA to recover the board if the CPU fails to boot. Make certain a valid u-boot is present on a boot device before switching to it.

Write a u-boot to mmcblk0boot1 with:

echo 0 > /sys/block/mmcblk0boot1/force_ro
dd if=/path/to/u-boot.kwb bs=1M of=/dev/mmcblk0boot1

Once the data has been verified as written, the active boot partition can be switched to mmcblk0boot1:

# The argument after enable should be 2 for mmcblk0boot1, or 1 for mmcblk0boot0
mmc bootpart enable 2 1 /dev/mmcblk0

The active partition can be read as part of the extcsd read:

mmc extcsd read /dev/mmcblk0

7.6 Ethernet

The TS-7840 supports 7 total Ethernets. The CPU offers a total of 3 Ethernet ports which each have 1Gb/s of bandwidth available. The eth0/eth1 ports directly provide a connection to a dedicated CPU Ethernet. The eth2 port is connected to a Marvell 88E6352 gigabit switch.

TS-7840 Switch Diagram.jpg

The gigabit switch provides 5 external Ethernet ports. On startup all ports are disabled and Linux configures all 5 ports (lan0-lan4) to forward packets only to and from the CPU Ethernet port. These interfaces will act as individual Ethernet ports, with the exception that they share 1Gb/s to the CPU. If ports are bridged with brctl, the switch will connect their internal VLANs and forward packets between them without requiring the CPU's intervention. The WAN ports can also be forwarded to LAN ports the same with with brctl, but this will use CPU time instead to coordinate bridging the ports.

7.6.1 Onboard Marvell Switch Controller

The Marvell 88E6352 switch is supported by Linux's DSA (Distributed Switch Architecture). On startup Linux will expose all of the external ports as separate Ethernet ports. List all interfaces with:

ip a

The "lan0-lan4" ports on the TS-7840 are the external switch ports. By default these are configured to forward packets between the external port, and the CPU "eth2" interface. Packets will not forward between the external ports unless configured with brctl. To bring up a lan port:

# Bring up eth2, required for any of the switch
# ports to send/receive packets to the CPU
ip link set eth2 up
ip link set lan0 up
# At this point lan0 can be configured like any normal network interface
# Eg, start a dhcp client:
dhclient lan0

The switch can also be configured to connect ports together to pass packets without the CPU's intervention. This is done with brctl. For example, to bridge lan0 and lan1 together:

# Create a bridge interface
brctl addbr br0
# Add interfaces to the bridge
brctl addif br0 lan0
brctl addif br0 lan1

# Bring up the interfaces, note that eth2 is not
# required to be up in order to bridge the ports 
# unless packets must be accessed by Linux.
ip link set lan0 up
ip link set lan1 up
# lastly, bring up the bridge
ip link set br0 up

After this bridge is up, to access lan0/lan1 ports the br0 interface should be used. This br0 interface can now be treated like any other interface. Additional bridges can be created with "brctl addbr", and may include any of the externally available network ports.

7.6.2 POE Sourcing

The LAN4 (T1) port supports acting as a POE+ source (25W) to power another device. This requires a 48VDC supply to be connected to the #Power Connector, and enabling the POE source after boot.

# Enable POE Power
gpioset 3 6=0

7.6.3 PTP

TS-7840 PTP

7.7 FRAM

The unit supports an optional non-volatile Ferroelectric RAM (FRAM) device. The Cypress FM25L16B is a 2kbyte device, in a configuration not unlike an SPI EEPROM. However, the nature of FRAM means it is non-volatile, incredibly fast to write, and is specified with 100 trillion read/write cycles per each byte and a 150 year data retention. The device is connected to Linux and presents itself as a flat file that can be read and written like any standard Linux file.

The EEPROM file can be found at /sys/class/spi_master/spi2/spi0.0/eeprom, and should be accessed like a normal file to store data in the FRAM.

The last byte is reserved. This is used for U-boot's bootcount.

7.8 FPGA

The TS-7840 includes an Intel Cyclone IV FPGA. This is connected to the CPU over a x1 PCIe 2.0 lane, and provides additional perihperals and IO expansion to the system.

The onboard FPGA also permits customization such as adding quadrature encoders, PWM, additional serial ports, DMX, or other unique communication protocols. Please contact Technologic Systems if you require custom FPGA logic.

The FPGA registers are in PCIe BAR0 of 1e6d:7840, and use legacy level based interrupts for the shared peripherals.

All FPGA peripherals have drivers in our default BSP, but the FPGA registers can be manually accessed with fpga_peekpoke:

# 0x0 maps to the FPGA syscon, and register 0 of the syscon returns a static value.
fpga_peekpoke 32 0x0

Prints out 0xDEADBEEF.

FPGA memory map
Offset Description
0x0 FPGA Syscon
0x40 FPGA DIO Bank 2
0x5c FPGA DIO Bank 1
0x80 16550 #0 (COM1 RS-232)
0x88 16550 #1 (COM2 RS-232)
0x90 16550 #2 (GPS)
0x98 16550 #3 (Nimbelink)
0xa0 16550 #4 (Iridium Modem)
0xa8 16550 #5 (DSL Modem Debug)
0xb0 16550 #6 (Mikrobus UART)
0xb8 16550 #7 (RS-485)
0xc0 16550 #8 (XBEE)
0x200 SJA1000 compatible CAN controller
0x400 SPI controller

7.8.1 FPGA Syscon

Syscon
Offset Bits Access Description
0x0 31:0 Read Only Static value of 0xdeadbeef
0x4 31:0 Read Only CRC32 of running FPGA
0x8 31:0 RW ASMI
0xc 31:0 RW Scratch register
0x10 31:5 N/A Reserved
4 Read Only strap_5_pad
3 Read Only strap_4_pad
2 Read Only strap_3_pad
1 Read Only strap_2_pad
0 Read Only strap_1_pad
0x14 31:0 N/A Reserved
0x18 31 Read/Write Set 1 to reload FPGA from 0xf0000 in SPI flash
30:0 N/A Reserved
0x1c 31:0 Read Only Reserved
0x20 31:0 Read Only High Accuracy ms timer [1]
0x24 31:0 Read Only FPGA RNG
0x28 31:0 N/A Reserved
0x2c 31:0 N/A Reserved
0x30 31:0 N/A Reserved
0x34 31:0 Read/Write GPS Count
0x38 31:0 Read Only Epoch Time
0x3c 31:0 Read Only Epoch Time Fraction
  1. Compute hz with f(x, y) = x/y*1048576, where x = reg 0x34 (or 125e6) and y = reg 0x20

7.8.2 FPGA DIO

This FPGA includes two banks of GPIO with atomic set/clr for data and output enable, as well as level based IRQs. Under Linux this is exposed as /dev/gpiochip2 and /dev/gpiochip3. These character devices are normally accessed with libgpiod. The utilities from libgpiod are included in our shipping image and allow accessing GPIO from the shell prompt.

See gpioinfo for a list of all usable GPIO:

gpioinfo /dev/gpiochip2 /dev/gpiochip3

Returns:

 gpiochip2 - 32 lines:
 	line   0:  "uart0_irq"       unused   input  active-high 
 	line   1:  "uart1_irq"       unused   input  active-high 
 	line   2:  "uart2_irq"       unused   input  active-high 
 	line   3:  "uart3_irq"       unused   input  active-high 
 	line   4:  "uart4_irq"       unused   input  active-high 
 	line   5:  "uart5_irq"       unused   input  active-high 
 	line   6:  "uart6_irq"       unused   input  active-high 
 	line   7:  "uart7_irq"       unused   input  active-high 
 	line   8:  "uart8_irq"       unused   input  active-high 
 	line   9:    "gps_pps"       unused   input  active-high 
 	line  10:    "can_irq"       unused   input  active-high 
 	line  11:   "reserved"  "interrupt"   input  active-high [used]
 	line  12:   "reserved"       unused   input  active-high 
 	line  13:   "reserved"       unused   input  active-high 
 	line  14:   "reserved"       unused   input  active-high 
 	line  15:   "reserved"       unused   input  active-high 
 	line  16:   "reserved"       unused   input  active-high 
 	line  17:   "reserved"   "blue-led"  output  active-high [used]
 	line  18:   "reserved"       unused   input  active-high 
 	line  19:   "reserved"       unused   input  active-high 
 	line  20:   "reserved"       unused   input  active-high 
 	line  21:   "reserved"        "sda"   input  active-high [used]
 	line  22: "ird_network_rdy_pad" "scl" input active-high [used]
 	line  23: "ird_modem_on_pad" unused input active-high 
 	line  24: "oled_i2c_dat_pad" unused input active-high 
 	line  25: "oled_i2c_clk_pad" unused input active-high 
 	line  26: "grn_led_padn" "green-led" output active-low [used]
 	line  27: "red_led_padn" "red-led" output active-low [used]
 	line  28: "blu_led_pad" unused output active-high 
 	line  29: "prog_silab_clk_padn" unused input active-high 
 	line  30: "prog_silab_data_pad" unused input active-high 
 	line  31: "cpu_push_sw_padn" unused input active-high 
 gpiochip3 - 32 lines:
 	line   0: "en_ls_out_1_pad" unused input active-high 
 	line   1: "en_ls_out_2_pad" unused input active-high 
 	line   2: "en_ls_out_3_pad" unused input active-high 
 	line   3: "en_hs_sw_pad" unused input active-high 
 	line   4: "mikro_pwm_pad" unused input active-high 
 	line   5:   "reserved"       unused   input  active-high 
 	line   6: "en_poe_padn" unused input active-high 
 	line   7: "i2c_poe_clk_pad" unused input active-high 
 	line   8: "i2c_poe_dat_in_pad" unused input active-high 
 	line   9: "i2c_poe_dat_out_pad" unused input active-high 
 	line  10: "cage1_sda_pad" unused input active-high 
 	line  11: "cage1_scl_pad" unused input active-high 
 	line  12: "cage1_present_padn" unused input active-high 
 	line  13: "cage2_present_padn" unused input active-high 
 	line  14: "cage2_sda_pad" unused input active-high 
 	line  15: "cage2_scl_pad" unused input active-high 
 	line  16: "en_nimbel_4v_pad" unused input active-high 
 	line  17: "en_nimbel_3v3_pad" unused input active-high 
 	line  18: "en_emmc_3v3_pad" unused input active-high 
 	line  19: "en_modem_5v_pad" unused input active-high 
 	line  20: "en_usb_5v_pad" unused output active-high 
 	line  21: "en_nim_usb_padn" unused input active-high 
 	line  22: "mini_pcie_reset_padn" unused output active-high 
 	line  23: "ssd_present_padn" unused input active-high 
 	line  24: "en_xbee_usb_padn" unused input active-high 
 	line  25: "mikro_int_pad" unused input active-high 
 	line  26: "mikro_reset_padn" unused input active-high 
 	line  27: "mikro_an_3v_pad" unused input active-high 
 	line  28: "aux_i2c_dat_pad" "sda" input active-high [used]
 	line  29: "aux_i2c_clk_pad" "scl" input active-high [used]
 	line  30: "phy_0_led_pad" "phy-0-led" output active-low [used]
 	line  31: "phy_1_led_pad" "phy-1-led" output active-low [used]

From here, commands such as gpioget and gpioset can be used:

gpioget /dev/gpiochip2 31 # Get cpu_push_sw_padn
# Returns 1 when not pressed, 0 when pressed

gpioset /dev/gpiochip3 21=0 # Set en_usb_5v_pad to 0, turning off USB 5V
gpioset /dev/gpiochip3 21=1 # Re-enable USB

These driver interfaces should be used in most cases, but the register documentation is provided for driver writers or for those with reasons to go directly to the hardware:

GPIO Read Decodes
Offset Description
0x00 Output Enable [1]
0x04 Output Data
0x0C Data In
0x10 IRQ Enable [2]
0x14 IRQ Status [3]
0x18 IRQ nPOL [4]
GPIO Write Decodes
Offset Description
0x00 Output Enable Set
0x04 Output Enable Clear
0x08 Output Data Set
0x0c Output Data Clear
0x10 IRQ Enable
0x18 IRQ nPOL
  1. Output when 1, input when 0
  2. IRQ Enabled when 1, input when 0
  3. IRQ triggered when 1. The PCIe interrupt is only triggered if IRQ Enable is set, but this status will reflect changes whether or not the enable is on.
  4. IRQ active high when 0, active low when 1

7.8.3 FPGA 16550

The TS-7840 includes a National Semiconductor 16550A compatible register interface for accessing the FPGA based UARTs. These must be accessed a byte at a time. These use GPIO IRQs from bank0.

By default these UARTs have a crystal of 1.8432MHz. The max baud rate of a 16550 is the input frequency / 16. With the default 1.8432MHz clock this allows typical baud rates of 115200 to 300 baud. There is a command included in our BSP set_uart_baud which can set custom clocks. For example, to use 3MBaud on ttyS1:

root@tsa38x:~# set_uart_baud -p 0 --baud 3000000
port=0
requested_baud=3000000
actual_baud=3000000.000000
baud_ppm_error=823999

This was able to meet the 3M baud rate with minimal ppm error. In your application code, you would tell Linux to use 115200 baud. This will select a divide by 1 for the new clock rate and get 3000000 baud.

If you were to use an unusual baud rate this will print the closest actual_baud rate the clock is capable of reaching. Even if the actual_baud rate is different, as long as the difference between the two devices is < 10% they will typically still be able to communicate.

The 16550s already have existing drivers in our BSP, but the registers are accessible here:

PCIe BAR0 Offset UART IRQ GPIO
0x80 ttyS1 FPGA GPIO Bank 0 IO 0
0x88 ttyS2 FPGA GPIO Bank 0 IO 1
0x90 ttyS3 FPGA GPIO Bank 0 IO 2
0x98 ttyS4 FPGA GPIO Bank 0 IO 3
0xa0 ttyS5 FPGA GPIO Bank 0 IO 4
0xa8 ttyS6 FPGA GPIO Bank 0 IO 5
0xb0 ttyS7 FPGA GPIO Bank 0 IO 6
0xb8 ttyS8 FPGA GPIO Bank 0 IO 7
0xc0 ttyS9 FPGA GPIO Bank 0 IO 8

7.8.4 FPGA CAN

This FPGA includes a SJA1000 compatible controller. The Linux BSP includes a socketcan compatible driver.

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 using C-types, Java using JNI.

7.9 GPIO

The Armada 385 and FPGA GPIO are exposed using a kernel character device. This interface provides a set of files and directories for interacting with GPIO which can be used from any language that interact with special files in linux using ioctl() or similar. For our platforms, we pre-install the "libgpiod" library and binaries. Documentation on these tools can be found here. This section only covers using these userspace tools and does not provide guidance on using the libgpiod library in end applications. Please see the libgpiod documentation for this purpose.

A user with suitable permissions to read and write /dev/gpiochip* files can immediately interact with GPIO pins. For example, to read the push switch:

gpioget 2 31

Multiple pins in the same chip can be read simultaneously by passing multiple pin numbers separated by spaces.

To write to a pin, the 'gpioset' command is used. For example, to set mikro_int_pad:

gpioset 3 26=0

Multiple pins in the same chip can be set simultaneously by passing multiple pin=value pairs separated by spaces.

If a call with 'gpioset' or 'gpioget' fails with "Device or resource busy," that means that specific GPIO is claimed by another device. The command 'cat /sys/kernel/debug/gpio' can be used to get a list of all of the system GPIO and what has claimed them.

7.9.1 FPGA GPIO

Chip Pin Net Description
2 0 uart0_irq FPGA internal
2 1 uart1_irq FPGA internal
2 2 uart2_irq FPGA internal
2 3 uart3_irq FPGA internal
2 4 uart4_irq FPGA internal
2 5 uart5_irq FPGA internal
2 6 uart6_irq FPGA internal
2 7 uart7_irq FPGA internal
2 8 uart8_irq FPGA internal
2 9 gps_pps PPS signal from onboard GPS
2 10 can_irq FPGA internal
2 11 NC NC
2 12 NC NC
2 13 NC NC
2 14 NC NC
2 15 NC NC
2 16 NC NC
2 17 NC NC
2 18 NC NC
2 19 NC NC
2 20 NC NC
2 21 NC NC
2 22 ird_network_rdy_pad CN8 pin 19
2 23 ird_modem_on_pad CN8 pin 5
2 24 oled_i2c_dat_pad CN13 pin 1
2 25 oled_i2c_clk_pad CN13 pin 2
2 26 grn_led_padn LED1
2 27 red_led_padn LED1
2 28 blu_led_pad LED2
2 29 prog_silab_clk_padn Onboard Silabs
2 30 prog_silab_data_pad Onboard Silabs
2 31 cpu_push_sw_padn SW1
3 0 en_ls_out_1_pad CN17 top pin 7
3 1 en_ls_out_2_pad CN17 top pin 8
3 2 en_ls_out_3_pad CN17 bottom bin 15
3 3 en_hs_sw_pad CN17 bottom pin 16
3 4 mikro_pwm_pad CN12 pin 16
3 5 NC NC
3 6 en_poe_padn Onboard POE
3 7 i2c_poe_clk_pad Onboard POE
3 8 i2c_poe_dat_in_pad Onboard POE
3 9 i2c_poe_dat_out_pad Onboard POE
3 10 cage1_sda_pad Onboard SFP K3
3 11 cage1_scl_pad Onboard SFP K3
3 12 cage1_present_padn Onboard SFP K3
3 13 cage2_present_padn Onboard SFP K2
3 14 cage2_sda_pad Onboard SFP K2
3 15 cage2_scl_pad Onboard SFP K2
3 16 en_nimbel_4v_pad Onboard
3 17 en_nimbel_3v3_pad Enable 3.3V to nimbelink header
3 18 en_emmc_3v3_pad Enable onboard eMMC power
3 19 en_modem_5v_pad Enables power to ADSL modem, Internal USB, and Iridium Modem
3 20 en_usb_5v_pad Enable USB 5V to USB headers
3 21 en_nim_usb_padn Enables USB to the Nimbelink socket
3 22 mini_pcie_reset_padn J4 pin 22
3 23 ssd_present_padn K6 pin 1
3 24 en_xbee_usb_padn Enable USB port on XBEE socket
3 25 mikro_int_pad CN12 pin 15
3 26 mikro_reset_pad CN12 pin 2
3 27 mikro_an_3v_pad CN12 pin 1
3 28 aux_i2c_dat_pad Mikrobus I2C
3 29 aux_i2c_clk_pad Mikrobus I2C
3 30 phy_0_led_pad T2 bottom left LED
3 31 phy_1_led_pad T2 top left LED

7.10 I2C

This system includes 3 I2C busses.

The first bus is used for the RTC, onboard supervisory microcontroller, and connects to the FPGA.

/dev/i2c-0
Address Device
0x54 Onboard Supervisory microcontroller
0x68 ST M41T00S RTC

The second bus is used for the security chipset, and the Mikrobus socket

/dev/i2c-1
Address Device
0x64 ATSHA204 Security chipset

The third bus is for the SFP port (K3_A) on the right of the enclosure.

/dev/i2c-3
Address Device
0x50 SFP "eeprom" module


The fourth bus is for the second SFP port (K2_A) on the left edge of the enclosure.

/dev/i2c-4
Address Device
0x50 SFP "eeprom" module

7.11 LEDs

The TS-7840 has 2 external status LEDs (green/red), one internal blue LED, and control over the link status LEDs on the RJ45.

On startup, U-boot will turn on the red LED, and turn the green LED off. When Linux starts up, it will by default turn the red LED off, and the green LED will act as a kernel heartbeat which will blink at rates depending on the system load.

The LEDs are accessed through files. For example:

# Turn 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

# Set Green LED back to heartbeat
echo "heartbeat" > /sys/class/leds/green-led/trigger

# See all available triggers
cat /sys/class/leds/green-led/trigger

# Set PHY0 led back to default:
echo "f1072004.mdio-mii:00:1Gbps" > /sys/class/leds/phy-0-led/trigger

# Set PHY1 LED back to default
echo "f1072004.mdio-mii:01:1Gbps" > /sys/class/leds/phy-1-led/trigger

7.12 PCIe Controller

The Marvell Armada 385 supports two PCIe 2.0 channels with 1 lane each. On the TS-7840 the onboard FPGA provides all of its peripherals over one of the PCIe lanes. See the #FPGA section for more details on the FPGA's PCIe access.

The other PCIe bus is a x1 lane which is accessible on the #Mini PCIe header.

7.13 SATA

The TS-7840 provides one m.2 connector with SATA 3.

SATA disks will appear in Linux as /dev/sda. This is also a possible boot device if a valid operating system is installed on the disk.

7.14 Security Chipset (ATSHA204)

TS-7840 ATSHA204

7.15 SPI

TS-7840 SPI

7.16 TS-SILO Supercaps

TS-7840 Supercaps

7.17 UARTs

The TS-7840 includes 9 UARTs for onboard and offboard peripherals.

While /dev/ttyS0 is built into the CPU, the remaining UARTs are 16550As in the FPGA. These will work as typical Linux UARTs, with the exception that flow control is built into the UARTs. For RS-485 no special ioctls are required, and they will assert TX enable automatically on any transmit.

All of these UARTs are accessed using the standard /dev/ interfaces. See these resources for information on programming with UARTs in Linux.

UART Type TXD (+)Location RXD (-)Location
/dev/ttyS0 USB Silabs console board (CN7) Silabs console board (CN7)
/dev/ttyS1 RS-232 Terminal block bottom pin 3 Terminal block bottom pin 2
/dev/ttyS2 RS-232 Terminal block bottom pin 5 Terminal block bottom pin 4
/dev/ttyS3 Onboard to GPS N/A GPS
/dev/ttyS4 3.3V TTL Nimbelink CN16 pin 3 Nimbelink CN16 pin 2
/dev/ttyS5 3.3V TTL Iridium CN8 pin 6 Iridium CN8 pin 7
/dev/ttyS6 3.3V TTL ADSL CN15 pin 9 ADSL CN15 pin 8
/dev/ttyS7 3.3V TTL Mikrobus CN12 pin 13 Mikrobus CN12 pin 14
/dev/ttyS8 RS-485 Terminal block top pin 3 Terminal block top pin 2
/dev/ttyS9 3.3V TTL XBEE CN20 pin 3 XBEE CN20 pin 2

7.18 USB Host

TS-7840 USB Controller

8 Specifications

8.1 I/O Specification

TS-7840 IO Specs

8.2 Power Input Specification

TS-7840 Power supply

8.3 Power Consumption

TS-7840 Power Consumption

8.4 Power Outputs

TS-7840 Power Outputs

8.5 Thermal Specifications

TS-7840 Thermal testing

9 External Interfaces

9.1 DSL Modem

The TS-7840 supports the Mestechs aDSL modem. This communicates over both a UART (/dev/ttyS6 at 115200 8n1), and a 10/100 Ethernet. The 10/100 Ethernet connects to the arm CPU using an onboard USB SMSC95XX Ethernet controller. This is shown in Linux as eth3.

# Turn on modem 5V:
gpioset 3 19=1


DSL Modem header pinout
Pin Description
1 MODEM_SW_5V
2 GND
3 NC
4 ETH_100_TX-
5 ETH_100_TX+
6 ETH_100_RX-
7 ETH_100_RX+
8 DSL_MODEM_RXD (/dev/ttyS6)
9 DSL_MODEM_TXD (/dev/ttyS6)
10 GND
11 NC
12 NC
13 NC
14 RING (#RJ11)
15 TIP (#RJ11)

9.1.1 RJ11

The TS-7840 includes an RJ11 port used for the optional aDSL modem.

Pin Description
1 NC
2 NC
3 TIP
4 RING
5 NC
6 NC

9.1.2 Earth GND connector

The EARTH ground connector is used by the ADSL port only to provide transient protection on the RJ11 port.

9.2 Ethernet Interfaces

See the this section for further detail on networking usage.

TS-7840 Ethernets.jpg

9.2.1 SFP Ports

The TS-7840 supports two SFP ports which replace existing copper ports. SFP0 uses the same controller as ETH1, and SFP1 uses the same controller as eth0. If both SFP0 and ETH1 are connected, the copper connection is preferred.

While we expect any 1Gbit fiber SFP should be compatible, these are the modules we have tested:

  • Finisar FTLF1318P3BTL
  • Finisar FTLF8519P3BTL

9.3 GPS

The GPS uses an embedded Telit SL869 module with an externally accessible SMA antenna. This is accessible at /dev/ttyS3 where the GPS provides NMEA strings.

A typical way of interfacing with the GPS is using gpsd. For example, under Debian:

apt install gpsd gpsd-clients -y

Then edit /etc/default/gpsd and change these two options:

# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
DEVICES="/dev/ttyS3"

# Other options you want to pass to gpsd
GPSD_OPTIONS="-b -n"

Then restart gpsd:

service gpsd restart

This allows clients from command line, or from most programming languages to interface with the GPS through gpsd:

9.4 Terminal Blocks

The TS-7840 includes two removable terminal blocks with 8 pins each.

This header includes 3 low side switches and one high side switch.

The low side switches can sink up to 700mA and support up to 30VDC. These IO feature a shared circuit breaker that will trip if the combined sinks total over 1000mA.

The high-side switch outputs the 10-48VDC source used to power the boards and will supply up to the 48VDC input max. This IO features its own circuit breaker that will trip at 330mA.

300px


TS-7840 Terminal Blocks.png
Top
Pin # Description
1 Ground
2 RS485- (/dev/ttyS8)
3 RS485+ (/dev/ttyS8)
4 CAN_H (can0 interface)
5 CAN_L (can0 interface)
6 Ground
7 Low side switch GPIO bank 3 IO 0
8 Low side switch GPIO bank 3 IO 1
Bottom
Pin # Description
1 Ground
2 COM1_232_RXD (/dev/ttyS1)
3 COM1_232_TXD (/dev/ttyS1)
4 COM2_232_RXD (/dev/ttyS2)
5 COM2_232_TXD (/dev/ttyS2)
6 Ground
7 Low side switch GPIO bank 3 IO 2
8 High side switch GPIO bank 3 IO 3


9.5 Iridium Modem

The TS-7840 supports Iridium modems on CN8. This supports the Iridium Antenna on the external "IRD" SMA connector. The optional Iridium GPS antenna is not connected. For GPS support we recommend using the TS-7840's built in #GPS.

TS-7840 Iridium.jpg

# Turn on power to the modem
gpioset 3 19=1

# Release the modem reset
gpioset 2 23=1

# Poll for modem to be on the network
gpioget 2 22
# 0 = not ready

The Iridium modem usage is covered by the Iridium datasheet, but the modem can be tested with picocom:

picocom -b 19200 /dev/ttyS5

Type "AT" and press enter, and it should respond with "OK".

Pin Description
1 5V
2 5V
3 GND
4 GND
5 IRD_MODEM_ON GPIO Bank 2 IO 23
6 /dev/ttyS5 TXD
7 /dev/ttyS5 RXD
8 GND
9 /dev/ttyS5 DCD
10 /dev/ttyS5 DSR
11 /dev/ttyS5 CTS
12 /dev/ttyS5 RI
13 /dev/ttyS5 RTS
14 /dev/ttyS5 DTR
15 GND
16 NC
17 NC
18 GND
19 IRD_NETWORK_RDY GPIO Bank 2 IO 22
20 Modem 3.3V

9.6 Jumpers

TS-7840 Jumpers

9.7 Mikrobus

The Mikrobus provides compatibility with Mikroe's 750+ click boards. This interface has SPI, I2C, PWM, analog, a TTL UART, 3.3V and 5V.


Pin Name Description
1 AN gpio bank 3 io 27, #Silabs ADC
2 RST gpio bank 3 io 26
3 SPI_0_MIKRO_CS2# CPU SPI Chip select #2
4 SPI_0_CLK CPU SPI CLK
5 SPI_0_MISO CPU SPI MISO
6 SPI_0_MISO CPU SPI MISO
7 3.3V 3.3V source
8 GND GND
TS-7840 Mikrobus.png
Pin Description
16 PWM PWM 0
15 INT gpio bank 3 io 25
14 MIKRO_RXD ttyS7 RXD
13 MIKRO_TXD ttyS7 TXD
12 AUX_I2C_CLK /dev/i2c-2
11 AUX_I2C_DAT /dev/i2c-2
10 5V 5V Source
9 GND GND

9.8 Mini PCIe

TS-7840 minipcie

9.9 M.2 SATA

The m.2 SATA SSD port supports 2242 (22mmx42mm) drives supporting SATA III. The m.2 port includes a B key. This header does not include a pcie lane as used by NVME. If this is programmed with a bootable image this will be preferred over the onboard flash in the boot order.

9.10 Nimbelink Socket

The Nimbelink Cell Radio socket is intended for Nimbelink's Skywire embedded modems.

# Turn off both, only 1 can be on.
gpioset 3 16=0
gpioset 3 17=0

# For modems wanting 4V:
gpioset 3 16=1

# For modems wanting 3.3V:
gpioset 3 17=1

If your modem supports USB, this must be enabled.

gpioset 3 21=0

For UART based modems these may default to faster speeds than the default clock.

set_uart_baud --port 3 --baud 921600
picocom -b 115200 /dev/ttyS4
Note: Some Nimbelink cell modems have a long startup and may not show up on USB for a minute before enumerating on USB.
Pin Description
11 GND
12 /dev/ttyS4 CTS
13 NC
14 3.3V
15 GND
16 GND
17 NC
18 NC
19 NC
20 GND
TS-7840 Nimbelink.png
Pin Description
10 GND
9 GND
8 USB-
7 USB+
6 4.7V
5 NC
4 GND
3 /dev/ttyS4 TXD
2 /dev/ttyS4 RXD
1 NIMBEL_PWR (3.3V or 4V)

While pin 1 commonly lines up with the antennas on the modems, the pin 1 orientation should be verified in your modem's datasheet.

9.11 Power Connector

The power connector includes a removable 4 pin terminal block. To power the board, only 8-48VDC is required. The POE power pins can be left disconnected unless powering another device with POE PSE.

Pin Description
1 (Left) 10-48VDC
2 GND
3 POE 48V +
4 POE 48V -
TS-7840 Power Connector.png

9.12 Push Button

SW1 is an externally facing push button. This is accessible through the enclosure on a small hole near the USB console port.

This is read as a GPIO:

gpioget 2 31

9.13 USB Connectors

The TS-7840 has a total of 3 externally facing USB ports, and one internal USB port. All 4 are type A ports. 2 are USB 3.0, and 2 are USB 2.0.

CN11 is an external port with blue connectors which is USB 3.0. CN9 by the RJ11/SFP port is a USB 2.0 port. CN3 internal to the board has one active port on the top which can be use for internal USB peripherals. The lower port on USB 3.0 is not connected.

The internal USB port must be enabled with:

# Select internal USB (CN3)
gpioset 3 24=1

# Enable Modem SW 5V
gpioset 3 19=1


The external ports all have a single controllable rail that can be used to turn off power, or reset a problematic device in the field. This does not affect the modem 5V used for the internal USB.

# Turn off power
gpioset 3 20=0

# Turn on power
gpioset 3 20=1

9.14 XBEE Header

This board supports DIGI modules compatible with the XBEE pinout. This typically includes their 802.15.4, digimesh, or even the digi cellular modems. When a module is connected with USB, this should be enabled with:

# Set en_xbee_usb_padn low
gpioset 3 24=0

On non-USB modules, this pin is listed as reserved and has been observed to prevent normal functionality. With serial modules, this pin should be left in the default state, or set high to disable USB.

Related Links:

The XBEE header follows the pinout from digi:

Pin Description
1 3.3V
2 XBEE_RXD (/dev/ttyS9)
3 XBEE_TXD (/dev/ttyS9)
4 GND
5 NC
6 3.3V
7 USB_XBEE_P
8 USB_XBEE_M
9 GND
10 GND
Pin Description
11 GND
12 NC
13 NC
14 NC
15 NC
16 NC
17 NC
18 NC
19 NC
20 NC

10 Revisions and Changes

10.1 TS-7840 PCB Revisions

TS-7840 PCB Revs

10.2 U-Boot Changelog

TS-7840 U-boot Changelog

10.3 FPGA Changelog

TS-7840 FPGA Changelog

10.4 Software Images

10.4.1 Debian Changelog

TS-7840 Debian Changelog