Here is a step by step guide to boot up your SMARC:
a. By default, the (Android) or (Linux OS) has been preloaded in the eMMC, (or SD card)
of the SMARC demo kit. All you have to do is
- Connect your SMARC with TV/LCD by using an HDMI cable,
- Or connect your LVDS panel by using LVDS cable if you have them
- Connect the device with 12V power input directly.
b. To make a recovery SD card, please refer to Chapter 2.
c. To use the root/ serial port debug function, please check Chepter3.2.1 (COM1 debug
cable setup) information.
d. To boot up with an installed LVDS panel, please refer to Chapter 3.
Note: different LVDS panel will has different customization, please check with your sales.
e. For advanced users who would be building their own products, please refer to
Chapter 3~5.
f. For special requests or assistance, please contact IBASE Sales.
3.2.2.Display setting command For Android ............................................................................................... 3
3.2.3.Display setting for Linux...................................................................................................................... 4
ARM® Cortex™-A9 is a trademark of ARM Holdings, plc.
SGeT (Standardization Group for Embedded Technologies) is a technical and scientific
association with its registered office in Munich.
SMARC ("Smart Mobility ARChitecture") is a versatile small form factor computer
Module, defined by SGeT association
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.
7
7
IBASE Technology Inc.
1. Introduction
1.1. IBASE SMARC Starter Kit
SMARC (‘Smart Mobility ARChitecture’) is a specification published by the
Standardization Group for Embedded Technologies e.V. (SGET) for
Computer-on-Modules (COMs). SMARC Computer-on-Modules are specifically designed
for the development of compact low-power systems. Generally, SMARC modules are
based on ARM processors and other low-power SoC architectures.
Measuring 82mm x 50mm, the Ibase RM-F600-SMC SMARC module is integrated
with an i.MX6 Dual Lite 1Ghz extended consumer-grade CPU that supports 2D/3D
graphic acceleration and 1080p encode/ decode under Linux/Android BSP to allow easy
OS upgrade and short time to market.
Measuring 170mm x 170mm (Mini ITX form factor), the Ibase RP-100-SMC carrier
board is compatible with 82mm x 50mm - 82mm x 80mm standard SMARC form factors.
Engineers can choose the required embedded IOs to verify developed software
application under specified Operation System. Besides setting the default HDMI output
with O.S preload in RM-F600-SMC eMMC, IBASE can optionally provide driver-ready 3G
module, WIFI module, touch panel, cable kit, power adaptor and accessories to speed
up the evaluation cycle.
This specification is subject to change without prior notice.
9
9
IBASE Technology Inc.
Form Factor
Standard Mini-ITX (170mm x 170mm)
Edge IO
1x GB LAN
1x headphone
1x MIC
2x USB
1x USB OTG
1x HDMI
1x COM (232/422/485)
Internal Headers /
Connectors
2x CAN
1x parallel LCD
1x Single CH, 18/24 bit LVDS
1x LCD DDC (I2C)
1x LCD backlight power control header
1x CSI-MIPI
2x USB 2.0
8x GPIO
1x 2COM ports header
1x debug port
1x Mini-PCIe with USB
1x SIM socket
1x touch (4-wired)
1x speaker Out
1x micro-SD
Users who has Ibase standard image file can refer to this chapter to prepare your own
boot-up SD card. Ibase provides HDMI / LVDS output environment by default to let you
prepare the software application pre-development easily under Linux / Android
platform.
3.1. Make a Recovery SD Card
Preparing your Recovery SD card help to install the Linux/ Android image into eMMC
Please download the Recovery SD card’s image by FTP in advance.
In order to use the evaluation kit, you will need to install an Operating System (OS) onto
onboard eMMC by recovery SD card. An Operating System is the set of basic programs
and utilities that allow your computer to run.
These instructions will guide you through installing a recovery program on your SD card
that will allow you to easily install different OS’s and to recover your card when needed.
1. Insert an SD card that is 4GB or greater in size into your computer
2. Format the SD card
i. Download the SD Association's Formatting Tool (SD Card Formatter 4.0) from
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 DIP switch and make sure it can boot from SD Card.
(See 2.3 Boot on the SMARC starter kit )
Please double check the Boot device selection before power on.
SW3: Boot Select
Note: 1: Switch On ; 0: Switch Off
1. 7. Insert the SD card/MicroSD into motherboard, make sure the HDMI panel is
connected, and connect the power supply to boot up the system.
2. 8. Recovery program on your SD card will execute automatically. The eMMC on
SMARC will be format, and OS will be installed while the progress bar shows 100%
complete.
3. 9. Remove the power, and the recovery SD. Remember to set the boot source
from module eMMC.
4. Connect the power and boot up SMARC, you will see the Linux/ Android boot up
pages.
2
SMARC Evaluation Kit
3.3. Parameter Setting on U-boot
We provide HDMI output and (10.1 “ Onation LVDS Panel output command example)
for SMARC starter kit. If you have any other LVDS/ TTL panel need to be customized,
please contact Ibase sales or FAE staff.
3.3.1. Preparation (debug console)
i. We set the COM1 (Tx1, Rx1) as default debug port, please double check it can be
connect to (RX, Tx) of your PC environment.
ii. set 115200 bps (8n1, no flow control) in Windows terminal ( for example
Putty.exe)
iii. When booting the system, you can press “Enter” to stop auto boot and modify
your environment.
(Note: Users who are not sure the COM connection, please double check your
SMARC.COM1.Tx1 connect to PC.COM.Rx ; SMARC.COM1.Rx1 to PC.COM.Tx)
Note:
The COM1 is map to ttymxc0 device node under Linux& android.
The COM2 is map to ttymxc1 device node under Linux& android.
The COM5 is map to ttymxc4 device node under Linux& android.
This Chapter mainly for advanced EE to create your own carrier boards (or products), layout suggestion
can be found inside also. for RP-100-SMC carrier board design schematic file. Please contact your sales
in advance.
4.1. Block Diagram
6
SMARC Evaluation Kit
Pin
Signal Name
I/O
Type
Power Rail
Description
P83
PCIE_CLK1P
O
PCIe
Differential PCIe reference clock output
P84
PCIE_CLK1N
O
PCIe
P89
PCIE_TXP
O
PCIe
Differential PCIe transmit data pair
P90
PCIE_TXM
O
PCIe
P86
PCIE_RXP
I
PCIe
Differential PCIe receive data pair
P87
PCIE_RXM
I
PCIe
S146
PCIE_WAKE#
I
CMOS
3.3V
PCIe wake up signal
P75
PCIE_RST#
O
CMOS
3.3V
PCIe reset output
S49
I2C4_SDA
I/O
OD
3.3V
I2C interface data, some PICe device need SMB interface for
special configuration
S48
I2C4_SCL
O
OD
3.3V
I2C interface clock, some PICe device need SMB interface for
special configuration
C800.1UF/ 25V/4
C620.1UF/ 25V/4
C870.1UF/ 25V/4
R5810K/4
+3.3V_VCC
UIM_VPP
UIM_DATA
PCIE_WAKE#13
C610.1UF/ 25V/4
+3.3V_VCC
C830.1UF/ 25V/4
C780.1UF/ 25V/4
KEY
J9
FOXCONN_AS0B226-S99Q-7H
WAKE#
1
RSVD1
3
RSVD2
5
CLKREQ#
7
GND1
9
REFCLK-
11
REFCLK+
13
GND2
15
RSVD3
17
RSVD4
19
GND3
21
PER_N0
23
PER_P0
25
GND4
27
GND5
29
PET_N0
31
PET_P0
33
GND6
35
RSVD5
37
RSVD6
39
RSVD7
41
RSVD8
43
RSVD9
45
RSVD10
47
RSVD11
49
RSVD12
51
+3V_1
2
GND7
4
+1.5V_1
6
RSVD13
8
RSVD14
10
RSVD15
12
RSVD16
14
RSVD17
16
GND8
18
RSVD18
20
PERST#
22
+3V_AUX
24
GND9
26
+1.5V_2
28
SMB_CLK
30
SMB_DATA
32
GND10
34
USB_D-
36
USB_D+
38
GND11
40
LED_WWAN#
42
LED_WLAN#
44
LED_WPAN#
46
+1.5V_3
48
GND12
50
+3V_2
52
GND
57
GND
58
+3.3V_VCC
LED3LTST-C190KGKT_GRN
CA
+1.5_VCC
LED2LTST-C190KGKT_GRN
CA
LED_WLAN#
+3.3V_VCC
C890.1UF/ 25V/4
+3.3V_VCC
LED_WPAN#
LED4LTST-C190KGKT_GRN
CA
UIM_VPP
UIM_DATA
+1.5_VCC
+3.3V_VCC
UIM_RST
UIM_CLK
UIM_PWR
R90330/4
LED_WWAN#
LED_WPAN#
LED_WLAN#
+1.5_VCC
+1.5_VCC
R89330/4
UIM_RST
UIM_CLK
UIM_PWR
R88330/4
C854.7UF/ 16V/6
I2C4_SDA 8,13
+3.3V_VCC
PCIE_RXM13
PCIE_TXM13
PCIE_CLK1_N13
PCIE_TXP13
PCIE_RXP13
PCIE_RST# 13
PCIE_CLK1_P13
I2C4_SCL 8,13
LED_WWAN#
C654.7UF/ 16V/6
DOWN_USB_PA2+ 13
DOWN_USB_PA2- 13
J10
WIN W ING_WSC D-06ACP1U4
VCC
1
RESET
2
CLK
3
GND
4
VPP
5
I/O
6
4.2. Interfaces
4.2.1. PCI Express
PCIe Signals
Reference Schematic
*Notice* : SMARC PINS48~PINS49 are I2C4, which is activated in RM-F6SO-SMC and RM-F600-SMC
module only. Users who need to adopt I2C in RM-F6DU-SMC or RM-F6QD-SMC, please connect it from
I2C1~I2C3 in the carrier board.
* Note: ( Audio codec with I2S interface is strongly suggested for your carrier board design; please
kindly to be noticed that SPDIF interface was not verified in RM-F6xx-SMC + RP-100-SMC carrier board)
5. BSP User Guide ( for advanced software engineer only )
This Chapter mainly for advanced SW engineer to build the image for SMARC starter kit.
Any other modification, new device or driver should be handled carefully.
# Assume your linux kernel source is at ~/linux_bsp/kernel-3.0.35
cd ~/linux_bsp/kernel-3.0.35
make ARCH=arm clean
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
**** If the building process is successful, uImage file will be generated under
arch/arm/boot directory. ****
34
SMARC Evaluation Kit
5.1.5. Copying u-boot, kernel to SD card
Insert an empty SD card with at least 4GB size and put it in a card reader connecting to
your host PC. Assume your SD card is /dev/sdb on your x86 host PC
First, a partition table must be created. If a partition already exists and it is big enough
for the file system you want to deploy, then you can skip this step.
To create a partition, at offset 16384 (in sectors of 512 bytes) enter the following
On most Linux host operating systems, SD card will be mounted automatically upon
insertion. Therefore, before running fdisk, please make sure that SD card is unmounted (via 'sudo umount /dev/sdb').
Type the following parameters (each followed by <ENTER>):
u [switch the unit to sectors instead of cylinders]
d [repeat this until no partition is reported by the 'p' command ]
n [create a new partition]
p [create a primary partition]
1 [the first partition]
16384 [starting at offset sector #16384, i.e. 8MB, which leaves enough space for the kernel, the
boot loader and its configuration data]
<enter> [using the default value will create a partition that spans to the last sector of the
medium]
w [ this writes the partition table to the medium and fdisk exits]
The file system format ext3 or ext4 is a good option for removable media due to the built-in journaling.
Run the following command to format the partition:
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 */
if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
fprintf(stderr, "Error: Could not get the adapter "
"functionality matrix: %s\n", strerror(errno));
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 "
"address 0x%02x, ", filename, address);
if (daddress < 0)
fprintf(stderr, "current data\naddress");
else
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
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_WORD_DATA:
if (!(funcs & I2C_FUNC_SMBUS_WRITE_WORD_DATA)) {
fprintf(stderr, MISSING_FUNC_FMT, "SMBus write 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 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")) {
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')) {
48
SMARC Evaluation Kit
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();
}
block[len] = value;
}
value = -1;
break;
default:
value = -1;
break;
}
fprintf(stderr, "Continue? [Y/n] ");
fflush(stderr);
if (!user_ack(1)) {
fprintf(stderr, "Aborting on user request.\n");
exit(0);
}
}
}
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);
50
SMARC Evaluation Kit
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
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--)
52
SMARC Evaluation Kit
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 */
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, ".."))
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");
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"
int main(void)
{
int fd = open("/dev/watchdog", O_WRONLY);
int ret = 0;
if (fd == -1) {
perror("watchdog");
exit(EXIT_FAILURE);
}
while (1) {
ret = write(fd, "\0", 1);
if (ret != 1) {
ret = -1;
break;
}
puts("[WDT] Keep alive");
sleep(50);
}
close(fd);
return ret;
}
6.2.3. How to use Watch dog in Linux
60
SMARC Evaluation Kit
Group
Circuit Net
Ball
Mixed Functions
CSPI1 [SPI]
CSPI1_SS1
G21
EIM_D19
CSPI1
CSPI1_SS2
F22
EIM_D24
CSPI1
CSPI1_MOSI
V6
KEY_ROW0
CSPI1
CSPI1_MISO
U7
KEY_COL1
CSPI1
CSPI1_CLK
W5
KEY_COL0
CSPI2 [SPI]
CSPI2_SS0
K20
EIM_RW
CSPI2
CSPI2_SS1
K22
EIM_LBA
CSPI2
CSPI2_MOSI
J23
EIM_CS1
CSPI2
CSPI2_MISO
J24
EIM_OE
CSPI2
CSPI2_CLK
H24
EIM_CS0
Battery
CHARGING#
H19
EIM_A25
Battery
BATLOW#
D25
EIM_D25
Battery
CHARGER_PRSNT#
J20
EIM_D30
Carrier Board
RESET_OUT#
P5
GPIO_19
Carrier Board
Carrier_STBY#
R4
GPIO_5
Carrier Board
Carrier_PWR_ON
R2
GPIO_16
Carrier Board
Carrier_LID#
E23
EIM_D21
Carrier Board
Carrier_SLEEP#
G22
EIM_D25
HDMI
HDMI_DDC_DAT_IN
C25
EIM_D16
HDMI
HDMI_DDC_CLK_IN
E22
EIM_EB2
HDMI
HDMI_HPD
K1
HDMI_HPD
HDMI
HDMI_CEC_IN
K2
HDMI_DDCCEC
HDMI
HDMI_CLKM
J5
HDMI_CLKM
HDMI
HDMI_CLKP
J6
HDMI_CLKP
HDMI
HDMI_D0M
K5
HDMI_D0M
7. Appendix B - i.MX6 CPU ball out Table.
This Chapter is referenced for advanced SW Engineer to modify the Kernel driver or
make their own BSP. Please check Freescale i.MX6 specification, porting guide and user
manuals carefully
# cd flash_emmc/rp100_emmc
# ./fsl-sdcard-partition.sh –f /dev/mmcblk0
8. Appendix C : how to Flash the image to eMMC
(for advanced user only) You can flash the current SD image system (standard or
customized by user) to eMMC by following method.
Use “fdisk -l” command to check current storage devices, current boot device is
represented as /dev/mmcblk1, SMARC module’s eMMC device is /dev/mmcblk0
Flash Module eMMC:
Remember to check the boot set up of dip switch is “boot from SMARC’s eMMC”,
then, you can boot from eMMC with the above concept.
9. Appendix D –Useful links
For more information about Android, please visit:
http://developer.android.com/index.html
For more information Freescale i.MX6 CPU , please visit: