Here is a step-by-step guide to boot up the IB113:
a. Based on the order, the (Android) or (Linux OS) will be preloaded in the
IB113’s eMMC. System can be booted up with HDMI (by default) and power
input ready.
b. To use the root/ serial port debug function, please check Chapter 4.2.1 (COM1
debug cable setup) information.
c. To boot up with a different LVDS panel, please refer to Chapter 4.2.2.
d. To make a recovery SD card (for IB113 advanced user only), please refer to
Chapter 4.
Note: different LVDS panels have different customization; please check with your sales
contact.
e. For advanced users who are building their own products, please refer to
Chapter 5.
f. For special HW/SW/ panel customization requests or assistance, please check
with Ibase sales dept.
4
IB113
TABLE OF CONTENTS
This page is intentionally left blank.Quick Start Guide ............................................................ 2
ARM® Cortex™-A9 is a trademark of ARM Holdings, plc.
Android, name, logo, and other Android trademarks are property of Google Inc.
Linux, trademarks or marks include all trade and service marks and logos owned
by the Linux Foundation.
All other product names or trademarks are properties of their respective owners.
6
IB113
1. Introduction
1.1. IB113 Introduction
IB113 is a 3.5" Disk-Size SBC w/ ARM Base Freescale i.MX6 Cortex-A9
800Mhz CPU. IB113 fulfill industrial ambient operating temperature from -40
℃ to +85℃. The device offers 3D graphics acceleration, while also supporting
numerous peripherals, including RS232/422/485, CAN, USB, USB OTG, 1st/2nd LAN
ports, SATA, R/C touch interfaces, that are well suited for industrial applications.
All components are selected from industrial grade parts for wide-temperature
environment operation.
[Important] Please check the jumpers, DIP, buttons and switches on
IB113 before doing the panel connection and boot up.
Jumpers are used on IB113 to select various settings and features according
to your needs and applications. Contact your supplier if you have doubts
about the best configuration for your needs. The following lists the
connectors on IB113 and their respective functions.
Jumper Locations on IB113
Top Side
12
IB113
SW1
Boot From
10101010
SD
01100110
EMMC
Mode
JP9
RS232
2-4 Short
3-5 Short
RS422
3-5 Short
4-6 Short
RS485
1-3 Short
4-6 Short
2
1
SW1: System Boot Configuration (factory use only)
JP9: COM2 RS232, RS422, RS485 Selection
Default setting is RS232 mode. JP9 setting for COM2.
Basically, the IB113 is preloaded O.S (Android / Linux) into eMMC by default.
Connect the HDMI with IB113, and 9~36V power directly.
3.1. Make a Recovery SD Card (for advanced user only)
For advanced user who has Ibase standard image file, refer to this chapter to
prepare the recovery boot-up SD card. Ibase optionally provides 8” LVDS panel
for users to prepare the software application pre-development easily under Linux
/ Android platform.
Preparing the Recovery SD card to install the Linux/ Android image into eMMC
Note: all data in the eMMC will be erased.
-- for IB113
Please download the Recovery SD card’s image by FTP in advance.
ii. Install and run the Formatting Tool on your machine
iii. Set "FORMAT SIZE ADJUSTMENT" option to "ON" in the "Options"
menu
iv. Check that the SD card you inserted matches the one selected by the
Tool
v. Click the “Format” button
3. Download the target operating system image from the DVD/ or FTP
(Descripted in previous page)
4. Download the Win32DiskImager from
http://sourceforge.net/projects/win32diskimager/ and use it to restore the
target operating system.
And then, flash the Android/ Linux image into your SD card in your PC
(Windows).
6. Please check the boot device switch and make sure it can boot from SD Card
by
setenv xres 1024
setenv yres 768
run setlvds18
run setlvds
setenv xres 1024
setenv yres 768
run setlvds24
run setlvds
setenv xres 1920
setenv yres 1080
run setlvds24
run setlvds2
setenv xres 1024
setenv yres 768
run setlvds18
run dul1
3.2.2. Display setting command For Linux and Android
With the debug port, follow the reference command examples to help you to be
familiar with display modification. (for advanced software engineers only)
Command to set HDMI output (default is auto-detect):
Command to assign resolution set HDMI output:
Command to set LVDS output to 1024x768, 18bit:
Command to set LVDS output to 1024x768, 24bit:
Command to set LVDS output to 1920x1080 with dual-link LVDS, 24bit:
Command to set LVDS0, LVDS1 and HDMI output, LVDS is 1024x768, 18bit:
32
IB113
setenv xres 1024
setenv yres 768
run setlvds18
run dul1
setenv xres 1920
setenv yres 1080
run setlvds24
run dul2
setenv video ‘setenv vdoset video=mxcfb1:off video=mxcfb2:off video=mxcfb3:off
video=mxcfb0:dev=ldb,${xres}x${yres}M@60,if=${lclr},bpp=32 ldb=sin0’
Dual display (same frame) output mode 1. (only work in Android).
Command to set LVDS0 and LVDS1 (same frame), HDMI output with auto-detect, LVDS is
1024x768, 18bit:
Dual display (same frame) output mode 2, (only work in Android).
Command to set dual-link LVDS, HDMI output with auto-detect, LVDS is 1920x1080, 24bit:
*Note:
- If the resolution of LVDS panels is =< 1366x768, both LVDS0 & LVDS1 will get the same frame
from GPU (clone mode) by default.
- If the user wants to try extended desktop mode output in LVDS0+LVDS1 panels under Linux,
please change the parameter in u-boot:
- If the resolution of LVDS panel is > 1366 x 768, Dual-Link LVDS mode will be activated
automatically by default. (ex.1920x1080),
- For any other configurations, please contact iBASE sales, or FAE support.
4. BSP User Guide ( for advanced software engineer only )
This Chapter is an example only, and it is mainly for advanced SW engineers to build the image for IBASE ARM PCB. Any other modification, new device or driver should be handled carefully.
4.1. Building BSP Source
4.1.1. Preparation
Suggested Host Platform: Ubuntu 10.04, 12.04, 14.04, x86 and x64 version
Note: ** To simplify build process, please run build/installation with root on your x86 host PC.
**
4.1.2. Installing Toolchain
** Before download the toolchain and BSP code, please install xz-utils to unpackage. **
Download and extract freescale toolchain (gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12.tar.xz)
# assume your toolchain file is located at root home dir,
“gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12.tar.xz” file in “Downloads” folder:
** read words is your command **
sudo su
cd ~
mkdir -p ~/IB113_BSP ~/IB113_BSP/linux
cd ~/IB113_BSP/linux
tar Jxf gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12.tar.xz
34
IB113
root@u1004x64:~# cd ~/IB113_BSP/linux
root@u1004x64:~/IB113_BSP/linux# tar Jxf ~/Downloads/IB113bsp_linux_uboot_src_141105.tar.xz
root@u1004x64:~/IB113_BSP/linux# cd uboot-imx
root@u1004x64:~/IB113_BSP/linux/uboot-imx# ./mklnx-uboot.sh….
/root/IB113_BSP/linux/uboot-imx/../fsl-linaro-toolchain/bin/arm-fsl-linux-gnueabi-objcopy --gap-fill=0xff -O
binary u-boot u-boot.bin
image size 198KiB
198+0 records in
198+0 records out
202752 bytes (203 kB) copied, 0.000471782 s, 430 MB/s
197+1 records in
197+1 records out
202448 bytes (202 kB) copied, 0.00698078 s, 29.0 MB/s
root@u1004x64:~/IB113_BSP/linux/uboot-imx#
4.1.3. Building u-boot
# u-boot source file is “IB113bsp_linux_uboot_src_XXXXXX.tar.xz”, XXXXXX is release date,
assume u-boot source file is in /root/Downloads/ folder:
cd ~/IB113_BSP/linux/
tar Jxf ~/Downloads/IB113bsp_linux_uboot_src_141105.tar.xz
cd uboot-imx/
./mklnx-uboot.sh
Note: **** If the building process is successful, u-boot.bin file will be generated. ****
root@u1004x64:~# cd ~/IB113_BSP/linux
root@u1004x64:~/IB113_BSP/linux# tar Jxf ~/Downloads/IB113bsp_linux_kernel_src_141105.tar.xz
root@u1004x64:~/IB113_BSP/linux# cd linux-3.0.35
root@u1004x64:~/IB113_BSP/linux/linux-3.0.35#./mx.sh ib113_defconfig;./mx.sh….
image size 7MiB
7+0 records in
7+0 records out
7340032 bytes (7.3 MB) copied, 0.00890854 s, 824 MB/s
13028+0 records in
13028+0 records out
6670336 bytes (6.7 MB) copied, 0.160881 s, 41.5 MB/s
root@u1004x64:~/IB113_BSP/linux/linux-3.0.35# ./mx.sh modules_install…
DEPMOD 3.0.35
Warning: you may need to install module-init-tools
See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt…
root@u1004x64:~/IB113_BSP/linux/linux-3.0.35#
4.1.4. Building kernel
# kernel source file is “IB113bsp_kernel_uboot_src_XXXXXX.tar.xz”, XXXXXX is release date,
assume kernel source file is in /root/Downloads/ folder:
cd ~/IB113_BSP/linux/
tar Jxf ~/Downloads/IB113bsp_linux_kernel_src_141105.tar.xz
cd linux-3.0.35/
./mx.sh ib113_defconfig;./mx.sh
./mx.sh modules_install
** If the building process is successful, zImage file will be generated under arch/arm/boot
directory. **
** kernel module files are installed at ~/IB113_BSP/linux/rootfs/ **
36
IB113
root@u1004x64:~/IB113_BSP/linux/ramfs# tree lib/modules/3.0.35/
lib/modules/3.0.35/
root@u1004x64:~/IB113_BSP/linux# ./fimg.sh
image size 7MiB
7+0 records in
7+0 records out
7340032 bytes (7.3 MB) copied, 0.00492305 s, 1.5 GB/s
13028+0 records in
13028+0 records out
6670336 bytes (6.7 MB) copied, 0.128988 s, 51.7 MB/s
root@u1004x64:~/IB113_BSP/linux#
4.1.5. Build RAMdisk image (option.)
** RAMdisk image depend on need, not necessary **
After kernel module files install into ~/IB113_BSP/linux/rootfs/, copy kernel modules define, and
kernel module files into ~/IB113_BSP/linux/ramfs/, file struct same as ~/IB113_BSP/linux/rootfs/
Example:
Todo packaged RAMdisk files into RAMdisk cpio image “~/IB113_BSP/linux/IMG/ramfs.bin”:
./img.sh
Todo packaged RAMdisk ans zImage images into kernel image for u-boot using
“~/IB113_BSP/linux/IMG/113linux.img”:
root@u1004x64:~/IB113_BSP/linux/# tar Jxf ~/Downloads/IB113bsp_rootfs_linux_141105.tar.xz –C
~/IB113_BSP/linux/
root@u1004x64:~/IB113_BSP/linux/# cd IMG
root@u1004x64:~/IB113_BSP/linux/IMG/# ./113linux.sh /dev/sdf…
iBASElinux: 155204/163840 files (0.1% non-contiguous), 536524/655360 blocks
resize2fs 1.42.9 (4-Feb-2014)
Resizing the filesystem on /dev/sdf2 to 1044223 (4k) blocks.
The filesystem on /dev/sdf2 is now 1044223 blocks long.
Completed.
4.1.6. Install Linux to SD card
i. Insert an empty SD card with at least 8GB size and put it in a card reader
connecting to your host PC. Assume your SD card is /dev/sdf on your x86 host
PC
ii. This installer script will destroy every data in your SD card, please make sure file
already backup that you needed.
iii. Linux rootfs archive file is “IB113bsp_rootfs_linux_XXXXXX_installer.tar.xz”,
XXXXXX is release date. Assume this file is in /root/Downloads/
SDcard map
tar Jxf ~/Downloads/IB113bsp_rootfs_linux_141105.tar.xz –C ~/IB113_BSP/linux/
** any message from e2fsck are generate by resize, please ignore it**
38
IB113
4.1.7. Booting with your SD card
(For advance software users only)
Put SD card in your board and insert special COM port dongle to boot from SD. Connect a debug
cable to debug port with serial port 115200/N/8/1 setting on your PC’s serial port program such
hyperterminal/teraterm. Connect HDMI monitor. Power on and you will see u-boot prompt.
If you want change to other monitor (or display panel) type, please reference section 3.2.2 to
setting video output command for want.
After that, prepare your LCD, power off and power on again.
Reading / writing i2c
i2cget.c
/*
i2cget.c - A user-space program to read an I2C register.
Copyright (C) 2005-2012 Jean Delvare <jdelvare@suse.de>
Based on i2cset.c:
Copyright (C) 2001-2003 Frodo Looijaard <frodol@dds.nl>, and
Mark D. Studebaker <mdsxyz123@yahoo.com>
Copyright (C) 2004-2005 Jean Delvare
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
static void help(void)
{
fprintf(stderr,
"Usage: i2cget [-f] [-y] I2CBUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]\n"
" I2CBUS is an integer or an I2C bus name\n"
" ADDRESS is an integer (0x03 - 0x77)\n"
" MODE is one of:\n"
" b (read byte data, default)\n"
" w (read word data)\n"
" c (write byte/read byte)\n"
" Append p for SMBus PEC\n");
exit(1);
}
static int check_funcs(int file, int size, int daddress, int pec)
{
unsigned long funcs;
/* check adapter functionality */
5. Reference Code
5.1. How to use I2C in Linux
40
IB113
if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
fprintf(stderr, "Error: Could not get the adapter "
"functionality matrix: %s\n", strerror(errno));
return -1;
}
case I2C_SMBUS_BYTE_DATA:
if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
fprintf(stderr, MISSING_FUNC_FMT, "SMBus read byte");
return -1;
}
break;
case I2C_SMBUS_WORD_DATA:
if (!(funcs & I2C_FUNC_SMBUS_READ_WORD_DATA)) {
fprintf(stderr, MISSING_FUNC_FMT, "SMBus read word");
return -1;
}
break;
}
if (pec
&& !(funcs & (I2C_FUNC_SMBUS_PEC | I2C_FUNC_I2C))) {
fprintf(stderr, "Warning: Adapter does "
"not seem to support PEC\n");
}
return 0;
}
static int confirm(const char *filename, int address, int size, int daddress,
int pec)
{
int dont = 0;
fprintf(stderr, "WARNING! This program can confuse your I2C "
"bus, cause data loss and worse!\n");
/* Don't let the user break his/her EEPROMs */
if (address >= 0x50 && address <= 0x57 && pec) {
fprintf(stderr, "STOP! EEPROMs are I2C devices, not "
"SMBus devices. Using PEC\non I2C devices may "
"result in unexpected results, such as\n"
"trashing the contents of EEPROMs. We can't "
"let you do that, sorry.\n");
return 0;
}
if (size == I2C_SMBUS_BYTE && daddress >= 0 && pec) {
fprintf(stderr, "WARNING! All I2C chips and some SMBus chips "
"will interpret a write\nbyte command with PEC as a"
"write byte data command, effectively writing a\n"
"value into a register!\n");
dont++;
}
fprintf(stderr, "I will read from device file %s, chip "
fprintf(stderr, "Continue? [%s] ", dont ? "y/N" : "Y/n");
fflush(stderr);
if (!user_ack(!dont)) {
fprintf(stderr, "Aborting on user request.\n");
return 0;
}
return 1;
}
int main(int argc, char *argv[])
{
char *end;
int res, i2cbus, address, size, file;
int daddress;
char filename[20];
int pec = 0;
int flags = 0;
int force = 0, yes = 0, version = 0;
/* handle (optional) flags first */
while (1+flags < argc && argv[1+flags][0] == '-') {
switch (argv[1+flags][1]) {
case 'V': version = 1; break;
case 'f': force = 1; break;
case 'y': yes = 1; break;
default:
fprintf(stderr, "Error: Unsupported option "
"\"%s\"!\n", argv[1+flags]);
help();
exit(1);
}
flags++;
}
if (version) {
fprintf(stderr, "i2cget version %s\n", VERSION);
exit(0);
}
if (argc < flags + 3)
help();
i2cbus = lookup_i2c_bus(argv[flags+1]);
if (i2cbus < 0)
help();
address = parse_i2c_address(argv[flags+2]);
if (address < 0)
help();
i2cset.c
/*
i2cset.c - A user-space program to write an I2C register.
Copyright (C) 2001-2003 Frodo Looijaard <frodol@dds.nl>, and
Mark D. Studebaker <mdsxyz123@yahoo.com>
Copyright (C) 2004-2012 Jean Delvare <jdelvare@suse.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
static void help(void)
{
fprintf(stderr,
"Usage: i2cset [-f] [-y] [-m MASK] [-r] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]\n"
" I2CBUS is an integer or an I2C bus name\n"
" ADDRESS is an integer (0x03 - 0x77)\n"
" MODE is one of:\n"
" c (byte, no value)\n"
" b (byte data, default)\n"
" w (word data)\n"
" i (I2C block data)\n"
" s (SMBus block data)\n"
" Append p for SMBus PEC\n");
exit(1);
}
static int check_funcs(int file, int size, int pec)
{
unsigned long funcs;
/* check adapter functionality */
if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
fprintf(stderr, "Error: Could not get the adapter "
"functionality matrix: %s\n", strerror(errno));
return -1;
}
switch (size) {
case I2C_SMBUS_BYTE:
if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE)) {
fprintf(stderr, MISSING_FUNC_FMT, "SMBus send byte");
return -1;
}
break;
case I2C_SMBUS_BYTE_DATA:
if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
fprintf(stderr, MISSING_FUNC_FMT, "SMBus write byte");
return -1;
}
break;
case I2C_SMBUS_BLOCK_DATA:
if (!(funcs & I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)) {
fprintf(stderr, MISSING_FUNC_FMT, "SMBus block write");
return -1;
}
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
if (!(funcs & I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
fprintf(stderr, MISSING_FUNC_FMT, "I2C block write");
return -1;
}
break;
}
if (pec
&& !(funcs & (I2C_FUNC_SMBUS_PEC | I2C_FUNC_I2C))) {
fprintf(stderr, "Warning: Adapter does "
"not seem to support PEC\n");
}
return 0;
}
static int confirm(const char *filename, int address, int size, int daddress,
int value, int vmask, const unsigned char *block, int len,
int pec)
{
int dont = 0;
fprintf(stderr, "WARNING! This program can confuse your I2C "
"bus, cause data loss and worse!\n");
if (address >= 0x50 && address <= 0x57) {
fprintf(stderr, "DANGEROUS! Writing to a serial "
"EEPROM on a memory DIMM\nmay render your "
"memory USELESS and make your system "
"UNBOOTABLE!\n");
dont++;
}
fprintf(stderr, "I will write to device file %s, chip address "
"0x%02x, data address\n0x%02x, ", filename, address, daddress);
if (size == I2C_SMBUS_BYTE)
fprintf(stderr, "no data.\n");
else if (size == I2C_SMBUS_BLOCK_DATA ||
size == I2C_SMBUS_I2C_BLOCK_DATA) {
int i;
/* check for command/mode */
if (argc == flags + 4) {
/* Implicit "c" */
size = I2C_SMBUS_BYTE;
} else if (argc == flags + 5) {
/* "c", "cp", or implicit "b" */
if (!strcmp(argv[flags+4], "c")
|| !strcmp(argv[flags+4], "cp")) {
46
IB113
size = I2C_SMBUS_BYTE;
pec = argv[flags+4][1] == 'p';
} else {
size = I2C_SMBUS_BYTE_DATA;
}
} else {
/* All other commands */
if (strlen(argv[argc-1]) > 2
|| (strlen(argv[argc-1]) == 2 && argv[argc-1][1] != 'p')) {
fprintf(stderr, "Error: Invalid mode '%s'!\n", argv[argc-1]);
help();
}
switch (argv[argc-1][0]) {
case 'b': size = I2C_SMBUS_BYTE_DATA; break;
case 'w': size = I2C_SMBUS_WORD_DATA; break;
case 's': size = I2C_SMBUS_BLOCK_DATA; break;
case 'i': size = I2C_SMBUS_I2C_BLOCK_DATA; break;
default:
fprintf(stderr, "Error: Invalid mode '%s'!\n", argv[argc-1]);
help();
}
pec = argv[argc-1][1] == 'p';
if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) {
if (pec && size == I2C_SMBUS_I2C_BLOCK_DATA) {
fprintf(stderr, "Error: PEC not supported for I2C block writes!\n");
help();
}
if (maskp) {
fprintf(stderr, "Error: Mask not supported for block writes!\n");
help();
}
if (argc > (int)sizeof(block) + flags + 5) {
fprintf(stderr, "Error: Too many arguments!\n");
help();
}
} else if (argc != flags + 6) {
fprintf(stderr, "Error: Too many arguments!\n");
help();
}
}
len = 0; /* Must always initialize len since it is passed to confirm() */
/* read values from command line */
switch (size) {
case I2C_SMBUS_BYTE_DATA:
case I2C_SMBUS_WORD_DATA:
value = strtol(argv[flags+4], &end, 0);
if (*end || value < 0) {
fprintf(stderr, "Error: Data value invalid!\n");
help();
}
if ((size == I2C_SMBUS_BYTE_DATA && value > 0xff)
|| (size == I2C_SMBUS_WORD_DATA && value > 0xffff)) {
fprintf(stderr, "Error: Data value out of range!\n");
help();
}
break;
case I2C_SMBUS_BLOCK_DATA:
case I2C_SMBUS_I2C_BLOCK_DATA:
for (len = 0; len + flags + 5 < argc; len++) {
value = strtol(argv[flags + len + 4], &end, 0);
if (*end || value < 0) {
fprintf(stderr, "Error: Data value invalid!\n");
help();
}
if (value > 0xff) {
fprintf(stderr, "Error: Data value out of range!\n");
help();
}
fprintf(stderr, "Continue? [Y/n] ");
fflush(stderr);
if (!user_ack(1)) {
fprintf(stderr, "Aborting on user request.\n");
exit(0);
}
}
}
48
IB113
if (pec && ioctl(file, I2C_PEC, 1) < 0) {
fprintf(stderr, "Error: Could not set PEC: %s\n",
strerror(errno));
close(file);
exit(1);
}
switch (size) {
case I2C_SMBUS_BYTE:
res = i2c_smbus_write_byte(file, daddress);
break;
case I2C_SMBUS_WORD_DATA:
res = i2c_smbus_write_word_data(file, daddress, value);
break;
case I2C_SMBUS_BLOCK_DATA:
res = i2c_smbus_write_block_data(file, daddress, len, block);
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
res = i2c_smbus_write_i2c_block_data(file, daddress, len, block);
break;
default: /* I2C_SMBUS_BYTE_DATA */
res = i2c_smbus_write_byte_data(file, daddress, value);
break;
}
if (res < 0) {
fprintf(stderr, "Error: Write failed\n");
close(file);
exit(1);
}
if (pec) {
if (ioctl(file, I2C_PEC, 0) < 0) {
fprintf(stderr, "Error: Could not clear PEC: %s\n",
strerror(errno));
close(file);
exit(1);
}
}
if (!readback) { /* We're done */
close(file);
exit(0);
}
switch (size) {
case I2C_SMBUS_BYTE:
res = i2c_smbus_read_byte(file);
value = daddress;
break;
case I2C_SMBUS_WORD_DATA:
res = i2c_smbus_read_word_data(file, daddress);
break;
default: /* I2C_SMBUS_BYTE_DATA */
res = i2c_smbus_read_byte_data(file, daddress);
}
close(file);
if (ioctl(file, I2C_FUNCS, &funcs) < 0)
ret = adt_unknown;
else if (funcs & I2C_FUNC_I2C)
ret = adt_i2c;
else if (funcs & (I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
ret = adt_smbus;
else
50
IB113
ret = adt_dummy;
close(file);
return ret;
}
/* Remove trailing spaces from a string
Return the new string length including the trailing NUL */
static int rtrim(char *s)
{
int i;
for (i = strlen(s) - 1; i >= 0 && (s[i] == ' ' || s[i] == '\n'); i--)
s[i] = '\0';
return i + 2;
}
void free_adapters(struct i2c_adap *adapters)
{
int i;
for (i = 0; adapters[i].name; i++)
free(adapters[i].name);
free(adapters);
}
/* We allocate space for the adapters in bunches. The last item is a
terminator, so here we start with room for 7 adapters, which should
be enough in most cases. If not, we allocate more later as needed. */
#define BUNCH 8
/* n must match the size of adapters at calling time */
static struct i2c_adap *more_adapters(struct i2c_adap *adapters, int n)
{
struct i2c_adap *new_adapters;
/* look in sysfs */
/* First figure out where sysfs was mounted */
if ((f = fopen("/proc/mounts", "r")) == NULL) {
goto done;
}
while (fgets(n, NAME_MAX, f)) {
sscanf(n, "%*[^ ] %[^ ] %[^ ] %*s\n", sysfs, fstype);
if (strcasecmp(fstype, "sysfs") == 0) {
foundsysfs++;
break;
}
}
fclose(f);
if (! foundsysfs) {
goto done;
}
/* Bus numbers in i2c-adapter don't necessarily match those in
i2c-dev and what we really care about are the i2c-dev numbers.
Unfortunately the names are harder to get in i2c-dev */
strcat(sysfs, "/class/i2c-dev");
if(!(dir = opendir(sysfs)))
goto done;
/* go through the busses */
while ((de = readdir(dir)) != NULL) {
if (!strcmp(de->d_name, "."))
continue;
if (!strcmp(de->d_name, ".."))
continue;
/* this should work for kernels 2.6.5 or higher and */
/* is preferred because is unambiguous */
sprintf(n, "%s/%s/name", sysfs, de->d_name);
f = fopen(n, "r");
/* this seems to work for ISA */
52
IB113
if(f == NULL) {
sprintf(n, "%s/%s/device/name", sysfs, de->d_name);
f = fopen(n, "r");
}
/* non-ISA is much harder */
/* and this won't find the correct bus name if a driver
has more than one bus */
if(f == NULL) {
sprintf(n, "%s/%s/device", sysfs, de->d_name);
if(!(ddir = opendir(n)))
continue;
while ((dde = readdir(ddir)) != NULL) {
if (!strcmp(dde->d_name, "."))
continue;
if (!strcmp(dde->d_name, ".."))
continue;
if ((!strncmp(dde->d_name, "i2c-", 4))) {
sprintf(n, "%s/%s/device/%s/name",
sysfs, de->d_name, dde->d_name);
if((f = fopen(n, "r")))
goto found;
}
}
}
found:
if (f != NULL) {
int i2cbus;
enum adt type;
char *px;
px = fgets(s, 120, f);
fclose(f);
if (!px) {
fprintf(stderr, "%s: read error\n", n);
continue;
}
if ((px = strchr(s, '\n')) != NULL)
*px = 0;
if (!sscanf(de->d_name, "i2c-%d", &i2cbus))
continue;
if (!strncmp(s, "ISA ", 4)) {
type = adt_isa;
} else {
/* Attempt to probe for adapter capabilities */
type = i2c_get_funcs(i2cbus);
}
if ((count + 1) % BUNCH == 0) {
/* We need more space */
adapters = more_adapters(adapters, count + 1);
if (!adapters)
return NULL;
}
static int lookup_i2c_bus_by_name(const char *bus_name)
{
struct i2c_adap *adapters;
int i, i2cbus = -1;
adapters = gather_i2c_busses();
if (adapters == NULL) {
fprintf(stderr, "Error: Out of memory!\n");
return -3;
}
/* Walk the list of i2c busses, looking for the one with the
right name */
for (i = 0; adapters[i].name; i++) {
if (strcmp(adapters[i].name, bus_name) == 0) {
if (i2cbus >= 0) {
fprintf(stderr,
"Error: I2C bus name is not unique!\n");
i2cbus = -4;
goto done;
}
i2cbus = adapters[i].nr;
}
}
if (i2cbus == -1)
fprintf(stderr, "Error: I2C bus name doesn't match any "
"bus present!\n");
done:
free_adapters(adapters);
return i2cbus;
}
/*
* Parse an I2CBUS command line argument and return the corresponding
* bus number, or a negative value if the bus is invalid.
*/
int lookup_i2c_bus(const char *i2cbus_arg)
{
unsigned long i2cbus;
char *end;
i2cbus = strtoul(i2cbus_arg, &end, 0);
if (*end || !*i2cbus_arg) {
/* Not a number, maybe a name? */
return lookup_i2c_bus_by_name(i2cbus_arg);
}
if (i2cbus > 0xFFFFF) {
fprintf(stderr, "Error: I2C bus out of range!\n");
return -2;
}
return i2cbus;
}
/*
* Parse a CHIP-ADDRESS command line argument and return the corresponding
* chip address, or a negative value if the address is invalid.
*/
int parse_i2c_address(const char *address_arg)
{
long address;
char *end;
address = strtol(address_arg, &end, 0);
if (*end || !*address_arg) {
fprintf(stderr, "Error: Chip address is not a number!\n");
54
IB113
return -1;
}
if (address < 0x03 || address > 0x77) {
fprintf(stderr, "Error: Chip address out of range "
"(0x03-0x77)!\n");
return -2;
}
return address;
}
int open_i2c_dev(int i2cbus, char *filename, size_t size, int quiet)
{
int file;
if (file < 0 && !quiet) {
if (errno == ENOENT) {
fprintf(stderr, "Error: Could not open file "
"`/dev/i2c-%d' or `/dev/i2c/%d': %s\n",
i2cbus, i2cbus, strerror(ENOENT));
} else {
fprintf(stderr, "Error: Could not open file "
"`%s': %s\n", filename, strerror(errno));
if (errno == EACCES)
fprintf(stderr, "Run as root?\n");
}
}
return file;
}
int set_slave_addr(int file, int address, int force)
{
/* With force, let the user read from/write to the registers
even when a driver is also running */
if (ioctl(file, force ? I2C_SLAVE_FORCE : I2C_SLAVE, address) < 0) {
fprintf(stderr,
"Error: Could not set address to 0x%02x: %s\n",
address, strerror(errno));
return -errno;
}
int lookup_i2c_bus(const char *i2cbus_arg);
int parse_i2c_address(const char *address_arg);
int open_i2c_dev(int i2cbus, char *filename, size_t size, int quiet);
int set_slave_addr(int file, int address, int force);
#define MISSING_FUNC_FMT "Error: Adapter does not have %s capability\n"
#endif
/*
util.c - helper functions
*/
#include <stdio.h>
#include "util.h"
/* Return 1 if we should continue, 0 if we should abort */
int user_ack(int def)
{
char s[2];
int ret;
if (!fgets(s, 2, stdin))
return 0; /* Nack by default */
switch (s[0]) {
case 'y':
case 'Y':
ret = 1;
break;
case 'n':
case 'N':
ret = 0;
break;
default:
ret = def;
}
/* Flush extra characters */
while (s[0] != '\n') {
int c = fgetc(stdin);
if (c == EOF) {
ret = 0;
break;
}
s[0] = c;
}
return ret;
}
/*
util - helper functions
*/
#ifndef _UTIL_H
#define _UTIL_H
extern int user_ack(int def);
#endif /* _UTIL_H */
Version.h
#define VERSION "3.1.1"
56
IB113
GPIO
Logical Number
Physical Number
0
40
1
41
2
42 3 43
4
44 5 45
6
46 7 47
8
201 9 202
# GPIO example 1: Output (take GPIO 40 as example)
echo 32 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio40/direction
echo 0 > /sys/class/gpio/gpio40/value
echo 1 > /sys/class/gpio/gpio40/value
# GPIO example 2: Input (take GPIO 40 as example)
echo 32 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio40/direction
cat /sys/class/gpio/gpio40/value
Insert USB flash disk then assure it is in IB113 device list
Note! This operation may damage the data stored in USB flash disk. Please make sure
there is no critical data in the USB flash disk being used for this test.
When booting from SDcard, replace test pattern “/dev/mmcblk1” to “/dev/mmcblk0”
Note! This operation may damage the data stored in USB flash disk. Please make sure
there is no critical data in the USB flash disk being used for this test.
6. Appendix D – ADB configuration (For Android only)
Update the ADB configuration to scan for the new vendor ID. Below are the steps to
update the ADB configuration for Windows PC. These steps (and the steps for Linux PC
as well) can also be found in the R10,3.x user guide.
1. Download ADB driver from iBASE website, like: IB113_ADB_usb_driver.7z
2. Enable the "USB debugging" option on the i.MX6 device
System settings -> Developer options -> USB debugging
3. Connect the Android Device into PC, uninstall your old driver named "Android
Phone" in the device manager, then re-install driver by scanning and locating .inf file
under the directory you unpack the IB113_ADB_usd_driver.7z manually: