How to use & access OpenRex peripherals (Examples)

Content

DDR3 Memory test

First check how much free memory you have (we used 2GB OpenRex version):
free
             total       used       free     shared    buffers     cached
Mem:       1805768     236512    1569256          0       7584     132584
-/+ buffers/cache:      96344    1709424
Swap:            0          0          0
#
To run the memory test use as much free memory as you can:
# memtester 480M
memtester version 4.3.0 (32-bit)
Copyright (C) 2001-2012 Charles Cazabon.
Licensed under the GNU General Public License version 2 (only).

pagesize is 4096
pagesizemask is 0xfffff000
want 480MB (503316480 bytes)
got  480MB (503316480 bytes), trying mlock ...locked.
Loop 1:
  Stuck Address       : ok
  Random Value        : ok
  Compare XOR         : ok
  Compare SUB         : ok
  Compare MUL         : ok
  Compare DIV         : ok
  Compare OR          : ok
  Compare AND         : ok
  Sequential Increment: ok
  Solid Bits          : ok
  Block Sequential    : ok
  Checkerboard        : ok
  Bit Spread          : ok
  Bit Flip            : ok
  Walking Ones        : ok
  Walking Zeroes      : ok
  8-bit Writes        : ok
  16-bit Writes       : ok

Ethernet test

A simple ping test. You can increase the size of the packet (press -s switch) an specify number of packets (use -c switch):
# ping -c 5 -s 1000 192.168.0.80
PING 192.168.0.80 (192.168.0.80) 1000(1028) bytes of data.
1008 bytes from 192.168.0.80: icmp_req=1 ttl=64 time=0.358 ms
1008 bytes from 192.168.0.80: icmp_req=2 ttl=64 time=0.280 ms
1008 bytes from 192.168.0.80: icmp_req=3 ttl=64 time=0.333 ms
1008 bytes from 192.168.0.80: icmp_req=4 ttl=64 time=0.271 ms
1008 bytes from 192.168.0.80: icmp_req=5 ttl=64 time=0.338 ms

--- 192.168.0.80 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3996ms
rtt min/avg/max/mdev = 0.271/0.316/0.358/0.034 ms
You can also test the Ethernet by downloading a big file form a remote server:
wget http://www.imx6rex.com/rex-uploads/imx6rex-xubuntu-13-04-production-04-AUG-2014.tar
--2016-02-09 11:17:04--  http://www.imx6rex.com/rex-uploads/imx6rex-xubuntu-13-04-production-04-AUG-2014.tar
Resolving www.imx6rex.com (www.imx6rex.com)... 54.83.203.118
Connecting to www.imx6rex.com (www.imx6rex.com)|54.83.203.118|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 627334028 (598M) [application/x-tar]
Saving to: imx6rex-xubuntu-13-04-production-04-AUG-2014.tar

100%[======================================>] 627,334,028 2.24MB/s   in 7m 56s

2016-02-09 11:25:01 (1.26 MB/s) - imx6rex-xubuntu-13-04-production-04-AUG-2014.tar saved [627334028/627334028]

USB

Plug in a USB memory stick, and use dmesg command. You will see a message like this:
# dmesg | tail
usb 2-1.2: new high speed USB device number 5 using fsl-ehci
scsi1 : usb-storage 2-1.2:1.0
scsi 1:0:0:0: Direct-Access     TOSHIBA  TransMemory      1.00 PQ: 0 ANSI: 4
sd 1:0:0:0: [sdb] 30297216 512-byte logical blocks: (15.5 GB/14.4 GiB)
sd 1:0:0:0: [sdb] Write Protect is off
sd 1:0:0:0: [sdb] Mode Sense: 45 00 00 00
sd 1:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
 sdb: sdb1
sd 1:0:0:0: [sdb] Attached SCSI removable disk
Mount the USB (in this example the USB is formatted as FAT)
# mount /dev/sdb1 /media/usb0
# ls -la /media/usb0
total 3590620
drwxr-xr-x 11 root root       8192 Jan  1  1970 .
drwxr-xr-x  9 root root       4096 Feb  8 10:11 ..
-rwxr-xr-x  1 root root   27230208 Jul 20  2015 blackbird.wav
drwxr-xr-x  2 root root       8192 Jan  1  1980 BMP
drwxr-xr-x  2 root root       8192 Sep  8 15:57 EMC-8-sep
drwxr-xr-x  2 root root       8192 Sep  3 15:55 emc-testing
drwxr-xr-x  2 root root       8192 Jul 20  2015 env-chamber-testing
-rwxr-xr-x  1 root root 2466408942 Jun 13  2014 imx6rex-xubuntu-13-04-ogre-13-JUN-2014.tar
-rwxr-xr-x  1 root root  606266482 Apr  5  2014 imx6rex-xubuntu-13-04.tar
drwxr-xr-x  2 root root       8192 Feb  7 16:36 openrex
-rwxr-xr-x  1 root root    8388608 Jan  1  1980 tmp-file1
Now, you can copy a video to /media and play it. This will perform a simple USB test.

SD

You can follow a similar approach when testing SD card as used for USB memory stick. You can list the connected storage devices:
# fdisk -l
Disk /dev/mmcblk0: 7948 MB, 7948206080 bytes
81 heads, 10 sectors/track, 19165 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1              10    15523649     7761820   83  Linux

Preparing SD card for a filesystem

