TS-7840: Difference between revisions

From embeddedTS Manuals
Line 440: Line 440:
|-
|-
| 0x5c
| 0x5c
| [[#FPGA_DIO|DIO Bank 1]]
| [[#FPGA_DIO|FPGA DIO Bank 1]]
|-
|-
| 0x80
| 0x80

Revision as of 17:42, 30 August 2019

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


Overview

The TS-7840 is a Single Board Computer (SBC) based on a Marvell MV88F6820 1.3GHz (1.8GHz optional) 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 RJ45 Ethernets that can be use for filtering or switching.

Getting Started

A Linux PC is recommended for development. For developers who use Windows, virtualized Linux using VMWare or similar are 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 target platform. 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.
  • Builds such as Linux kernel, buildroot, yocto, distro-seed will not work from WSL1/2 on a case insensitive filesystem.
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.

Getting Console and Powering up

The TS-7840 receives power through the 3 pin power connecting from 5VDC, or 8-28VDC power. Once power is applied, the device will output information via the console. The first output is from U-Boot:

U-Boot 2017.09-00078-gfc76cc1452 (Feb 13 2018 - 16:07:14 -0700)

SoC:   MV88F6820-A0 at 1333 MHz
I2C:   ready
DRAM:  1 GiB (533 MHz, ECC enabled)
MMC:   mv_sdh: 0
SF: Detected n25q64 with page size 256 Bytes, erase size 4 KiB, total 8 MiB
*** Warning - bad CRC, using default environment

PCI:
  00:01.0     - 1172:0004 - Does not fit any class
Model: Technologic Systems TS-7840
fpga_rev=31
board_id=0xB480
SCSI:  MVEBU SATA INIT
SATA link 0 timeout.
SATA link 1 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)
Booting kernel/dtb from eMMC and rootfs from SD

This u-boot and its environment is loaded from the emmc boot partition 0. This a hardware partition that is independent of the main flash on the emmc. From here, you can use the SD boot jumper to pick between SD/eMMC, or you can change the environment to "run usbboot", "run sataboot", or override the jumper and use emmcboot or sdroot by default.

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.

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

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 lets you set fuses in the processor
# Setting fuses can brick your board, will void your warranty,
# and should not be done in most cases
fuse

# This command is used to copy a file from most devices
# Load kernel from SD
ext4load mmc 1:2 ${loadaddr} /boot/zImage
# Load Kernel from eMMC
ext4load mmc 0:2 ${loadaddr} /boot/zImage

# You can view the fdt from u-boot with fdt
ext4load 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
ext4load mmc 0:2 ${loadaddr} /boot/custombinary
go ${loadaddr}

# Browse fat,ext2,ext3,or ext4 filesystems:
ext4ls 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

# Check for new SD card
mmc rescan
# Read SD card size
mmc dev 1
mmcinfo
# Read eMMC Size
mmc dev 0
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

# Delay in seconds
sleep 10

# You can load HUSH scripts that have been created with mkimage
ext4load 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 bdinfo

# Print U-boot version/build information
version

First Linux Boot

U-Boot is always loaded from the onboard eMMC boot partitions (/dev/mmcblk0boot*). U-boot can access the eMMC, SATA, Network, an USB. By default it will load Linux from the first partition on the eMMC, but it can be configured to boot to SATA or Network by default. When the U-Boot jumper is present the board will attempt to boot to USB for our #Production Mechanism.

The eMMC and SD cards shipped with the unit are pre-programmed with our Debian Stretch image.

Backup / Restore

SD Card

Note that only one of the full-size SD card and microSD card may be present at any given time.

If backing up on a separate workstation, keep in mind windows does not have direct block device support needed to write these images. You will also need to determine the SD card device. You can usually find this in the output of 'dmesg' after inserting the SD card and you will typically see something like '/dev/sdb' as the block device and '/dev/sdb1' for the first partition. On some newer kernels you will see '/dev/mmcblk0' as the block device and '/dev/mmcblkop1' for the first partition. For these examples it will be assumed that your workstation uses the '/dev/mmcblk0' format. Both of the sd cards will use the same commands, but with the name of the block device being "/dev/tssdcarda".

If you are backing up directly on the board you will likely need to use some kind of offboard storage like a thumbdrive or external hard drive.

From Workstation


Backup

Entire SD card

dd if=/dev/mmcblk0 of=/path/to/backup.dd bs=4M conv=fsync

Initrd

dd if=/dev/mmcblk0p2 of=/path/to/initrd bs=4M conv=fsync

Restore

Entire SD card

dd if=/path/to/backup.dd of=/dev/mmcblk0 bs=4M conv=fsync

Initrd

dd if=/path/to/initrd  of=/dev/mmcblk0p2 bs=4M conv=fsync

From TS-7800-V2


Backup

Entire card

dd if=/dev/mmcblk0 of=/path/to/backup.dd bs=4M conv=fsync

Restore

The entire card from SBC

dd if=/path/to/sdimage.dd of=/dev/mmcblk0 bs=4M conv=fsync

Debian

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:

Getting Started with Debian

Once installed the default user is "root" with no password. Services such as telnet, ssh, or others will typically require a password set and other configuration before they allow remote connections.

The current shipping image can always be downloaded here:

There is a newer distribution for those who would prefer Debian Buster, here:

Prepare a USB media device (thumb drive, memory stick, etc.). Use a partitioning tool such as 'fdisk' 'cfdisk' or 'gparted' in linux to create a single linux partition on the media. The default shipping images use GPT partitions MBR will also work. Then format the device using 'sudo mkfs.ext3 /dev/devicename_here' if your preferred partition tool (such as fdisk) does not format the media for you. Once the media is formatted, extract the above tarball with:

# Assuming your media card is /dev/sdc with one partition
mkfs.ext3 /dev/sdc1
mkdir /mnt/sd/
sudo mount /dev/sdc1 /mnt/sd/
sudo tar --numeric-owner -xJf ts7800v2-deb_stretch-latest.tar.xz -C /mnt/sd     #note the capital J for xz decompression
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.

To rewrite the eMMC the unit must be booted to media that is not eMMC. Once booted, run the following commands:

mkfs.ext3 /dev/mmcblk0p1
mkdir /mnt/emmc
mount /dev/mmcblk0p1 /mnt/emmc
wget ftp://ftp.embeddedTS.com/ts-arm-sbc/ts-7800-v2-linux/distributions/ts7800v2-deb_stretch-latest.tar.xz
tar -xJf ts7800v2-deb_stretch-latest.tar.xz -C /mnt/emmc/
umount /mnt/emmc
sync

The same commands can be used to write a SATA drive by substituting /dev/mmcblk2p1 with /dev/sda1.

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

Older Debian releases are moved to a different server to indicate it is no longer getting security updates. To download packages for these older distributions, edit /etc/apt/sources.list to only have the following lines:

Jessie:

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

Wheezy:

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

After modifying that file, be sure to update the package list:

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@ts:~# apt-cache search openjdk
jvm-7-avian-jre - lightweight virtual machine using the OpenJDK class library
freemind - Java Program for creating and viewing Mindmaps
icedtea-7-plugin - web browser plugin based on OpenJDK and IcedTea to execute Java applets
default-jdk - Standard Java or Java compatible Development Kit
default-jdk-doc - Standard Java or Java compatible Development Kit (documentation)
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)
icedtea-7-jre-jamvm - Alternative JVM for OpenJDK, using JamVM
openjdk-7-dbg - Java runtime based on OpenJDK (debugging symbols)
openjdk-7-demo - Java runtime based on OpenJDK (demos and examples)
openjdk-7-doc - OpenJDK Development Kit (JDK) documentation
openjdk-7-jdk - OpenJDK Development Kit (JDK)
openjdk-7-jre - OpenJDK Java runtime, using Hotspot Zero
openjdk-7-jre-headless - OpenJDK Java runtime, using Hotspot Zero (headless)
openjdk-7-jre-lib - OpenJDK Java runtime (architecture independent libraries)
openjdk-7-source - OpenJDK Development Kit (JDK) source files
uwsgi-app-integration-plugins - plugins for integration of uWSGI and application
uwsgi-plugin-jvm-openjdk-7 - Java plugin for uWSGI (OpenJDK 7)
uwsgi-plugin-jwsgi-openjdk-7 - JWSGI plugin for uWSGI (OpenJDK 7)
                                                       

In this case you will want the openjdk-7-jre package. Names of packages are on Debian's wiki or the packages site.

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

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

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

Debian Setting Up SSH

To install ssh, install the package as normal with apt-get:

apt-get install openssh-server


Make sure the device is configured on the network and set a password for the remote user. SSH will not allow remote connections without a password or a valid SSH key pair.

passwd root
Note: The default OpenSSH server will not permit root to login via SSH as a security precaution. To allow root to log in via ssh anyway, edit the /etc/ssh/sshd_config file and add the line PermitRootLogin yes in the authentication section. This change will take effect after reboot or after sshd service restart.

After this setup it is now possible to connect from a remote PC supporting SSH. On Linux/OS X this is the "ssh" command, or from Windows using a client such as PuTTY.

Note: If a DNS server is not present on the target network, it is possible to save time at login by adding "UseDNS no" in /etc/ssh/sshd_config.

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

To start an application on bootup with X11 instead change the x-session-manager. By default the system starts xfce:

root@ts:~# ls -lah /usr/bin/x-session-manager 
lrwxrwxrwx 1 root root 35 May 26  2015 /usr/bin/x-session-manager -> /etc/alternatives/x-session-manager
root@ts:~# ls -lah /etc/alternatives/x-session-manager
lrwxrwxrwx 1 root root 19 May 26  2015 /etc/alternatives/x-session-manager -> /usr/bin/startxfce4

The x-session can be modified to only start specified processes. Create the file /usr/bin/mini-x-session with these contents:

#!/bin/bash
matchbox-window-manager -use_titlebar no &

exec xfce4-terminal

You may need to "apt-get install matchbox-window-manager." first. This is a tiny window manager which also has a few flags that simplify embedded use. Now enable this session manager and restart slim to restart x11 and show it now.

chmod a+x /usr/bin/mini-x-session
rm /etc/alternatives/x-session-manager
ln -s /usr/bin/mini-x-session /etc/alternatives/x-session-manager
service slim restart

If the x-session-manager process ever closes x11 will restart. The exec command allows a new process to take over the existing PID. In the above example xfce4-terminal takes over the PID of x-session-manager. If the terminal is closed with commands like exit the slim/x11 processes will restart.

Debian Application Development

Debian Stretch Cross Compiling

Debian Stretch provides cross compilers from the Debian apt repository archive for Debian Stretch. An install on a workstation can build for the same release on other architectures. A Linux desktop or laptop PC, virtual machine, or chroot will need to be used for this. Debian Stretch for a workstation can be downloaded from here.

From a Debian workstation (not the target), run these commands to set up the cross compiler:

# Run "lsb_release -a" and verify Debian 9.X is returned.  These instructions are not
# expected to work on any other version or distribution.
su root
# Not needed for the immediate apt-get install, but used
# so we can install package:armhf for cross compiling
dpkg --add-architecture armhf
apt-get update
apt-get install curl build-essential crossbuild-essential-armhf -y

This will install a toolchain that can be used with the prefix "arm-linux-gnueabihf-". The standard GCC tools will start with that name, eg "arm-linux-gnueabihf-gcc".

The toolchain can now compile a simple hello world application. Create hello-world.c on the Debian workstation:

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

To compile this:

arm-linux-gnueabihf-gcc hello-world.c -o hello-world
file hello-world

This will return that the binary created is for ARM. Copy this to the target platform to run it there.

Debian Stretch supports multiarch which can install packages designed for other architectures. On workstations this is how 32-bit and 64-bit support is provided. This can also be used to install armhf packages on an x86 based workstation.

This cross compile environment can link to a shared library from the Debian root. The package would be installed in Debian on the workstation to provide headers and libraries. This is included in most "-dev" packages. When run on the arm target it will also need a copy of the library installed, but it does not need the -dev package.

apt-get install libcurl4-openssl-dev:armhf

# Download the simple.c example from curl:
wget https://raw.githubusercontent.com/bagder/curl/master/docs/examples/simple.c
# After installing the supporting library, curl will link as compiling on the unit.
arm-linux-gnueabihf-gcc simple.c -o simple -lcurl

Copy the binary to the target platform and run on the target. This can be accomplished with network protocols like NFS, SCP, FTP, etc.

If any created binaries do not rely on hardware support like GPIO or CAN, they can be run using 'qemu'.

# using the hello world example from before:
./hello-world
# Returns Exec format error
apt-get install qemu-user-static
./hello-world

Compile The Kernel

WARNING: BACK UP YOUR DATA FIRST

Prerequisites

This guide is intended to run on an x86 compatible Linux workstation. While you may be able to compile the kernel on the board, we do not recommend it. A typical workstation compile will take several minutes. The same compile on the board may take several hours.

RHEL/Fedora/CentOS:

yum install ncurses-devel ncurses
yum groupinstall "Development Tools" "Development Libraries"
Ubuntu/Debian:
apt-get install build-essential libncurses5-dev libncursesw5-dev

For other distributions, please refer to their documentation to find equivalent tools. Next you need to set up the cross compiler and sources:

# Download the cross compile toolchain from Technologic Systems:
wget ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7800-v2-linux/cross-toolchains/armv7-marvell-linux-gnueabi-hard_i686_64K_Dev_20131002.tar.bz2

#Extract to current working directory:
tar -xjf armv7-marvell-linux-gnueabi-hard_i686_64K_Dev_20131002.tar.bz2

#Download the kernel sources
git clone https://github.com/embeddedarm/linux-armada38x.git

cd linux-4.4.8

Export the CROSS_COMPILE variable with a path that points to the appropriate cross-compiler. If you followed the steps above exactly, the toolchain is extracted into the same directory as the kernel.

export CROSS_COMPILE=../armv7-marvell-linux-gnueabi-hard_i686_64K_Dev_20131002/bin/arm-marvell-linux-gnueabi-
export ARCH=arm

Now you will want to configure your settings. You can start with our default config by running:

make ts7800_v2_defconfig

At this point you can configure any additional options with:

make menuconfig

After you saved the configuration, you can build your kernel and modules with:

make && make modules

Features

CPU Functionality

MMU

The 88F6020 features a Memory Management Unit, enabling high level operating systems such as Embedded Linux to run on the TS-7800-V2. In the same way, the Linux TS-Kernel takes advantage of the MMU functionality. The MMU is controlled by page tables stored in system memory and is responsible for virtual address to physical address translation, memory protection through access permissions and domains, MMU cache and write buffer access. In doing so, software applications can access larger "virtual" memory space than the available physical memory size, allowing multiple programs to run and use the system memory simultaneously.

Interrupts

The 88F6020 has 192 interrupts available on chip as well as another TBD implemented in the Lattice FPGA by using the doorbell interrupt register (???).

TBD

For more information about the interrupt functionalities, refer to the 88F6020 User's Guide.

Onboard eMMC Flash

This board includes an 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 SBC if the CPU fails to boot. Make certain a valid u-boot is present on the 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


USB Host

The USB Connector on the TS-7800-V2 provide two USB 3.0 interfaces for the user. These are directly connected to the MV88F6020 processor, which integrates a USB dual-port Extensible Host Controller Interface (xHCI), providing serial communications ports at a baud rate of up to 5 Gbit/s ("SuperSpeed"). The MV88F6020 also has a USB 2.0 controller, with Enhanced Host Controller Interface (EHCI) for full compatibility with USB 2.0 at speeds up to 480 Mbits/sec ("High-Speed").

Linux provides support for most USB devices through drivers. Direct access to communicate with USB peripherals is typically done with libusb.

Additional non-volatile storage may be added with a USB flash drive. This device supplies additional non-volatile storage either for data or for a complete operation system distribution, such as Debian. A tar-file of Debian is available on the Technologic Systems FTP site.

SATA

The TS-7800-V2 provides up to two SATA 3.0 ports at data rates of up to 6 Gbits/sec.

SATA drives will appear (in Linux) as /dev/sda and (with the optional second SATA port) /dev/sdb. In U-Boot, after executing the "scsi init" command, they will appear as SCSI drives "scsi 1:0" and (with the optional second SATA port) "scsi 0:0".

If the drive is formatted, with the required files in the "/boot" subdirectory, the board may be booted from the drive by substituting (for example) "scsi 0:1" for "mmc 0:2" in the ext4load command (see the #U-Boot Commands section for more details on booting). It will also be necessary to modify the bootargs from (for example) "root=/dev/mmcblk0p2" to "root=/dev/sda1".

DDR3 RAM

The TS-7800-V2 comes with 1 GB of DDR3 as standard, with 2 GB as an option.


SiLabs Functionality

ADC Sampling

The TS-7800-V2 provides an analog to digital capture function through the on-board SiLabs microcontroller. The microcontroller has five 10 bit 0-5V analog inputs and is capable of sampling at up to 500 kspa. The analog input channels are brought out to the A/D header (see table below). A voltage divider is used on each input to divide the input voltage by two; therefore, the maximum input voltage at the header should not exceed 6.6V.

The A/D header is laid out as follows:

GND GND GND GND GND
2 4 6 8 10
1 3 5 7 9
CH0 CH1 CH2 CH3 CH4

The ADC is implemented using ts7800ctl:

root@ts7800:root# ts7800ctl -S 0,1
[0x00000000, 0]=1023
[0x00000001, 1]=0810
[0x00000002, 0]=1023
[0x00000003, 1]=1023
[0x00000004, 0]=1023

This requests ts7800ctl to output ADC in string data. This returns:

 [Hex counter, Channel]=Value

If you prefer to implement this in your own code, you can get ts7800ctl.c here.

Examples

# Capture 1000 raw binary samples from channel 0 and print the output to a file in a comma separated format.
ts7800ctl -r"0" | dd bs=2 count=1000 2>/dev/null | hexdump -v -e '1/2 "%u, "' > ch0_500_samples.csv

#Capture 500 samples from channel 0 and 500 samples from channel 1. Write the 
#samples to a file where all channel 0 samples are in the first column and all 
#channel 1 samples are in the second column.
ts7800ctl -r"0-1" | dd bs=2 count=1000 | hexdump -v -e '1/2 "0x%x\t" 1/2 "0x%x\n"' > ch0_ch1_1k_samples.dat

#Capture 1000 samples from channel 0, and then print the output to standard out in ASCII.
ts7800ctl -S"0,1" 2>/dev/null | dd bs=19 count=1000

#Capture 5 samples from channel 0 and 5 samples from channel 1, then print the output to standard out in ASCII.
ts7800ctl -S"0-1" 2>/dev/null | dd bs=19 count=10

FPGA Functionality

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

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 [1] 31:24 N/A Reserved
23 Read Only strap_5_pad [2]
22 Read Only i2c_err [3]
21 Read Only crc32_done [4]
20 Read Only cpu_push_sw_padn
19 Read Only strap_4_pad [2]
18 Read Only strap_3_pad [2]
17 Read Only strap_2_pad [2]
16 Read Only strap_1_pad [2]
15 Read Only sys_reset_padn
14 Read Only Always 1
13 Read Only prog_silab_data_pad
12 Read Only jp2_padn
11 Read Only jp1_padn
10 Read Only power_fail_3v_pad
9 Read Only oled_i2c_clk_pad
8 Read Only oled_i2c_dat_pad
7 Read Only ssd_present_padn
6 Read Only pps_lock
5 Read Only GPS Lock
4 Read Only GPS Detected
3:0 N/A Reserved
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 [5]
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. This register is only needed for the early strapping registers.
  2. 2.0 2.1 2.2 2.3 2.4 The straps indicate the features on this board which are used to match the board with a model number
  3. Indicates issues with i2c on startup
  4. Loading the CRC32 as shown in 0x4 takes some ms to complete. This register can be polled either in early boot or after FPGA reload to know when to safely access the CRC32.
  5. Compute hz with f(x, y) = x/y*1048576, where x = reg 0x34 (or 125e6) and y = reg 0x20

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