├── lint.xml
├── assets
├── dump.png
├── set.png
├── detect.png
└── i2c-command-line-tools.png
├── ic_launcher-web.png
├── libs
└── android-support-v4.jar
├── res
├── drawable-hdpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── drawable-xhdpi
│ └── ic_launcher.png
├── drawable-xxhdpi
│ └── ic_launcher.png
├── values
│ ├── integers.xml
│ ├── dimens.xml
│ ├── styles.xml
│ ├── array.xml
│ └── strings.xml
└── layout
│ ├── dialog_i2c_info.xml
│ ├── dialog_i2c_set.xml
│ └── activity_main.xml
├── project.properties
├── proguard-project.txt
├── AndroidManifest.xml
├── bin
└── AndroidManifest.xml
├── src
└── com
│ └── mitac
│ └── android
│ └── i2ctool
│ ├── LogFileHelper.java
│ ├── I2cSetDialog.java
│ ├── I2cInfo.java
│ ├── I2cToolHelper.java
│ ├── I2cInfoDialog.java
│ ├── I2cParserHelper.java
│ └── MainActivity.java
└── README.md
/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/assets/dump.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/li2/android-i2c-tool/HEAD/assets/dump.png
--------------------------------------------------------------------------------
/assets/set.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/li2/android-i2c-tool/HEAD/assets/set.png
--------------------------------------------------------------------------------
/assets/detect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/li2/android-i2c-tool/HEAD/assets/detect.png
--------------------------------------------------------------------------------
/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/li2/android-i2c-tool/HEAD/ic_launcher-web.png
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/li2/android-i2c-tool/HEAD/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/assets/i2c-command-line-tools.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/li2/android-i2c-tool/HEAD/assets/i2c-command-line-tools.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/li2/android-i2c-tool/HEAD/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/li2/android-i2c-tool/HEAD/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/li2/android-i2c-tool/HEAD/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/li2/android-i2c-tool/HEAD/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/values/integers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 512
5 |
6 |
7 |
--------------------------------------------------------------------------------
/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/res/values/array.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - 0.5
5 | - 1
6 | - 1.5
7 | - 2
8 | - 5
9 | - 10
10 |
11 |
12 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mitac I2C Tool
5 | Hello world
6 | Dump
7 | Set
8 | Detect
9 | Clean
10 | Data Address: 0x
11 | Value: 0x
12 |
13 |
14 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-22
15 | android.library.reference.1=../../android-sdk/extras/android/support/v7/appcompat
16 |
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/bin/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/res/layout/dialog_i2c_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
17 |
18 |
23 |
24 |
31 |
32 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/res/layout/dialog_i2c_set.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
18 |
19 |
28 |
29 |
30 |
36 |
37 |
41 |
42 |
51 |
52 |
53 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/src/com/mitac/android/i2ctool/LogFileHelper.java:
--------------------------------------------------------------------------------
1 | package com.mitac.android.i2ctool;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.FileWriter;
6 | import java.io.IOException;
7 | import java.text.SimpleDateFormat;
8 | import java.util.Date;
9 | import java.util.Locale;
10 |
11 | import android.os.Environment;
12 | import android.util.Log;
13 |
14 | public class LogFileHelper {
15 |
16 | private static final String TAG = "i2c_LogFileHelper";
17 |
18 | public static final String TIME_FORMATTER_YMDHMS = "yyyy-MM-dd HH:mm:ss";
19 | public static final String TIME_FORMATTER_HMS = "HH:mm:ss";
20 |
21 | private static final String LOG_FILE_SUBDIR = "/i2clog";
22 |
23 | private static LogFileHelper sLogFileHelper;
24 | private File mLogDirectory;
25 |
26 | private LogFileHelper() {
27 | super();
28 | mLogDirectory = new File(getInnerSDCardPath() + LOG_FILE_SUBDIR);
29 | mLogDirectory.mkdirs();
30 | }
31 |
32 | public static LogFileHelper get() {
33 | if (sLogFileHelper == null) {
34 | sLogFileHelper = new LogFileHelper();
35 | }
36 | return sLogFileHelper;
37 | }
38 |
39 | public File createFile(String filename) {
40 | File file = new File(mLogDirectory, filename);
41 | writeFile(file, "\r\n" + timestamp(TIME_FORMATTER_YMDHMS) + "\r\n\r\n" );
42 | return file;
43 | }
44 |
45 | /**
46 | * Method to write ascii text characters to file on SD card. Note that you
47 | * must add a WRITE_EXTERNAL_STORAGE permission to the manifest file or this
48 | * method will throw a FileNotFound Exception because you won't have write
49 | * permission.
50 | */
51 | public void writeFile(File file, String content) {
52 | if (file == null) {
53 | Log.e(TAG, "File not created.");
54 | }
55 |
56 | try {
57 | FileWriter out = new FileWriter(file, true);
58 | out.write("\r\n" + content);
59 | out.flush();
60 | out.close();
61 | } catch (FileNotFoundException e) {
62 | e.printStackTrace();
63 | Log.e(TAG, "File not found. Did you add a WRITE_EXTERNAL_STORAGE permission to the manifest?");
64 | } catch (IOException e) {
65 | e.printStackTrace();
66 | }
67 | }
68 |
69 | //Get inner SDCard path
70 | public String getInnerSDCardPath() {
71 | return Environment.getExternalStorageDirectory().getPath();
72 | }
73 |
74 | public String timestamp(String formatter) {
75 | SimpleDateFormat sdf = new SimpleDateFormat(formatter, Locale.US);
76 | Date date = new Date();
77 | return sdf.format(date);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Android I2C Tool Manual
2 |
3 | This tool is to
4 |
5 | - detect Android I2C devices,
6 | - dump and set the values of I2C device registers periodically or just one time.
7 | - log device registers values.
8 |
9 | The core part is running linux commannd line tool through `Runtime.getRuntime().exec()`, then read and parse the stand out/error and then write to log.
10 |
11 | ### Setup
12 |
13 | 1. Build the [i2c linux command line tool](https://github.com/suapapa/i2c-tools) in target Android BSP to generate binary files: `i2cdump`, `i2cset`.
14 | 2. Root Android device.
15 | 3. Upload these two files to target device path `/system/xbin`, and modify the permission as 755;
16 |
17 | ```sh
18 | adb-platform-tools>adb remount
19 | adb-platform-tools>adb push i2cdump /system/xbin
20 | adb-platform-tools>adb push i2cset /system/xbin
21 | adb-platform-tools>adb shell chmod 755 /system/xbin/i2c*
22 | ```
23 | 4. If encounter the following error:
24 |
25 | ```sh
26 | Error: Could not open file `/dev/i2c-2': Permission denied, Run as root?
27 | ```
28 | then need to modify the permission of Android I2C device file:`root@android:/ # chmod 666 /dev/i2c*`
29 |
30 |
31 | 
32 |
33 |
34 | ### Detect I2C bus and chips on target Android device
35 |
36 | 
37 |
38 |
39 | ### Dump all registers of specific I2C chip
40 |
41 | 1. click right button to popup a I2C device selector dialog, then set bus number, device addres, read mode;
42 | 2. enable read periodically;
43 | 3. enable Log,
44 |
45 | log path :/mnt/sdcard/i2clog/i2c_log_parsed.txt and i2c_log_raw.txt
46 |
47 | ```sh
48 | 14:54:59 -
49 | 24 02 00 00 64 00 12 0c 3f 10 88 02 8c 0b 8c 0b
50 | c9 0c c9 0c 08 00 ff ff c9 0c fa ff 27 0b 5b fd
51 | 27 0b c9 0c 21 00 00 00 12 0c 02 00 64 00 60 00
52 | 68 10 fa 05 ff ff 5e 00 53 00 76 11 f4 0b 00 00
53 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
54 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
55 | 00 00 0a 42 51 32 37 35 34 58 2d 47 31 ff 00 00
56 | 00 00 00 00 00 00 00 00 XX XX 95 ff 3f 10 12 0c
57 | 24 02 00 00 64 00 12 0c 3f 10 88 02 8c 0b 8c 0b
58 | c9 0c c9 0c 08 00 ff ff c9 0c fa ff 27 0b 5b fd
59 | 27 0b c9 0c 21 00 00 00 12 0c 02 00 64 00 60 00
60 | 68 10 fa 05 ff ff 5e 00 53 00 76 11 f4 0b 00 00
61 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
62 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
63 | 00 00 0a 42 51 32 37 35 34 58 2d 47 31 ff 00 00
64 | 00 00 00 00 00 00 00 00 XX XX 95 ff 3f 10 12 0c
65 | 14:55:00 -
66 | ```
67 | 
68 |
69 |
70 | ### Set value to specific I2C device register
71 |
72 | 
73 |
74 |
75 | ## About
76 |
77 | App可以用于探测Android设备I2C总线、读取/设置I2C设备寄存器值,并写入log,硬件工程师可以直接把log导入excel,就可以进一步分析数据。
78 | 方便不熟悉命令行和ADB的硬件工程师测试。
79 |
80 | 核心是通过`Runtime.getRuntime().exec()`调用命令行工具,然后读取进程的标准输出/标准错误。核心代码在`I2cToolHelper.java`和`I2cParserHelper.java`
81 |
82 | 之所以开发这个App,是因为我负责的驱动模块出现了问题,需要和硬件工程师排一起查软、硬问题。因为硬件工程师不熟悉命令行、ADB,并且使用ADB打印的log不便于处理。
83 |
84 | 第一版于2013.08开发完成,这是第一次开发Android,所有细节都得搜索,很琐碎很差劲,至于有多差劲,可以看代码:[branch-v1](https://github.com/li2/Android_I2C_Tool/tree/v1),
85 | 第二版于2015.10开发完成,重构了之前的代码。
86 |
87 | 之所以开源这个App,是因为没有上述提到的开源的命令行工具,这个App没有任何作用。
88 | 希望对别人有所帮助。
89 |
90 | weiyi.just2@gmail.com
91 | li2.me
92 |
--------------------------------------------------------------------------------
/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
14 |
15 |
23 |
24 |
25 |
26 |
32 |
33 |
38 |
39 |
44 |
45 |
49 |
50 |
51 |
52 |
57 |
58 |
64 |
65 |
72 |
73 |
80 |
81 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/src/com/mitac/android/i2ctool/I2cSetDialog.java:
--------------------------------------------------------------------------------
1 | package com.mitac.android.i2ctool;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.AlertDialog;
5 | import android.app.Dialog;
6 | import android.content.DialogInterface;
7 | import android.content.DialogInterface.OnClickListener;
8 | import android.os.Bundle;
9 | import android.support.v4.app.DialogFragment;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.widget.EditText;
13 | import android.widget.NumberPicker;
14 | import android.widget.NumberPicker.OnValueChangeListener;
15 | import android.widget.Toast;
16 |
17 | public class I2cSetDialog extends DialogFragment {
18 |
19 | private static final String TAG = "i2c_I2cSetDialog";
20 |
21 | private int mDataAddr = 0;
22 | private int mDataValue = 0;
23 | private int mI2cSetMode = 0;
24 |
25 | EditText mDataAddrEt;
26 | EditText mDataValueEt;
27 |
28 | private OnSetClickListener mOnSetClickListener;
29 |
30 | public interface OnSetClickListener {
31 | void onSetClick(int dataAddress, int value, String mode);
32 | }
33 |
34 | public void setOnSetClickListener(OnSetClickListener l) {
35 | mOnSetClickListener = l;
36 | }
37 |
38 | @SuppressLint("InflateParams")
39 | @Override
40 | public Dialog onCreateDialog(Bundle savedInstanceState) {
41 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
42 | LayoutInflater inflater = getActivity().getLayoutInflater();
43 |
44 | View view = inflater.inflate(R.layout.dialog_i2c_set, null);
45 | builder.setView(view)
46 | .setPositiveButton(R.string.i2c_set, new OnClickListener() {
47 | @Override
48 | public void onClick(DialogInterface dialog, int which) {
49 | if (mOnSetClickListener != null) {
50 | String mode = I2cInfo.getI2cSetMode(mI2cSetMode);
51 | mDataAddr = Integer.valueOf(mDataAddrEt.getText().toString(), 16);
52 | mDataValue = Integer.valueOf(mDataValueEt.getText().toString(), 16);
53 | mOnSetClickListener.onSetClick(mDataAddr, mDataValue, mode);
54 | I2cInfo.saveI2cSetToPref(getActivity(), mDataAddr, mDataValue, mI2cSetMode);
55 | }
56 | }
57 | })
58 | .setNegativeButton(android.R.string.cancel, new OnClickListener() {
59 | @Override
60 | public void onClick(DialogInterface dialog, int which) {
61 | I2cSetDialog.this.getDialog().cancel();
62 | }
63 | });
64 |
65 | mDataAddrEt = (EditText) view.findViewById(R.id.dialogDataAddrEt);
66 | mDataValueEt = (EditText) view.findViewById(R.id.dialogDataValueEt);
67 |
68 | // Mode picker
69 | NumberPicker i2cModePicker = (NumberPicker) view.findViewById(R.id.dialogModePicker);
70 | i2cModePicker.setMinValue(0);
71 | i2cModePicker.setMaxValue(I2cInfo.SET_MODE_COUNT-1);
72 | i2cModePicker.setOnValueChangedListener(new OnValueChangeListener() {
73 | @Override
74 | public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
75 | mI2cSetMode = newVal;
76 | Toast.makeText(getActivity(), I2cInfo.getI2cSetModeDescription(newVal), Toast.LENGTH_SHORT).show();;
77 | }
78 | });
79 | i2cModePicker.setDisplayedValues(getModeDisplayedValues());
80 |
81 | // Init data
82 | mDataAddr = I2cInfo.getDataAddrFromPref(getActivity());
83 | mDataValue = I2cInfo.getDataValueFromPref(getActivity());
84 | mI2cSetMode = I2cInfo.getSetModeFromPref(getActivity());
85 |
86 | mDataAddrEt.setText(Integer.toHexString(mDataAddr));
87 | mDataValueEt.setText(Integer.toHexString(mDataValue));
88 | i2cModePicker.setValue(mI2cSetMode);
89 |
90 | return builder.create();
91 | }
92 |
93 | private String[] getModeDisplayedValues() {
94 | String[] displayedValues = new String[I2cInfo.SET_MODE_COUNT];
95 | for (int i=0; i stream);
33 | }
34 |
35 | public void setOnStreamParsedListener(OnStreamParsedListener l) {
36 | mOnStreamParsedListener = l;
37 | }
38 |
39 | public I2cToolHelper(Handler responseHandler) {
40 | super();
41 | mResponseHandler = responseHandler;
42 | }
43 |
44 | // android runtime exec Could not open file `/dev/i2c-2'Permission denied, Run as root?
45 | // default is 600
46 | // chmod 666 /dev/i2c-2
47 | // crw------- root root 89, 2 2015-10-27 14:51 i2c-2
48 | // crw-rw-rw- root root 89, 2 2015-10-27 14:51 i2c-2
49 | private Process doRuntimeExec(String program) {
50 | Process process;
51 | try {
52 | Log.i(TAG, "Execute " + program);
53 | process = Runtime.getRuntime().exec(program);
54 | mHandler.postDelayed(mStreamParserRunnable, DELAY_AFTER_CMD_EXECUTED);
55 |
56 | } catch (IOException ioe) {
57 | process = null;
58 | Log.e(TAG, "Requested program can not be executed: " + program + ", " + ioe);
59 | }
60 |
61 | return process;
62 | }
63 |
64 | public void doDump(int bus, int address, String mode) {
65 | String program = I2C_TOOL_PATH + "/" + I2C_TOOL_DUMP + " -f -y " + bus + " " + address;
66 | if (mode != null) {
67 | program += " " + mode;
68 | }
69 | mNativeProcess = doRuntimeExec(program);
70 | }
71 |
72 | public void doSet(int bus, int address, int dataAddress, int value, String mode) {
73 | String program = I2C_TOOL_PATH + "/" + I2C_TOOL_SET + " -f -y " +
74 | bus + " " + address + " " + dataAddress + " " + value;
75 | if (mode != null) {
76 | program += " " + mode;
77 | }
78 | mNativeProcess = doRuntimeExec(program);
79 | }
80 |
81 | public void doDetect() {
82 | String program = I2C_TOOL_PATH + "/" + I2C_TOOL_DETECT + " -l";
83 | // use this command instead
84 | program = "ls /sys/bus/i2c/devices ; ls /sys/bus/i2c/drivers";
85 | // program = "ls /sys/bus/i2c/devices ; cat /sys/bus/i2c/devices/*/name";
86 | mNativeProcess = doRuntimeExec(program);
87 | }
88 |
89 | private Runnable mStreamParserRunnable = new Runnable() {
90 | @Override
91 | public void run() {
92 | if (mNativeProcess == null) {
93 | return;
94 | }
95 | ArrayList result;
96 | result = getStandOut();
97 | if (result == null || result.size() == 0) {
98 | result = getStandError();
99 | if (result != null) {
100 | Log.e(TAG, "Stand Err: " + result);
101 | handleParseResult(PROCESS_STREAM_STDERR, result);
102 | }
103 | } else {
104 | // Log.d(TAG, "Stand Out: " + result);
105 | handleParseResult(PROCESS_STREAM_STDOUT, result);
106 | }
107 | }
108 | };
109 |
110 | private void handleParseResult(final int streamType, final ArrayList stream) {
111 | if (mResponseHandler == null) {
112 | Log.e(TAG, "Response handler is null");
113 | return;
114 | }
115 |
116 | mResponseHandler.post(new Runnable() {
117 | @Override
118 | public void run() {
119 | if (mOnStreamParsedListener != null) {
120 | mOnStreamParsedListener.onStreamParsed(streamType, stream);
121 | }
122 | }
123 | });
124 | }
125 |
126 | private ArrayList getStandOut() {
127 | if (mNativeProcess == null) {
128 | return null;
129 | }
130 | return getProcessStream(mNativeProcess, PROCESS_STREAM_STDOUT);
131 | }
132 |
133 | private ArrayList getStandError() {
134 | if (mNativeProcess == null) {
135 | return null;
136 | }
137 | return getProcessStream(mNativeProcess, PROCESS_STREAM_STDERR);
138 | }
139 |
140 | private ArrayList getProcessStream(Process process, int streamType) {
141 | try {
142 | ArrayList result = new ArrayList();
143 | String line = "";
144 | BufferedReader bufReader;
145 | if (streamType == PROCESS_STREAM_STDERR) {
146 | bufReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
147 | } else {
148 | bufReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
149 | }
150 |
151 | while ((line = bufReader.readLine()) != null) {
152 | if (line.trim().equals("")) {
153 | continue;
154 | }
155 | result.add(line);
156 | }
157 | return result;
158 |
159 | } catch (IOException ioe) {
160 | ioe.printStackTrace();
161 | return null;
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/com/mitac/android/i2ctool/I2cInfoDialog.java:
--------------------------------------------------------------------------------
1 | package com.mitac.android.i2ctool;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.AlertDialog;
5 | import android.app.Dialog;
6 | import android.content.DialogInterface;
7 | import android.content.DialogInterface.OnClickListener;
8 | import android.os.Bundle;
9 | import android.support.v4.app.DialogFragment;
10 | import android.util.Log;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.widget.NumberPicker;
14 | import android.widget.NumberPicker.OnValueChangeListener;
15 | import android.widget.Toast;
16 |
17 | public class I2cInfoDialog extends DialogFragment {
18 |
19 | private static final String TAG = "i2c_I2cInfoDialog";
20 |
21 | private static final int MIN_VALUE = 0;
22 | private static final int MAX_VALUE = 0xf;
23 |
24 | private int mI2cBusId = 0;
25 | private int mI2cAddrHigh = 0;
26 | private int mI2cAddrLow = 0;
27 | private int mI2cMode = 0;
28 |
29 | private OnI2cInfoChangedListener mOnI2cInfoChangedListener;
30 |
31 | public interface OnI2cInfoChangedListener {
32 | void onI2cInfoChanged(int busId, int address, String mode);
33 | }
34 |
35 | public void setOnI2cInfoChangedListener(OnI2cInfoChangedListener l) {
36 | mOnI2cInfoChangedListener = l;
37 | }
38 |
39 | @SuppressLint("InflateParams")
40 | @Override
41 | public Dialog onCreateDialog(Bundle savedInstanceState) {
42 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
43 | LayoutInflater inflater = getActivity().getLayoutInflater();
44 |
45 | View view = inflater.inflate(R.layout.dialog_i2c_info, null);
46 | builder.setView(view)
47 | .setPositiveButton(android.R.string.ok, new OnClickListener() {
48 | @Override
49 | public void onClick(DialogInterface dialog, int which) {
50 | if (mOnI2cInfoChangedListener != null) {
51 | Log.d(TAG, "Address High " + mI2cAddrHigh + ", Low " + mI2cAddrLow);
52 | int address = mI2cAddrHigh * 16 + mI2cAddrLow;
53 | String mode = I2cInfo.getI2cDumpMode(mI2cMode);
54 | mOnI2cInfoChangedListener.onI2cInfoChanged(mI2cBusId, address, mode);
55 | I2cInfo.saveI2cInfoToPref(getActivity(), mI2cBusId, address, mI2cMode);
56 | }
57 | }
58 | })
59 | .setNegativeButton(android.R.string.cancel, new OnClickListener() {
60 | @Override
61 | public void onClick(DialogInterface dialog, int which) {
62 | I2cInfoDialog.this.getDialog().cancel();
63 | }
64 | });
65 |
66 | AlertDialog dialog = builder.create();
67 |
68 | // dialog.findViewById in DialogFragment onCreateDialog()
69 | // view.findViewById solve it.
70 |
71 | // Bus picker
72 | NumberPicker i2cBusIdPicker = (NumberPicker) view.findViewById(R.id.dialogBusIdPicker);
73 | i2cBusIdPicker.setMinValue(MIN_VALUE);
74 | i2cBusIdPicker.setMaxValue(MAX_VALUE);
75 | i2cBusIdPicker.setOnValueChangedListener(new OnValueChangeListener() {
76 | @Override
77 | public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
78 | mI2cBusId = newVal;
79 | }
80 | });
81 |
82 | // Adress picker
83 | NumberPicker i2cAddrHightPicker = (NumberPicker) view.findViewById(R.id.dialogAddrHighPicker);
84 | i2cAddrHightPicker.setMinValue(MIN_VALUE);
85 | i2cAddrHightPicker.setMaxValue(MAX_VALUE);
86 | i2cAddrHightPicker.setOnValueChangedListener(new OnValueChangeListener() {
87 | @Override
88 | public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
89 | mI2cAddrHigh = newVal;
90 | }
91 | });
92 | // setFormatter return "0x" + Integer.toHexString(value)
93 | // 停止滚动后,0xfe变成0,0xf2变成2,所有字母都没有显示!
94 | // workaround
95 | i2cAddrHightPicker.setDisplayedValues(getAddrDisplayedValues());
96 |
97 | NumberPicker i2cAddrLowPicker = (NumberPicker) view.findViewById(R.id.dialogAddrLowPicker);
98 | i2cAddrLowPicker.setMinValue(MIN_VALUE);
99 | i2cAddrLowPicker.setMaxValue(MAX_VALUE);
100 | i2cAddrLowPicker.setOnValueChangedListener(new OnValueChangeListener() {
101 | @Override
102 | public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
103 | mI2cAddrLow = newVal;
104 | }
105 | });
106 | i2cAddrLowPicker.setDisplayedValues(getAddrDisplayedValues());
107 |
108 | // Mode picker
109 | NumberPicker i2cModePicker = (NumberPicker) view.findViewById(R.id.dialogModePicker);
110 | i2cModePicker.setMinValue(0);
111 | i2cModePicker.setMaxValue(I2cInfo.DUMP_MODE_COUNT-1);
112 | i2cModePicker.setOnValueChangedListener(new OnValueChangeListener() {
113 | @Override
114 | public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
115 | mI2cMode = newVal;
116 | Toast.makeText(getActivity(), I2cInfo.getI2cDumpModeDescription(newVal), Toast.LENGTH_SHORT).show();;
117 | }
118 | });
119 | i2cModePicker.setDisplayedValues(getModeDisplayedValues());
120 |
121 | // Init data
122 | mI2cBusId = I2cInfo.getBusIdFromPref(getActivity());
123 | int address = I2cInfo.getAddressFromPref(getActivity());
124 | mI2cAddrHigh = address/16;
125 | mI2cAddrLow = address%16;
126 | mI2cMode = I2cInfo.getDumpModeFromFref(getActivity());
127 |
128 | i2cBusIdPicker.setValue(mI2cBusId);
129 | i2cAddrHightPicker.setValue(mI2cAddrHigh);
130 | i2cAddrLowPicker.setValue(mI2cAddrLow);
131 | i2cModePicker.setValue(mI2cMode);
132 | return dialog;
133 | }
134 |
135 | private String[] getModeDisplayedValues() {
136 | String[] displayedValues = new String[I2cInfo.DUMP_MODE_COUNT];
137 | for (int i=0; i buslist){
69 | String pattern_stdout_i2cbus = "(.*)([\\s\\S]*)i2c-(.*)i2c(.*)I2C(.*)adapter(.*)([\\s\\S]*)";
70 |
71 | // i2cdetect to identify id-0, id-1, id-2, ...;
72 | if (true == matchPattern(s, pattern_stdout_i2cbus)){
73 | String s_split[] = s.split("i2c-");
74 | for (int i=0; i 0
77 | if (s_split[i].length() > 0){
78 | buslist.add(String.valueOf(s_split[i].charAt(0)));
79 | }
80 | }
81 | return true;
82 | }
83 | return false;
84 | }
85 |
86 |
87 | /*
88 | * i2cdetect -y 2
89 | * output example is:
90 | 0 1 2 3 4 5 6 7 8 9 a b c d e f
91 | 00: -- -- -- -- -- -- -- -- -- -- -- -- --
92 | 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
93 | 20: -- -- -- -- -- -- -- -- -- 29 -- -- -- -- -- --
94 | 30: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
95 | 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
96 | 50: -- -- UU -- -- -- -- -- -- -- -- -- -- -- -- --
97 | 60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- --
98 | 70: -- -- -- -- -- -- -- --
99 | * "--". The address was probed but no chip answered.
100 | * "UU". Probing was skipped, because this address is currently in use by a driver.
101 | * This strongly suggests that there is a chip at this address.
102 | * An address number in hexadecimal, e.g. "2d" or "4e".
103 | * A chip was found at this address.
104 | */
105 | public static boolean StdoutMatch_I2CDevDetect(String s, List devlist, String busnum){
106 | String pattern_stdout_i2cdev =
107 | "(.*)([\\s\\S]*)(.*)00:(.*)--([\\s\\S]*)";
108 |
109 | // i2cdetect to identify device attach to bus
110 | if (true == matchPattern(s, pattern_stdout_i2cdev)){
111 | //
112 | List i2c_dev_list = new ArrayList();
113 | //
114 | char[] tempchar = new char[2];
115 |
116 | //split by "\r\n", then parse every line.
117 | //Because line length is difference, is difficult to parse.
118 | String s_split[] = s.split("\r\n");
119 | //for (int i=0; i parseI2cDumpMode_W(ArrayListlist){
175 | if (list == null || list.size() == 0) {
176 | return null;
177 | }
178 | if (!matchPattern(list.get(0), I2C_DUMP_MODE_W_PATTERN)){
179 | return null;
180 | }
181 |
182 | ArrayList result = new ArrayList();
183 | //parse every line.
184 | //Because line length is difference, is difficult to parse.
185 | char[] tempchar = new char[2]; //从特定位置连续取2个字符
186 | int char_index; //字符在文本行中的下标;
187 | int x; //i2cdump stdout列序号, 0~15总计16列;
188 | int y; //i2cdump stdout行序号, 0~16 总计17行,数据是1~16行
189 | int dumpindex; //字节在数组中的下标
190 |
191 | int y_first = Integer.valueOf(String.valueOf(list.get(1).charAt(0)), 16);
192 | String tempstr = new String("");
193 |
194 | dumpindex = y_first*16;
195 | //遍历行
196 | for (y=1; y stream) {
198 | // write log raw file
199 | String newResult = "";
200 | for (String str : stream) {
201 | newResult += str + "\r\n";
202 | }
203 | LogFileHelper.get().writeFile(mLogRawFile, newResult);
204 |
205 | // write log parsed file
206 | ArrayList parsedStream = I2cParserHelper.parseI2cDumpMode_W(stream);
207 | if (parsedStream != null) {
208 | LogFileHelper.get().writeFile(mLogParsedFile,
209 | LogFileHelper.get().timestamp(LogFileHelper.TIME_FORMATTER_HMS)
210 | + " - "
211 | + TextUtils.join(" ", parsedStream));
212 | }
213 |
214 | // update console view
215 | if (mConsoleTv.getLineCount() + stream.size() > mConsoleMaxLines) {
216 | mConsoleTv.setText("");
217 | }
218 | String result = mConsoleTv.getText().toString() + "\r\n" + newResult;
219 | mConsoleTv.setText(result);
220 | mConsoleScroll.postDelayed(new Runnable() { // delay to scrolling down completely
221 | @Override
222 | public void run() {
223 | mConsoleScroll.fullScroll(ScrollView.FOCUS_DOWN);
224 | }
225 | }, 100);
226 | }
227 |
228 | private void detect() {
229 | mI2cToolHelper.doDetect();
230 | }
231 |
232 | private void set(int dataAddress, int value, String mode) {
233 | mI2cToolHelper.doSet(mI2cBus, mI2cAddress, dataAddress, value, mode);
234 | }
235 |
236 | private void dump() {
237 | mI2cToolHelper.doDump(mI2cBus, mI2cAddress, mI2cMode);
238 | }
239 |
240 | private ScheduledExecutorService mExecutorService = Executors.newSingleThreadScheduledExecutor();
241 | private ScheduledFuture> mScheduledFuture;
242 |
243 | private void scheduleDump() {
244 | stopScheduleDump();
245 | if (!mExecutorService.isShutdown()) {
246 | mScheduledFuture = mExecutorService.scheduleAtFixedRate(new Runnable() {
247 | @Override
248 | public void run() {
249 | mHandler.post(mDumpTask);
250 | }
251 | }, 0, mLoopInterval, TimeUnit.MILLISECONDS);
252 | }
253 | }
254 |
255 | private void stopScheduleDump() {
256 | if (mScheduledFuture != null) {
257 | mScheduledFuture.cancel(false);
258 | }
259 | }
260 |
261 | private final Runnable mDumpTask = new Runnable() {
262 | @Override
263 | public void run() {
264 | dump();
265 | }
266 | };
267 |
268 | private OnStreamParsedListener mOnStreamParsedListener = new OnStreamParsedListener() {
269 | @Override
270 | public void onStreamParsed(int streamType, ArrayList stream) {
271 | // stream is not null
272 | updateConsoleView(stream);
273 | }
274 | };
275 | }
276 |
--------------------------------------------------------------------------------