These steps described creating a filesystem on a new SD card for the OpenRex board. Download the filesystem, the default kernel. Be sure, you have the latest files. Copy all the files to your host machine (we use Ubuntu 9.04), the computer where you will be preparing the SD card.

Check if the card was successfully plugged in:
# dmesg | tail
[813850.046729] sd 7:0:0:0: [sdb] Write Protect is off
[813850.046732] sd 7:0:0:0: [sdb] Mode Sense: 03 00 00 00
[813850.046733] sd 7:0:0:0: [sdb] Assuming drive cache: write through
[813850.054749] sd 7:0:0:0: [sdb] 15523840 512-byte hardware sectors: (7.94 GB/7.40 GiB)
[813850.061263] sd 7:0:0:0: [sdb] Write Protect is off
[813850.061265] sd 7:0:0:0: [sdb] Mode Sense: 03 00 00 00
[813850.061267] sd 7:0:0:0: [sdb] Assuming drive cache: write through
[813850.061272]  sdb: sdb1
[813850.072395] sd 7:0:0:0: [sdb] Attached SCSI removable disk
[813850.072443] sd 7:0:0:0: Attached scsi generic sg2 type 0
Be sure your SD card is not mounted. Now run partition manager (in our case the card is mapped as /dev/sdb) and create a new partition:
# fdisk /dev/sdb

The number of cylinders for this disk is set to 19165.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): p

Disk /dev/sdb: 7948 MB, 7948206080 bytes
81 heads, 10 sectors/track, 19165 cylinders
Units = cylinders of 810 * 512 = 414720 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1       19165     7761820   83  Linux

Command (m for help): d
Selected partition 1

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-19165, default 1): 
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-19165, default 19165): 
Using default value 19165

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
Format the partition:
# mkfs.ext3 /dev/sdb1
mke2fs 1.41.4 (27-Jan-2009)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
485760 inodes, 1940455 blocks
97022 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1988100096
60 block groups
32768 blocks per group, 32768 fragments per group
8096 inodes per group
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 39 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
SD card is now prepared for copying the files. Mount it:
mount /dev/sdb1 /media/sdcard
cd /media/sdcard
Unpack the filesystem:
tar -pxvzf /home/fedevel/imx6rex-xubuntu-13-04-production-04-AUG-2014.tar
Now copy the kernel to the SD card:
cp -prv /home/fedevel/openrex/uImage .
Unmout the USB stick and the SD card is ready to work with:
cd
umount /media/sdcard
You can remove the SD card and try it in an OpenRex board.

Listing SD card files in u-boot

You can check the content of the SD card in the u-boot with this command:
mmc dev 0; ext2ls mmc 0

HDMI

To setup the HDMI monitor as a default video output (e.g. x window will be shown here) put following environment setup in u-boot. Use SD card which you have prepared in this section:
setenv bootargs 'console=ttymxc0,115200'
setenv bootcmd_mmc 'run bootargs_mmc; mmc dev 0; ext2load mmc 0 0x10800000 uImage 3850000; bootm 0x10800000'
setenv bootargs_mmc 'setenv bootargs ${bootargs} ip=dhcp root=/dev/mmcblk0p1 rootwait video=mxcfb0:dev=hdmi,1280x720M@60,if=RGB666 vmalloc=400M fbmem=28M fbcon=28M'
run bootcmd_mmc
Setup the HDMI monitor as primary when the filesystem is downloaded from network server:
setenv bootargs_nfs 'setenv bootargs ${bootargs} root=/dev/nfs rootdelay=4 ip=192.168.0.85:::255.255.255.0 nfsroot=${serverip}:${nfsroot},v3,tcp video=mxcfb0:dev=hdmi,1280x720M@60,if=RGB24 vmalloc=400M fbmem=28M fbcon=28M'
Start the X-session on HDMI from the console (Note: These commands may not work on every filesystem - tested with Ubuntu 13.04)
export DISPLAY=:0.0
startx &
Play a video on HDMI monitor:
# mplayer -vo fbdev2 /home/ubuntu/Clouds.avi
MPlayer svn r34540 (Ubuntu), built with gcc-4.7 (C) 2000-2012 MPlayer Team
mplayer: could not connect to socket
mplayer: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing /home/ubuntu/Clouds.avi.
libavformat version 53.21.1 (external)
Mismatching header version 53.19.0
AVI file format detected.
[aviheader] Video stream found, -vid 0
VIDEO:  [DIVX]  1024x576  24bpp  25.000 fps  3066.1 kbps (374.3 kbyte/s)
Clip info:
 Software: MEncoder 0.90rc5-3.2.2
Load subtitles in /home/ubuntu/
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
libavcodec version 53.35.0 (external)
Mismatching header version 53.32.2
Unsupported PixelFormat 61
Unsupported PixelFormat 53
Unsupported PixelFormat 81
Selected video codec: [ffodivx] vfm: ffmpeg (FFmpeg MPEG-4)
==========================================================================
Audio: no sound
Starting playback...
Could not find matching colorspace - retrying with -vf scale...
Opening video filter: [scale]
Movie-Aspect is 1.78:1 - prescaling to correct movie aspect.
[swscaler @ 0x2b2e0980]No accelerated colorspace conversion found from yuv420p to bgra.
[swscaler @ 0x2b2e0980]using unscaled yuv420p -> bgra special converter
VO: [fbdev2] 1024x576 => 1024x576 BGRA
V:  42.4 1062/1062 61% 25%  0.0% 0 0

Exiting... (End of file)
#
Play a video on HDMI monitor when not set as a default monitor (by u-boot). List all the mapped displays:
# cat /proc/cmdline; for fb in /sys/class/graphics/fb?; do echo "----$fb"; cat $fb/name; cat $fb/mode; cat $fb/fsl_disp_*; done
According to the listed devices, find the HDMI monitor (in this case located in fb0) and enable it (or disable):
// enable fb0 display
echo 0 > /sys/class/graphics/fb0/blank
// disable fb0 display
echo 1 > /sys/class/graphics/fb0/blank
The device, where the video will be played, needs to be specified (in this case /dev/fb0). Play a video in a loop on selected monitor:
mplayer -vo fbdev2:/dev/fb0 -vf scale -zoom -loop 0 -xy 1024 /home/ubuntu/Clouds.avi

Booting from a SATA hard drive

Plug in the SATA device with copied filesystem (you can use SD card section - it is very similar). Note that we still need an SD card for kernel image. Reset the board, stop autoboot and put these settings into u-boot:
setenv bootargs 'console=ttymxc0,115200'
setenv bootcmd_sata 'run bootargs_sata; mmc dev 0; ext2load mmc 0 0x10800000 uImage 3850000; bootm 0x10800000'
setenv bootargs_sata 'setenv bootargs ${bootargs} ip=dhcp root=/dev/sda1 rootwait video=mxcfb0:dev=hdmi,1280x720M@60,if=RGB666 vmalloc=400M fbmem=28M fbcon=28M'
run bootcmd_sata
Now you will boot up using filesystem form SATA hard drive.

Wifi PCIE mini card Intel 4965AGN

Enable WiFi support in menuconfig:
make ARCH=arm CROSS_COMPILE=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi- menuconfig
//enable PCIE support
Add a star to: make menuconfig -> System Type -> Freescale MXC Implementations ->; PCI Express support
Add a star to: make menuconfig -> Bus support -> Message Signaled Interrupts (MSI and MSI-X)
Add a star to: make menuconfig -> Bus support -> PCI Express support

//enable iwl4965 support
Add a star to: make menuconfig -> Networking support -> Wireless -> Generic IEE 802.11 Netwroking Stack (mac80211)
Add a star to: make menuconfig -> Device Drivers -> Network device support -> Wireless LAN -> Intel Wireless Wifi 4965AGN (iwl4965)

//disable FEC (the on board ethernet)
Remove the star from: make menuconfig -> Device Drivers -> Network device support -> Ethernet (10 or 100Mbit)
Compile the new kernel:
make ARCH=arm CROSS_COMPILE=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi- uImage
While new kernel is beeing compiled, run OpenRex with standard kernel supporting wired ethernet. Provide a Wifi firmware for the card:
cd
wget http://www.imx6rex.com/wp-content/uploads/2014/03/iwlwifi-4965-ucode-228.61.2.24.tar
tar -xvf iwlwifi-4965-ucode-228.61.2.24.tar
cd iwlwifi-4965-ucode-228.61.2.24
cp -prv iwlwifi-4965-2.ucode /lib/firmware/
Turn off your board. Plug in Wifi card (with plugged antenna in the ports 1 and 3). Copy new kernel with 4965AGN support to the SD card and boot up.

Check if you can see your Wifi. It should look like this:
# lspci
00:00.0 PCI bridge: Device 16c3:abcd (rev 01)
01:00.0 Network controller: Intel Corporation PRO/Wireless 4965 AG or AGN [Kedron] Network Connection (rev 61)
Configure Wifi. First create this file (be sure you are in the iwlwifi directory:
cd /home/ubuntu/iwlwifi-4965-ucode-228.61.2.24
nano wpa.conf
Insert your Wifi information there (replace ssid and psk with your Wifi settings):
network={
	ssid="wifinetworkname"
        psk="wifipassword"
}
Note: My router settings are - WPA PSK, aes ccm, WPA pre-shared key Run:
wpa_supplicant -B -Dwext -iwlan0 -cwpa.conf
Now obtain an IP address for the card. We use dhcp server:
dhclient -v -r wlan0
dhclient -v wlan0
If your router does not support dhcp, you can setup a static IP (addresses may be different for your network):
ifconfig wlan0 192.168.110.120
route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.110.1
If the ping is not working, update DNS settings. Open:
sudo nano /etc/resolv.conf
and update nameserver to:
nameserver 8.8.8.8
Try to ping google:
# ping www.google.com
PING www.google.com (62.197.198.223) 56(84) bytes of data.
64 bytes from cache.google.com (62.197.198.223): icmp_req=1 ttl=58 time=3.85 ms
64 bytes from cache.google.com (62.197.198.223): icmp_req=2 ttl=58 time=3.65 ms
64 bytes from cache.google.com (62.197.198.223): icmp_req=3 ttl=58 time=3.76 ms
This is how it should look when everything is configured properly:
# iwconfig
lo        no wireless extensions.

wlan0     IEEE 802.11abgn  ESSID:"s15as"
          Mode:Managed  Frequency:2.412 GHz  Access Point: D4:CA:6D:6B:64:57
          Bit Rate=65 Mb/s   Tx-Power=15 dBm
          Retry  long limit:7   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off
          Link Quality=70/70  Signal level=-28 dBm
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:431758  Invalid misc:1061   Missed beacon:0
We can also have check, if the IP address was obtained successfully:
# ifconfig
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:41 errors:0 dropped:0 overruns:0 frame:0
          TX packets:41 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:4376 (4.3 KB)  TX bytes:4376 (4.3 KB)

wlan0     Link encap:Ethernet  HWaddr 00:13:e8:44:2b:51
          inet addr:192.168.120.99  Bcast:192.168.120.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:413848 errors:0 dropped:0 overruns:0 frame:0
          TX packets:597649 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:205022775 (205.0 MB)  TX bytes:823018797 (823.0 MB)
Now we can try to download a file through Wifi:
# wget http://www.imx6rex.com/wp-content/uploads/2016/02/OpenRex-Picture-1400px.jpg
--1970-01-01 00:43:40--  http://www.imx6rex.com/wp-content/uploads/2016/02/OpenRex-Picture-1400px.jpg
Resolving www.imx6rex.com (www.imx6rex.com)... 54.83.203.118
Connecting to www.imx6rex.com (www.imx6rex.com)|54.83.203.118|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 299174 (292K) [image/jpeg]
Saving to: ‘OpenRex-Picture-1400px.jpg’

100%[======================================>] 299,174      409KB/s   in 0.7s

1970-01-01 00:43:41 (409 KB/s) - ‘OpenRex-Picture-1400px.jpg’ saved [299174/299174]
Disconnect the onboard ethernet and test network performance. The speed will wary depending on distance, type or number of antennae. We will use iperf tool:
sudo apt-get install iperf
Now we can test the connection:
//start iperf server, on a local computer
$ iperf -s

//start iper client on the OpenRex board
# iperf -c 192.168.10.90 -t 60 -i 10
------------------------------------------------------------
Client connecting to 192.168.10.90, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  3] local 192.168.120.99 port 59475 connected with 192.168.10.90 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  26.5 MBytes  22.2 Mbits/sec
[  3] 10.0-20.0 sec  28.6 MBytes  24.0 Mbits/sec
[  3] 20.0-30.0 sec  26.8 MBytes  22.4 Mbits/sec
[  3] 30.0-40.0 sec  26.5 MBytes  22.2 Mbits/sec
[  3] 40.0-50.0 sec  28.8 MBytes  24.1 Mbits/sec
[  3] 50.0-60.0 sec  30.1 MBytes  25.3 Mbits/sec
[  3]  0.0-60.1 sec   167 MBytes  23.4 Mbits/sec
and the other direction
//start iperf server on the OpenRex board
# iperf -s

//start iperf client on a local computer
$ iperf -c 192.168.120.99 -t 60 -i 10
------------------------------------------------------------
Client connecting to 192.168.120.99, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  3] local 192.168.10.90 port 43385 connected with 192.168.120.99 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  23.1 MBytes  19.4 Mbits/sec
[  3] 10.0-20.0 sec  22.4 MBytes  18.8 Mbits/sec
[  3] 20.0-30.0 sec  21.6 MBytes  18.1 Mbits/sec
[  3] 30.0-40.0 sec  22.1 MBytes  18.6 Mbits/sec
[  3] 40.0-50.0 sec  21.5 MBytes  18.0 Mbits/sec
[  3] 50.0-60.0 sec  22.4 MBytes  18.8 Mbits/sec
[  3]  0.0-60.3 sec    133 MBytes  18.5 Mbits/sec

Audio SGTL5000

During the testings we used Genius HS-M04SU headphones.
Access to audio mixer:
alsamixer
You can adjust Headphones gain (the first column). Play a wav file:
aplay -D hw:0,0 /home/ubuntu/blackbird.wav
Record audio from microphone
Before recording open alsamixer again and set the audio input source. Move with left arrow and find Capture Mux column. Be sure you set "MIC_IN" option. You can also adjust Microphone gain and Capture Attenuate Switch. Connect 4-pole headphones with microphone and run:
arecord -f dat -d 10 -D hw:0,0 test.wav
Play the recorded file:
aplay -f dat test.wav

I2C

We will list all the devices on the I2C1 bus:
# i2cdetect 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0.
I will probe address range 0x03-0x77.
Continue? [Y/n]
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Here are the devices which can be sees on I2C1 bus (without any external board):

7-bit addressPeripheral
0x1CCompass + Accelerometer
0x20Gyroscope
0x57EEPROM
Microcontroller which is connected to this bus, but is not visible, needs to have enabled I2C operation first. Another chip is PMIC and we removed bypass resistor during PMIC programming on this board.

We also check for peripherals on I2C2 bus:
# i2cdetect 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1.
I will probe address range 0x03-0x77.
Continue? [Y/n]
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- UU -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: 30 -- -- -- -- -- -- 37 -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- 48 -- 4a 4b -- -- -- --
50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
I2C2 devices which are available:

7-bit addressPeripheral
0x0aAudio codec
0x30HDMI monitor
0x40Humidity sensor
0x48Temperature sensor
0x50CPU HDMI EDID
I2C3 bus is dedicated for external connection, so there are no devices to be found yet.

Using this simple command we checked that all the devices placed on I2C buses are working and responding. This is just a very simple test but you are now sure that power rails for peripherals are OK and you haven't swap SCL and SDA signals. :)

EEPROM

We use a standard 24 family EEPROM memory with capacity of 2K and 8-bit programming. Simply we can test it with i2c-tool by writing data to it:
i2cset -y 0 0x57 0x00 0xfe
i2cset -y 0 0x57 0x01 0xde
i2cset -y 0 0x57 0x02 0x7e
i2cset -y 0 0x57 0x03 0x1f
We can check if we wrote the bytes correctly:
# i2cdump -y -r 0-0x0f 0 0x57
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: fe de 7e 1f ff ff ff ff ff ff ff ff ff ff ff ff    ??~????.........

Writing a file into EEPROM memory

If we would like to write a file, we can use eeprog program to do that (use this version instead which includes files support):
wget http://darkswarm.org/eeprog-0.7.6-tear5.tar.gz
tar -zxvf eeprog-0.7.6-tear5.tar.gz
cd eeprog-0.7.6-tear12/
Build the tool:
# make
cc -g -Wall -O2   -c -o eeprog.o eeprog.c
cc -g -Wall -O2   -c -o 24cXX.o 24cXX.c
cc   eeprog.o 24cXX.o   -o eeprog
We can prepare a simple text file which will be written into EEPROM:
echo 'Testing EEPROM write/read' > test_write.txt
And now we are ready to program:
# ./eeprog /dev/i2c-0 0x57 -8 -t 5 -i test_write.txt -f -w 0x00
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
  Bus: /dev/i2c-0, Address: 0x57, Mode: 8bit
  Operation: write at offset 0, Input file: test_write.txt
  Write cycle time: 5 milliseconds
  Writing test_write.txt starting at address 0x0
............................
We can read the data back:
# ./eeprog /dev/i2c-0 0x57 -8 -o test_read.txt -xf -r 0x00:0x30
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
  Bus: /dev/i2c-0, Address: 0x57, Mode: 8bit
  Operation: read 48 bytes from offset 0, Output file: test_read.txt
  Reading 48 bytes from 0x0
Now we will convert the hex file into ASCII characters and check it:
# cut -c 8- test_read.txt | xxd -r -p
Testing EEPROM write/read

Wireless Modem (Telit HE910 PCIE mini)

Enable modem support in menuconfig:
make ARCH=arm CROSS_COMPILE=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi- menuconfig

Add a star to: make menuconfig -> Device Drivers -> USB support -> USB Modem (CDC ACM) support
Install serial console e.g. picocom:
sudo apt-get install picocom
Insert SIM card and modem card. Plug the antennae into first 2 plugs from the right. Run serial console on the modem port:
picocom /dev/ttyACM3 -b 115200
Test network connection (here is a nice document with AT command examples):
AT
OK
AT+CPIN?
+CPIN: READY

OK
AT+CREG?
+CREG: 0,1

OK
AT+COPS?
+COPS: 0,0,"O2 - SK ",2

OK
Now we can test if modem is working by dialing up number 0123456789 (do not forget to use semicolon after number). Then we will hang-up:
ATD0123456789;
OK
ATH
OK
You can close the terminal by pressing Ctrl+A and then Ctrl+X.

PMIC regulator

We created a page dedicated to PMIC testing and programming.

Flashing LPC13xx microcontroller

To program LPC13xx with a firmware, follow the steps below.
1) Download the ISP handler software and unpack it:
wget https://github.com/FEDEVEL/openrex-nxp-lpc13xx/archive/LPC1347.zip
unzip LPC1347.zip
cd openrex-nxp-lpc13xx-LPC1347/
2) Now you can test programming the microcontroller by using a simple script (be sure binary is located in the folder):
./openrex-isp-handler.sh LPC1347-userLED.bin
Go to our page about microcontroller programming and testing for more info. There you can also find how to prepare your own binary file.

Sensors

Here you can find information how we have tested all sensor which are part of the OpenRex board. To simply test all the sensors at once run this script:
# wget http://www.imx6rex.com/download/released-files/openrex/v1i1/firmware/openrex-sensors.sh
# chmod 777 openrex-sensors.sh
# ./openrex-sensors.sh
OpenRex Sensors Measurements
                       TMP101   CPU HTC21
 Temperature    [C]   :    34    34    54
 Rel. humidity  [per] :                22
                            X     Y     Z
 Angular rate   [dps] :    -3     5     0
 Acceleration   [mg]  :   -23    10   987
 Magnetic field [uT]  :   -42     8  1624

Temperature sensor

Reading a temperature from TMP101 sensor, which we used, is very easy. The device consists of only four registers: 2 Bytes register for temperature value (address 0x00), configuration register (0x01) and 2x 2 Bytes register for setting up minimum (0x03) and maximum (0x02) alert threshold. Simply we can read from first register (use w for word readout):
i2cget 1 0x48 0x00 w
We got 0x002B and converting to decimal it is 43°C.

Now we are using default 9-bit resolution only. To increase the precision up to 0.0625°C, we can setup 12-bit ADC operation. We will set to one bits R1 a R0 in the configuration register:
# i2cget -y 1 0x48 0x01
0x80
# i2cset -y 1 0x48 0x01 0xE0
# i2cdump -y -r 0-0x07 1 0x48 w
     0,8  1,9  2,a  3,b  4,c  5,d  6,e  7,f
00: 2035 ffe0 004b 0050 XXXX XXXX XXXX XXXX
Temperature register now stores 12-bit value 0x2035 and converted it is 53.125 °C . Now the calculation is a bit more complex: 0x35->53°C plus decimal number 0.125 (fraction of 0x2 from 0xF).

To simple read the precision format directly in °C you can use a command created by Fabio:
i2cget -f -y 1 0x48 0x00 w | mawk '{printf("%.1f\n", (a=(("0x"substr($1,5,2)substr($1,3,1))*0.0625))>128?a-256:a)}'
Note that the temperature has risen because of stressapptest running. In comparison for high performance tasks CPU temperature (76°C) was 25°C higher than the temperate close to an edge (52.5°C - where the sensor is located).

Humidity sensor

SHT21 humidity and temperature sensor which is placed on OpenRex, uses a direct I2C measurement. After we send a request, we need to read data bytes which are directly being transmitted from the sensor (they are not stored in any accessible register). Because the measurement is 2 bytes long, we could not use i2c-tools for initial testing (i2cget supports word mode read only if register address is specified).

We are going to access humidity sensor using Linux driver. Kernel 3.0.35 already includes driver file which we need (located at drivers/hwmon/sht21.c). We just to mark the driver to be compiled. Go to arch/arm/configs/imx6_defconfig and set
CONFIG_SENSORS_SHT21=y
or you can setup it through menuconfig:
make ARCH=arm CROSS_COMPILE=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi- menuconfig
//enable SHT21 support
Add a star to: make menuconfig -> Device Drivers  -> Hardware Monitoring support -> Sensiron humidity and temperature sensors. SHT21 and compat.
Now we need to add the sensor into i2c_board_info structure (located in file arch/arm/mach-mx6/board-mx6q_sabresd.c in our case):
static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
	{
		I2C_BOARD_INFO("sht21", 0x40),
	},
Complile kernel and start the board. If we now run i2cdetect, we can see that the humidity sensor address is marked as under use:
# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- UU -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: 30 -- -- -- -- -- -- 37 -- -- -- -- -- -- -- --
40: UU -- -- -- -- -- -- -- 48 -- 4a 4b -- -- -- --
50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Now we can read the measurement:
# cat /sys/bus/i2c/devices/1-0040/humidity1_input
25288
# cat /sys/bus/i2c/devices/1-0040/temp1_input
29223
After conversion we got 42% relative humidity and 31.5 °C. To avoid computing the values, we can use for example this simple script:
#!/bin/bash
# OpenRex SHT21 humidity sensor reading script

hum=$( cat /sys/bus/i2c/devices/1-0040/humidity1_input )
temp=$( cat /sys/bus/i2c/devices/1-0040/temp1_input )

hum_result=0
temp_result=0

hum_result=$(echo "-6+125*$hum/65536" | bc -l)
temp_result=$(echo "-46.85+175.72*$temp/65536" | bc -l)

echo "SHT21 measurement on "$(date +\%Y/\%m/\%d-\%T)
printf "Rel. humidity : %4.2f %%\n" $hum_result
printf "Temperature   : %4.2f C\n" $temp_result
After we save it and setup a permission, we can try to read data once more:
# nano sht21-read.sh
# chmod 777 sht21-read.sh
# ./sht21-read.sh
SHT21 measurement on 2016/02/17-18:26:47
Rel. humidity : 41.17 %
Temperature   : 32.60 C

Gyroscope

As a gyroscope we are using FXAS21002. Before we can obtain data from the sensor we need to enable it first. We will put the gyroscope into the active mode:
i2cset -y 0 0x20 0x13 0x02
Now we can simply read all the registers (measurement are stored in bytes 1 to 6):
# i2cdump -y -r 0-0x15 0 0x20
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: ff ff e3 00 48 ff f5 9b 00 00 00 08 d7 00 00 00    ..?.H.??...??...
10: 00 01 2f 02 00 00
To print the measurement in more friendly way, we created a simple script. We read the registers, converted 2's complement if needed and displayed the values in degrees per second:
#!/bin/bash
# Gyroscope sensor reading script

# setup gyroscope settings
i2cset -y 0 0x20 0x13 0x02 # set active state
i2cset -y 0 0x20 0x0D 0x00 # set full-scale range
i2cset -y 0 0x20 0x15 0x00 # disable double range selection
nom_sens=62.5 # nominal sensitivity for 2000 dps range

echo "Gyroscope real-time measurement"
echo "Angular rate [dps]:    X    Y    Z"

while true
do
	# read gyroscope measurements
	gyro_x=$(( $( i2cget -f -y 0 0x20 0x01 ) << 8 | $( i2cget -f -y 0 0x20 0x02 ) ))
	gyro_y=$(( $( i2cget -f -y 0 0x20 0x03 ) << 8 | $( i2cget -f -y 0 0x20 0x04 ) ))
	gyro_z=$(( $( i2cget -f -y 0 0x20 0x05 ) << 8 | $( i2cget -f -y 0 0x20 0x06 ) ))

	# convert 2's complement if needed
	if [ "$gyro_x" -gt 32768 ]; then
	  gyro_x=$(echo "(65536-$gyro_x)*(-1)" | bc -l)
	fi
	if [ "$gyro_y" -gt 32768 ]; then
	  gyro_y=$(echo "(65536-$gyro_y)*(-1)" | bc -l)
	fi
	if [ "$gyro_z" -gt 32768 ]; then
	  gyro_z=$(echo "(65536-$gyro_z)*(-1)" | bc -l)
	fi

	# convert values to degrees per second
	gyro_x=$(echo "$gyro_x*$nom_sens/1000" | bc -l)
	gyro_y=$(echo "$gyro_y*$nom_sens/1000" | bc -l)
	gyro_z=$(echo "$gyro_z*$nom_sens/1000" | bc -l)
	
	printf "                    %4.0f %4.0f %4.0f \r" $gyro_x $gyro_y $gyro_z
	sleep 0.1
done
Now we can save the script and run it:
nano orx-gyro.sh
chmod 777 orx-gyro.sh
./orx-gyro.sh
When you will be moving with your board you can see the change in angular momentum. In this example the board was rotating while touching on the board (in z axis):
Gyroscope real-time measurement
Angular rate [dps]:    X    Y    Z
                      -3    5  109

Accelerometer & compass

Accelerometer sensor FXOS8700CQ, which we selected, has similar register structure as our gyroscope. Thus we will use the same approach and create a script.
At first we put the device into active state and then enabled hybrid mode where both sensors are active. Then we read the data and updated its format:
#!/bin/bash
# Accelerometer & magnetometer sensor reading script

# set active mode
i2cset -y 0 0x1C 0x02A 0x01
# enable both sensors
i2cset -y 0 0x1C 0x05B 0x03

acc_sens=0.244 # nominal sensitivity for 2g accelerometer mode
mag_sens=0.1 # nominal sensitivity for magnetometer

echo "Accelerometer and magnetometer real-time measurement"
echo "                         X    Y    Z"

while true
do
	# read 14-bit acceleration measurements
	acc_x=$(( $( i2cget -f -y 0 0x1C 0x01 ) << 6 | $( i2cget -f -y 0 0x1C 0x02 ) >> 2))
	acc_y=$(( $( i2cget -f -y 0 0x1C 0x03 ) << 6 | $( i2cget -f -y 0 0x1C 0x04 ) >> 2))
	acc_z=$(( $( i2cget -f -y 0 0x1C 0x05 ) << 6 | $( i2cget -f -y 0 0x1C 0x06 ) >> 2))
	
	# read 16-bit magnetic measurements	
	mag_x=$(( $( i2cget -f -y 0 0x1C 0x01 ) << 8 | $( i2cget -f -y 0 0x1C 0x02 ) ))
	mag_y=$(( $( i2cget -f -y 0 0x1C 0x03 ) << 8 | $( i2cget -f -y 0 0x1C 0x04 ) ))
	mag_z=$(( $( i2cget -f -y 0 0x1C 0x05 ) << 8 | $( i2cget -f -y 0 0x1C 0x06 ) ))
	
	# convert 2's complement if needed
	if [ "$acc_x" -gt 8192 ]; then
	  acc_x=$(echo "(16384-$acc_x)*(-1)" | bc -l)
	fi
	if [ "$acc_y" -gt 8192 ]; then
	  acc_y=$(echo "(16384-$acc_y)*(-1)" | bc -l)
	fi
	if [ "$acc_z" -gt 8192 ]; then
	  acc_z=$(echo "(16384-$acc_z)*(-1)" | bc -l)
	fi
	
	if [ "$mag_x" -gt 32768 ]; then
	  mag_x=$(echo "(65536-$mag_x)*(-1)" | bc -l)
	fi
	if [ "$mag_y" -gt 32768 ]; then
	  mag_y=$(echo "(65536-$mag_y)*(-1)" | bc -l)
	fi
	if [ "$mag_z" -gt 32768 ]; then
	  mag_z=$(echo "(65536-$mag_z)*(-1)" | bc -l)
	fi

	# convert values
	acc_x=$(echo "$acc_x*$acc_sens" | bc -l)
	acc_y=$(echo "$acc_y*$acc_sens" | bc -l)
	acc_z=$(echo "$acc_z*$acc_sens" | bc -l)
	
	mag_x=$(echo "$mag_x*$mag_sens" | bc -l)
	mag_y=$(echo "$mag_y*$mag_sens" | bc -l)
	mag_z=$(echo "$mag_z*$mag_sens" | bc -l)
	
	printf " Acceleration [mg]:   %4.0f %4.0f %4.0f \n" $acc_x $acc_y $acc_z
	printf " Magnetic Field [uT]: %4.0f %4.0f %4.0f \r" $mag_x $mag_y $mag_z
	sleep 0.1
	tput cuu 1
done
Now we can test the sensors:
# nano orx-acc-mag.sh
# chmod 777 orx-acc-mag.sh
# ./orx-acc-mag.sh
Accelerometer and magnetometer real-time measurement
                         X    Y    Z
 Acceleration [mg]:    -26   11  993
 Magnetic Field [uT]:  -38    8 1627

IR Receiver

On our board we are using a 3-pin infrared receiver TSOP38238. With this simple solution you can control the system with the vast majority of the remote controllers (which use 38kHz carrier frequency).

Before we can try it, we need to add a support into the kernel. We will follow a similar approach as it was used for Raspberry Pi boards (this tutorial also describes more details about building an IR software support). We will use an i.MX6 modification of this RPi driver made by Stephan and Rene. You can have a look on the modification which we have done on our Github.

As the first step we will add a new driver file into the Linux kernel. Open your Ubuntu machine, where you were compiling the source files and navigate to the main directory of OpenRex Linux.
Download driver file and save it as drivers/staging/lirc/lirc_openrex.c. Alternatively you can use wget and download it directly:
wget http://www.imx6rex.com/download/released-files/openrex/v1i1/firmware/lirc_openrex.c -P drivers/staging/lirc/
If you will use an external sensor connected to a different pad, you need to update the harcoded GPIO setting in the driver. Our IR receiver is connected to GPIO2_IO11:
#define MYGPIO  IMX_GPIO_NR(2, 11)
Now we need to include this driver into LIRC Makefile. Open it (located at drivers/staging/lirc/Makefile) and add line:
obj-$(CONFIG_LIRC_OPENREX)	+= lirc_openrex.o
As the next step we will add a new configuration option into drivers/staging/lirc/Kconfig file:
config LIRC_OPENREX
       tristate "Homebrew GPIO Port Receiver for OpenRex"
       depends on LIRC
       help
       Driver for Homebrew GPIO Port Receiver for the OpenRex
As the last thing we need to enable the IR signal usage. Go to mx6q_sabresd_pads structure located in arch/arm/mach-mx6/board-mx6q_sabresd.h file and add here
	// IR RECEIVER
	MX6Q_PAD_SD4_DAT3__GPIO_2_11,
If you will use a different pin, have a look into the file arch/arm/mach-mx6/board-mx6q_sabresd.c. Check if your signal has not been already use by the kernel.

Now we need to select this new driver to be compiled into the kernel. Go to menuconfig and update:
make ARCH=arm CROSS_COMPILE=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi- menuconfig
Add a star to: make menuconfig -> Device Drivers -> Multimedia support -> Remote controller adapters
Add a star to: make menuconfig -> Device Drivers -> Multimedia support -> Remote controller adapters -> Compile Remote Controller keymap modules (NEW)
Add a star to: make menuconfig -> Device Drivers -> Multimedia support -> Remote controller adapters -> Enable IR to LIRC bridge (NEW)

Add a star to: make menuconfig -> Device Drivers -> Staging drivers
Add a star to: make menuconfig -> Device Drivers -> Staging drivers -> Linux Infrared Remote Control IR receiver/transmitter drivers (NEW)
Add a star to: make menuconfig -> Device Drivers -> Staging drivers -> Linux Infrared Remote Control IR receiver/transmitter drivers (NEW) -> Homebrew GPIO Port Receiver for OpenRex (NEW)
Recompile the driver and run the board with it. You should see new LIRC driver beeing loaded as the board boots. You can check it with dmesg:
# dmesg | grep "LIRC" -i
lirc_dev: IR Remote Control driver registered, major 251
IR LIRC bridge handler initialized
lirc_openrex lirc_openrex.0: lirc_dev: driver lirc_openrex registered at minor = 0
lirc_openrex: driver registered!
lirc_openrex: using irq 299
lirc_openrex: auto-detected active low receiver on GPIO pin 43
Now we need to install packages which we help us with interfering with the receiver. During the configuration use "Simple IR diode (EXPERIMENTAL)" Custom as a receiver and "None" for transmitter:
apt-get install lirc liblircclient-dev
We can finally test the receiver. Run mode2 command and press any key on you remote controller. You will see a sequence starting like this:
# mode2 -d /dev/lirc0
space 4650628
pulse 9091
space 4441
pulse 629
space 503
Our infrared receiver is working. We can now assign a function to the particular keys. Run
irrecord -n -d /dev/lirc0 test_remote.conf
and follow the instructions. For demonstration we configured three color buttons. Now we can apply our settings and catch the pressed buttons:
rm /var/run/lirc/lircd.pid
lircd -d /dev/lirc0 test_remote.conf
irw
Here is output example:
0000000001fe30cf 00 red test_remote.conf
0000000001fe30cf 01 red test_remote.conf
0000000001feb04f 00 green test_remote.conf
0000000001fe708f 00 yellow test_remote.conf
0000000001feb04f 00 green test_remote.conf
0000000001feb04f 01 green test_remote.conf
0000000001feb04f 02 green test_remote.conf
0000000001feb04f 03 green test_remote.conf
From this point you can build you own application using remote control. :)

Read CPU Temperature

cat /sys/devices/virtual/thermal/thermal_zone0/temp

Read CPU Frequency

# cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq 
396000
# cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq 
996000

Read / Write MDIO (PHY Registers)

This application can read / write PHY registers. First, download & compile it:
cd
mkdir tmp
cd tmp
git clone https://github.com/FEDEVEL/phytool.git
cd phytool
make
Example: Standard register read (simple read):
#read eth0 placed on PHY address 3 and register 2 (PHY Identifier, should be 0x0022)
root@ubuntu-imx6:~/tmp/phytool# ./phytool read eth0/3/2
0x0022
root@ubuntu-imx6:~/tmp/phytool#
Example: Vendor-Specific Register Read:
#reads: Eth0, PHY address 3, Device address 0x2, Register Address 0x06 (KSZ9031 RGMII TX Data Pad Skew)
./phytool write eth0/3/0x0D 0x02
./phytool write eth0/3/0x0E 0x06
./phytool write eth0/3/0x0D 0x4002
./phytool read eth0/3/0x0E
Example: Vendor-Specific Register Write:
#writes: Eth0, PHY address 3, Device address 0x2, Register Address 0x06 = 0x0 (KSZ9031 RGMII TX Data Pad Skew)
./phytool write eth0/3/0x0D 0x02
./phytool write eth0/3/0x0E 0x06
./phytool write eth0/3/0x0D 0x4002
./phytool write eth0/3/0x0E 0x0