1
0
Fork 0

android: vendor: add friendlyelec (demo) apps

Signed-off-by: hmz007 <hmz007@gmail.com>
Change-Id: Ic80ac4a7eaa40bad588345f2103e44cb42ea4586
master
hmz007 2 years ago
parent 7759120fce
commit 9767d666af

@ -0,0 +1,14 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := ADCDemo
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_PRIVILEGED_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -lfriendlyarm-things
include $(BUILD_PACKAGE)

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.friendlyarm.ADCDemo"
coreApp="true"
android:sharedUserId="android.uid.system">
<!-- Android4.4, Android7.1 -->
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="25"
android:maxSdkVersion="25" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="ADCDemoMainActivity"
android:label="@string/ADCReaderActivityTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/listTextView1"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="18px"
android:paddingLeft="20dip"
/>
<TextView
android:id="@+id/listTextView2"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="18px"
android:gravity="right"
android:textColor="#FF7F00"
android:paddingRight="20dip"
/>
</LinearLayout>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView android:id="@+id/listView1" android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ADC Sample</string>
<string name="ADCReaderActivityTitle">ADC Sample</string>
</resources>

@ -0,0 +1,30 @@
package com.friendlyarm.ADCDemo;
public class ADC {
int value = 0;
String name = null;
public ADC(int value, String name) {
super();
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

@ -0,0 +1,221 @@
package com.friendlyarm.ADCDemo;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.io.BufferedWriter;
import android.os.Message;
import android.os.Handler;
import android.os.Looper;
import java.io.*;
import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.BoardType;
public class ADCDemoMainActivity extends Activity {
MyCustomAdapter dataAdapter = null;
private static final String TAG = "ADCDemo";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.adc_main);
Log.d("ADCDemo", "BoardID: " + mBoardType);
timer.schedule(task, 0, 500);
}
static int readNumFromFile(String path, String fileName) {
int result = 0;
File file = new File(path,fileName);
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line = br.readLine();
br.close();
try {
result = Integer.parseInt(line);
} catch(NumberFormatException nfe) {
System.out.println("Could not parse " + nfe);
result = 0;
}
}
catch (IOException e) {
//You'll need to add proper error handling here
}
return result;
}
private int mBoardType = HardwareControler.getBoardType();
private Timer timer = new Timer();
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
// Array list of countries
ArrayList<ADC> adcValueList = new ArrayList<ADC>();
switch (msg.what) {
case 1:
if (mBoardType > BoardType.RK3399_BASE && mBoardType <= BoardType.RK3399_MAX) {
//path:
//ADC
//in_voltage0_raw
//in_voltage2_raw
//in_voltage3_raw
int[] channels = { 0, 2, 3 };
int[] adc = { 0, 0, 0 };
final String path = "/sys/devices/platform/ff100000.saradc/iio:device0";
adc[0] = readNumFromFile(path, "in_voltage0_raw");
adc[1] = readNumFromFile(path, "in_voltage2_raw");
adc[2] = readNumFromFile(path, "in_voltage3_raw");
for (int i = 0; i < 3; i++) {
ADC adcObj = new ADC(adc[i], String.format("[AIN%d]",
channels[i]));
adcValueList.add(adcObj);
}
} else if (mBoardType > BoardType.RK3568_BASE && mBoardType <= BoardType.RK3568_MAX) {
int channel = 2;
int adc = 0;
final String path = "/sys/devices/platform/fe720000.saradc/iio:device0";
adc = readNumFromFile(path, "in_voltage2_raw");
ADC adcObj = new ADC(adc, String.format("[AIN%d]",channel));
adcValueList.add(adcObj);
} else if (mBoardType > BoardType.RK3588_BASE && mBoardType <= BoardType.RK3588_MAX) {
int channel = 2;
int adc = 0;
final String path = "/sys/devices/platform/fec10000.saradc/iio:device0";
adc = readNumFromFile(path, "in_voltage2_raw");
ADC adcObj = new ADC(adc, String.format("[AIN%d]",channel));
adcValueList.add(adcObj);
} else if (mBoardType == BoardType.S3C6410_COMMON) {
int[] channels = { 0, 1, 4, 5, 6, 7 };
int[] adc = HardwareControler.readADCWithChannels(channels);
for (int i = 0; i < 6; i++) {
ADC adcObj = new ADC(adc[i], String.format("[AIN%d]",
channels[i]));
adcValueList.add(adcObj);
}
} else if (mBoardType == BoardType.S5PV210_COMMON) {
int[] channels = { 0, 1, 6, 7, 8, 9 };
int[] adc = HardwareControler.readADCWithChannels(channels);
for (int i = 0; i < 6; i++) {
ADC adcObj = new ADC(adc[i], String.format("[AIN%d]",
channels[i]));
adcValueList.add(adcObj);
}
} else if (mBoardType == BoardType.S5P4412_COMMON) {
int[] channels = { 0, 1, 2, 3 };
int[] adc = HardwareControler.readADCWithChannels(channels);
for (int i = 0; i < 4; i++) {
ADC adcObj = new ADC(adc[i], String.format("[AIN%d]",
channels[i]));
adcValueList.add(adcObj);
}
} else if (mBoardType == BoardType.Smart4418SDK) {
int[] channels = { 1, 3, 4, 5, 6, 7 };
int[] adc = HardwareControler.readADCWithChannels(channels);
for (int i = 0; i < channels.length; i++) {
ADC adcObj = new ADC(adc[i], String.format("[AIN%d]",
channels[i]));
adcValueList.add(adcObj);
}
} else {
int adc = HardwareControler.readADCWithChannel(0);
ADC adcObj = new ADC(adc, String.format("[AIN%d]", 0));
adcValueList.add(adcObj);
}
dataAdapter = new MyCustomAdapter(getApplicationContext(),
R.layout.adc_listview_item, adcValueList);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(dataAdapter);
break;
}
super.handleMessage(msg);
}
};
private TimerTask task = new TimerTask() {
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
private class MyCustomAdapter extends ArrayAdapter<ADC> {
private ArrayList<ADC> adcValueList;
public MyCustomAdapter(Context context, int textViewResourceId,
ArrayList<ADC> adcValueList) {
super(context, textViewResourceId, adcValueList);
this.adcValueList = new ArrayList<ADC>();
this.adcValueList.addAll(adcValueList);
}
private class ViewHolder {
TextView nameTextView;
TextView valueTextView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.adc_listview_item, null);
holder = new ViewHolder();
holder.nameTextView = (TextView) convertView
.findViewById(R.id.listTextView1);
holder.valueTextView = (TextView) convertView
.findViewById(R.id.listTextView2);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ADC adcObj = adcValueList.get(position);
if (holder.nameTextView != null) {
holder.nameTextView.setText(adcObj.getName());
}
if (holder.valueTextView != null) {
holder.valueTextView.setText(String.valueOf(adcObj.getValue()));
}
return convertView;
}
}
}

@ -0,0 +1,107 @@
package com.friendlyarm.FriendlyThings;
public class BoardType {
/* getBoardType return value: */
public static final int S3C6410_COMMON = 6410;
public static final int S5PV210_COMMON = 210;
public static final int S5P4412_COMMON = 4412;
//s5p4418
public static final int S5P4418_BASE = 4418;
public static final int NanoPi2 = S5P4418_BASE+0;
public static final int NanoPC_T2 = S5P4418_BASE+1;
public static final int NanoPi_S2 = S5P4418_BASE+2;
public static final int Smart4418 = S5P4418_BASE+3;
public static final int NanoPi2_Fire = S5P4418_BASE+4;
public static final int NanoPi_M2 = S5P4418_BASE+5;
public static final int NanoPi_M2A = S5P4418_BASE+7;
public static final int Smart4418SDK = S5P4418_BASE+0x103;
public static final int S5P4418_MAX = Smart4418SDK;
//s5p6818
public static final int S5P6818_BASE = 6818;
public static final int NanoPC_T3 = S5P6818_BASE+1;
public static final int NanoPi_M3B = S5P6818_BASE+2;
public static final int Smart6818 = S5P6818_BASE+3;
public static final int NanoPC_T3T = S5P6818_BASE+4;
public static final int NanoPi_Fire3 = S5P6818_BASE+5;
public static final int NanoPi_M3 = S5P6818_BASE+7;
public static final int S5P6818_MAX = NanoPi_M3;
//s3c2451
public static final int S3C2451_BASE = 2451;
public static final int S3C2451_COMMON = S3C2451_BASE+0;
//allwinner
public static final int ALLWINNER_BASE = 7000;
public static final int NanoPi_M1 = ALLWINNER_BASE+1;
public static final int NanoPi_NEO = ALLWINNER_BASE+2;
public static final int NanoPi_NEO_Air = ALLWINNER_BASE+3;
public static final int NanoPi_M1_Plus = ALLWINNER_BASE+4;
public static final int NanoPi_A64 = ALLWINNER_BASE+5;
public static final int NanoPi_NEO2 = ALLWINNER_BASE+6;
public static final int NanoPi_M1_Plus2 = ALLWINNER_BASE+7;
public static final int NanoPi_NEO_Plus2 = ALLWINNER_BASE+8;
public static final int NanoPi_NEO_Core = ALLWINNER_BASE+9;
public static final int NanoPi_Duo = ALLWINNER_BASE+10;
public static final int NanoPi_NEO_Core2 = ALLWINNER_BASE+11;
public static final int NanoPi_K1 = ALLWINNER_BASE+12;
public static final int NanoPi_K1_Plus = ALLWINNER_BASE+13;
public static final int NanoPi_Hero = ALLWINNER_BASE+14;
public static final int NanoPi_Duo2 = ALLWINNER_BASE+15;
public static final int NanoPi_R1 = ALLWINNER_BASE+16;
public static final int NanoPi_C3 = ALLWINNER_BASE+17;
public static final int NanoPi_NEO2_Black = ALLWINNER_BASE+18;
public static final int NanoPi_NEO_S = ALLWINNER_BASE+19;
public static final int ZeroPi = ALLWINNER_BASE+20;
public static final int NanoPi_R1S_H3 = ALLWINNER_BASE+21;
public static final int NanoPi_R1S_H5 = ALLWINNER_BASE+22;
public static final int ALLWINNER_MAX = NanoPi_R1S_H5;
//amlogic
public static final int AMLOGIC_BASE = 8000;
public static final int NanoPi_K2 = AMLOGIC_BASE+1;
//rk3399
public static final int RK3399_BASE = 9000;
public static final int NanoPC_T4 = RK3399_BASE+1;
public static final int NanoPi_M4 = RK3399_BASE+2;
public static final int NanoPi_NEO4 = RK3399_BASE+3;
public static final int SOM_RK3399 = RK3399_BASE+4;
public static final int NanoPi_M4v2 = RK3399_BASE+5;
public static final int NanoPi_M4B = RK3399_BASE+6;
public static final int SOM_RK3399v2 = RK3399_BASE+7;
public static final int NanoPi_NEO4v2 = RK3399_BASE+8;
public static final int NanoPi_R4S = RK3399_BASE+9;
public static final int NanoPC_T4B = RK3399_BASE+10;
public static final int NanoPi_R4S_Plus = RK3399_BASE+11;
public static final int NanoPi_R4SE = RK3399_BASE+12;
public static final int RK3399_MAX = NanoPi_R4SE;
//rk3328
public static final int RK3328_BASE = 9500;
public static final int NanoPi_R2S = RK3328_BASE+1;
public static final int NanoPi_NEO3_Black = RK3328_BASE+2;
public static final int NanoPi_NEO3_S = RK3328_BASE+3;
public static final int NanoPi_NEO3 = RK3328_BASE+4;
public static final int NanoPi_R2Pro = RK3328_BASE+5;
public static final int NanoPi_R2C = RK3328_BASE+6;
public static final int NanoPi_R2C_Plus = RK3328_BASE+7;
public static final int NanoPi_R2S_Plus = RK3328_BASE+8;
public static final int Core3328 = RK3328_BASE+9;
public static final int RK3328_MAX = Core3328;
//rk3568
public static final int RK3568_BASE = 9600;
public static final int NanoPi_R5S = RK3568_BASE+1;
public static final int NanoPi_R5C = RK3568_BASE+2;
public static final int NanoPi_R5S_LTS = RK3568_BASE+3;
public static final int RK3568_MAX = NanoPi_R5S_LTS;
//rk3588
public static final int RK3588_BASE = 9700;
public static final int NanoPi_R6S = RK3588_BASE+1;
public static final int NanoPC_T6 = RK3588_BASE+2;
public static final int NanoPi_R6C = RK3588_BASE+3;
public static final int RK3588_MAX = NanoPi_R6C;
}

@ -0,0 +1,23 @@
package com.friendlyarm.FriendlyThings;
public class FileCtlEnum {
/* File Flag */
public final static int O_ACCMODE = 00000003;
public final static int O_RDONLY = 00000000;
public final static int O_WRONLY = 00000001;
public final static int O_RDWR = 00000002;
public final static int O_CREAT = 00000100; /* not fcntl */
public final static int O_EXCL = 00000200; /* not fcntl */
public final static int O_NOCTTY = 00000400; /* not fcntl */
public final static int O_TRUNC = 00001000; /* not fcntl */
public final static int O_APPEND = 00002000;
public final static int O_NONBLOCK = 00004000;
public final static int O_DSYNC = 00010000; /* used to be O_SYNC, see below */
public final static int FASYNC = 00020000; /* fcntl, for BSD compatibility */
public final static int O_DIRECT = 00040000; /* direct disk access hint */
public final static int O_LARGEFILE = 00100000;
public final static int O_DIRECTORY = 00200000; /* must be a directory */
public final static int O_NOFOLLOW = 00400000; /* don't follow links */
public final static int O_NOATIME = 01000000;
public final static int O_CLOEXEC = 02000000; /* set close_on_exec */
}

@ -0,0 +1,43 @@
package com.friendlyarm.FriendlyThings;
/*
GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
and have the following read/write attributes:
/sys/class/gpio/gpioN/
"direction" ... reads as either "in" or "out". This value may
normally be written. Writing as "out" defaults to
initializing the value as low. To ensure glitch free
operation, values "low" and "high" may be written to
configure the GPIO as an output with that initial value.
Note that this attribute *will not exist* if the kernel
doesn't support changing the direction of a GPIO, or
it was exported by kernel code that didn't explicitly
allow userspace to reconfigure this GPIO's direction.
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as high.
If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, either lseek(2) to the beginning of the sysfs
file and read the new value or close the file and re-open it
to read the value.
*/
public class GPIOEnum {
//Direction
public final static int IN = 1;
public final static int OUT = 2;
//Value
public final static int LOW = 0;
public final static int HIGH = 1;
}

@ -0,0 +1,89 @@
package com.friendlyarm.FriendlyThings;
import android.util.Log;
public class HardwareControler
{
/* I/O */
static public native int open(String devName, int flags);
static public native int write(int fd, byte[] data);
static public native int read(int fd, byte[] buf, int len);
static public native int select(int fd, int sec, int usec);
static public native void close(int fd);
static public native int ioctlWithIntValue(int fd, int cmd, int value);
static public native int ioctl(int fd, int cmd, byte[] buf);
/* Serial Port */
static public native int openSerialPort( String devName, long baud, int dataBits, int stopBits );
static public native int openSerialPortEx( String devName
, long baud
, int dataBits
, int stopBits
, String parityBit
, String flowCtrl
);
/* LED */
static public native int setLedState( int ledID, int ledState );
/* PWM */
static public native int PWMPlay(int frequency);
static public native int PWMStop();
static public native int PWMPlayEx(int gpioPin, int frequency);
static public native int PWMStopEx(int gpioPin);
/* ADC */
static public native int readADC();
static public native int readADCWithChannel(int channel);
static public native int[] readADCWithChannels(int[] channels);
/* I2C */
static public native int setI2CSlave(int fd, int slave);
static public native int setI2CTimeout(int fd, int timeout);
static public native int setI2CRetries(int fd, int retries);
static public native int I2CReadByteData(int fd, int pos, int wait_us);
static public native int I2CReadByte(int fd, int wait_us);
static public native int I2CWriteByteData(int fd, int pos, byte byteData, int wait_us);
static public native int I2CWriteByte(int fd, byte byteData, int wait_us);
/* Discard */ static public native int readByteFromI2C(int fd, int pos, int wait_ms);
/* Discard */ static public native int writeByteToI2C(int fd, int pos, byte byteData, int wait_ms);
/* Discard */ static public native int writeByteToI2C2(int fd, byte byteData, int wait_ms);
/* SPI */
static public native int setSPIWriteBitsPerWord( int spi_fd, int bits );
static public native int setSPIReadBitsPerWord( int spi_fd, int bits );
static public native int setSPIBitOrder( int spi_fd, int order);
static public native int setSPIClockDivider( int spi_fd, int divider);
static public native int setSPIMaxSpeed( int spi_fd, int spi_speed);
static public native int setSPIDataMode( int spi_fd, int mode);
static public native int SPItransferOneByte( int spi_fd, byte byteData, int spi_delay, int spi_speed, int spi_bits);
static public native int SPItransferBytes(int spi_fd, byte[] writeData, byte[] readBuff, int spi_delay, int spi_speed, int spi_bits);
static public native int writeBytesToSPI(int spi_fd, byte[] writeData, int spi_delay, int spi_speed, int spi_bits);
static public native int readBytesFromSPI(int spi_fd, byte[] readBuff, int spi_delay, int spi_speed, int spi_bits);
/* GPIO */
static public native int exportGPIOPin(int pin);
static public native int unexportGPIOPin(int pin);
//GPIOEnum.LOW or GPIOEnum.HIGH
static public native int setGPIOValue(int pin, int value);
static public native int getGPIOValue(int pin);
//GPIOEnum.IN or GPIOEnum.OUT
static public native int setGPIODirection(int pin, int direction);
static public native int getGPIODirection(int pin);
/* OldInterface: for EEPROM */
static public native int openI2CDevice();
static public native int writeByteDataToI2C(int fd, int pos, byte byteData);
static public native int readByteDataFromI2C(int fd, int pos);
/* return BoardType.xxx */
static public native int getBoardType();
static {
try {
System.loadLibrary("friendlyarm-things");
} catch (UnsatisfiedLinkError e) {
Log.d("HardwareControler", "libfriendlyarm-things library not found!");
}
}
}

@ -0,0 +1,108 @@
package com.friendlyarm.FriendlyThings;
import android.util.Log;
import android.widget.Toast;
import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.SPIEnum;
import com.friendlyarm.FriendlyThings.GPIOEnum;
import com.friendlyarm.FriendlyThings.FileCtlEnum;
public class SPI {
private static final String TAG = "com.friendlyarm.FriendlyThings.SPI";
private int spi_mode = 0;
private int spi_bits = 8;
private int spi_delay = 0;
private int spi_speed = 500000;
private int spi_byte_order = SPIEnum.LSBFIRST;
private static final String devName = "/dev/spidev1.0";
private int spi_fd = -1;
public void begin() {
spi_fd = HardwareControler.open( devName, FileCtlEnum.O_RDWR );
if (spi_fd >= 0) {
Log.d(TAG, "open " + devName + "ok!");
/* spi init */
HardwareControler.setSPIWriteBitsPerWord( spi_fd, spi_bits );
HardwareControler.setSPIReadBitsPerWord( spi_fd, spi_bits );
} else {
Log.d(TAG, "open " + devName + "failed!");
spi_fd = -1;
}
}
public void end() {
if (spi_fd != -1) {
HardwareControler.close(spi_fd);
spi_fd = -1;
}
}
public void setBitOrder(int order) {
if (spi_fd < 0) {
return ;
}
spi_byte_order = SPIEnum.MSBFIRST;
if(spi_byte_order == SPIEnum.LSBFIRST) {
spi_mode |= SPIEnum.SPI_LSB_FIRST;
} else {
spi_mode &= ~SPIEnum.SPI_LSB_FIRST;
}
HardwareControler.setSPIBitOrder( spi_fd, spi_byte_order );
}
public void setClockDivider(int divider) {
if (spi_fd < 0) {
return ;
}
spi_speed = 66666666/(2*(divider+1));
if(spi_speed > 500000) {
spi_speed = 500000;
}
HardwareControler.setSPIClockDivider( spi_fd, divider);
}
public void setDataMode(int mode) {
if (spi_fd < 0) {
return ;
}
switch(mode)
{
case SPIEnum.SPI_MODE0:
spi_mode &= ~(SPIEnum.SPI_CPHA|SPIEnum.SPI_CPOL);
break;
case SPIEnum.SPI_MODE1:
spi_mode &= ~(SPIEnum.SPI_CPOL);
spi_mode |= (SPIEnum.SPI_CPHA);
break;
case SPIEnum.SPI_MODE2:
spi_mode |= (SPIEnum.SPI_CPOL);
spi_mode &= ~(SPIEnum.SPI_CPHA);
break;
case SPIEnum.SPI_MODE3:
spi_mode |= (SPIEnum.SPI_CPHA|SPIEnum.SPI_CPOL);
break;
default:
Log.e(TAG, "error data mode");
}
HardwareControler.setSPIDataMode( spi_fd, spi_mode );
}
public void setChipSelectPolarity(int cs, int active) {
}
public void chipSelect(int cs) {
}
public byte transfer(int value) {
if (spi_fd < 0) {
return 0;
}
return (byte) HardwareControler.SPItransferOneByte(spi_fd, (byte) value, spi_delay, spi_speed, spi_bits);
}
}

@ -0,0 +1,42 @@
package com.friendlyarm.FriendlyThings;
public class SPIEnum {
// SPIBitOrder
public final static int LSBFIRST = 0; ///< LSB First
public final static int MSBFIRST = 1; ///< MSB First
// SPIMode
public final static int SPI_MODE0 = 0; ///< CPOL = 0, CPHA = 0
public final static int SPI_MODE1 = 1; ///< CPOL = 0, CPHA = 1
public final static int SPI_MODE2 = 2; ///< CPOL = 1, CPHA = 0
public final static int SPI_MODE3 = 3; ///< CPOL = 1, CPHA = 1
public final static int SPI_CPHA = 0x01;
public final static int SPI_CPOL = 0x02;
public final static int SPI_CS_HIGH = 0x04;
public final static int SPI_LSB_FIRST = 0x08;
public final static int SPI_3WIRE = 0x10;
public final static int SPI_LOOP = 0x20;
public final static int SPI_NO_CS = 0x40;
public final static int SPI_READY = 0x80;
// SPIClockDivider
public final static int SPI_CLOCK_DIV65536 = 0; ///< 65536 = 256us = 4kHz
public final static int SPI_CLOCK_DIV32768 = 32768; ///< 32768 = 126us = 8kHz
public final static int SPI_CLOCK_DIV16384 = 16384; ///< 16384 = 64us = 15.625kHz
public final static int SPI_CLOCK_DIV8192 = 8192; ///< 8192 = 32us = 31.25kHz
public final static int SPI_CLOCK_DIV4096 = 4096; ///< 4096 = 16us = 62.5kHz
public final static int SPI_CLOCK_DIV2048 = 2048; ///< 2048 = 8us = 125kHz
public final static int SPI_CLOCK_DIV1024 = 1024; ///< 1024 = 4us = 250kHz
public final static int SPI_CLOCK_DIV512 = 512; ///< 512 = 2us = 500kHz
public final static int SPI_CLOCK_DIV256 = 256; ///< 256 = 1us = 1MHz
public final static int SPI_CLOCK_DIV128 = 128; ///< 128 = 500ns = = 2MHz
public final static int SPI_CLOCK_DIV64 = 64; ///< 64 = 250ns = 4MHz
public final static int SPI_CLOCK_DIV32 = 32; ///< 32 = 125ns = 8MHz
public final static int SPI_CLOCK_DIV16 = 16; ///< 16 = 50ns = 20MHz
public final static int SPI_CLOCK_DIV8 = 8; ///< 8 = 25ns = 40MHz
public final static int SPI_CLOCK_DIV4 = 4; ///< 4 = 12.5ns 80MHz
public final static int SPI_CLOCK_DIV2 = 2; ///< 2 = 6.25ns = 160MHz
public final static int SPI_CLOCK_DIV1 = 1; ///< 0 = 256us = 4kHz
}

@ -0,0 +1,37 @@
package com.friendlyarm.FriendlyThings;
public class WatchDogEnum {
/* include/uapi/linux/watchdog.h */
public final static int WDIOC_GETSUPPORT = 0x80285700;
public final static int WDIOC_GETSTATUS = 0x80045701;
public final static int WDIOC_GETBOOTSTATUS = 0x80045702;
public final static int WDIOC_GETTEMP = 0x80045703;
public final static int WDIOC_SETOPTIONS = 0x80045704;
public final static int WDIOC_KEEPALIVE = 0x80045705;
public final static int WDIOC_SETTIMEOUT = 0xC0045706;
public final static int WDIOC_GETTIMEOUT = 0x80045707;
public final static int WDIOC_SETPRETIMEOUT = 0xC0045708;
public final static int WDIOC_GETPRETIMEOUT = 0x80045709;
public final static int WDIOC_GETTIMELEFT = 0x8004570A;
public final static int WDIOF_UNKNOWN = -1; /* Unknown flag error */
public final static int WDIOS_UNKNOWN = -1; /* Unknown status error */
public final static int WDIOF_OVERHEAT = 0x0001; /* Reset due to CPU overheat */
public final static int WDIOF_FANFAULT = 0x0002; /* Fan failed */
public final static int WDIOF_EXTERN1 = 0x0004; /* External relay 1 */
public final static int WDIOF_EXTERN2 = 0x0008; /* External relay 2 */
public final static int WDIOF_POWERUNDER = 0x0010; /* Power bad/power fault */
public final static int WDIOF_CARDRESET = 0x0020; /* Card previously reset the CPU */
public final static int WDIOF_POWEROVER = 0x0040; /* Power over voltage */
public final static int WDIOF_SETTIMEOUT = 0x0080; /* Set timeout (in seconds) */
public final static int WDIOF_MAGICCLOSE = 0x0100; /* Supports magic close char */
public final static int WDIOF_PRETIMEOUT = 0x0200; /* Pretimeout (in seconds), get/set */
public final static int WDIOF_ALARMONLY = 0x0400; /* Watchdog triggers a management or other external alarm not a reboot */
public final static int WDIOF_KEEPALIVEPING = 0x8000; /* Keep alive ping reply */
public final static int WDIOS_DISABLECARD = 0x0001; /* Turn off the watchdog timer */
public final static int WDIOS_ENABLECARD = 0x0002; /* Turn on the watchdog timer */
public final static int WDIOS_TEMPPANIC = 0x0004; /* Kernel panic on temperature trip */
}

@ -0,0 +1,26 @@
package com.friendlyarm.Utils;
import android.app.Activity;
import android.app.AlertDialog;
import android.widget.Toast;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.content.Context;
import android.content.DialogInterface;
public class CommonFuncs {
public static void showAlertDialog(Context context, String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(message)
.setCancelable(false)
.setPositiveButton("Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
}

@ -0,0 +1,3 @@
#!/bin/bash
adb disable-verity; adb root; adb remount; adb sync; adb reboot;

@ -0,0 +1,15 @@
#
# Copyright 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

@ -0,0 +1,14 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := GPIO_LED_Demo
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_PRIVILEGED_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -lfriendlyarm-things
include $(BUILD_PACKAGE)

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.friendlyarm.GPIODemo"
coreApp="true"
android:sharedUserId="android.uid.system">
<!-- Android4.4, Android7.1 -->
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="25"
android:maxSdkVersion="25" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="GPIODemoMainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- 高度40 -->
<size android:height="40dp" android:width="40dp"/>
<!-- 圆角弧度 20 -->
<corners android:radius="20dp"/>
<!-- 变化率 -->
<gradient
android:endColor="#eeeeee"
android:startColor="#eeeeee" />
<stroke android:width="1dp"
android:color="#666666"/>
</shape>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- 高度30 此处设置宽度无效-->
<size android:height="20dp"/>
<!-- 圆角弧度 15 -->
<corners android:radius="10dp"/>
<!-- 变化率 定义从左到右的颜色不变 -->
<gradient
android:endColor="#888888"
android:startColor="#888888" />
</shape>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- 高度40 -->
<size android:height="40dp" android:width="40dp"/>
<!-- 圆角弧度 20 -->
<corners android:radius="20dp"/>
<!-- 变化率 -->
<gradient
android:endColor="#eeeeee"
android:startColor="#eeeeee" />
<stroke android:width="1dp"
android:color="#33da33"/>
</shape>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 高度40 -->
<size android:height="20dp"/>
<!-- 圆角弧度 20 -->
<corners android:radius="10dp"/>
<!-- 变化率 -->
<gradient
android:endColor="#33da33"
android:startColor="#33da33" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- 高度40 -->
<size android:height="40dp" android:width="40dp"/>
<!-- 圆角弧度 20 -->
<corners android:radius="20dp"/>
<!-- 变化率 -->
<gradient
android:endColor="#da3333"
android:startColor="#da3333" />
<stroke android:width="1dp"
android:color="#da3333"/>
</shape>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 按钮的选择器,可以设置按钮在不同状态下的时候,按钮不同的颜色 -->
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true" android:drawable="@drawable/green_thumb" />
<item android:drawable="@drawable/gray_thumb" />
</selector>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 底层下滑条的样式选择器可控制Switch在不同状态下底下下滑条的颜色 -->
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true" android:drawable="@drawable/green_track" />
<item android:drawable="@drawable/gray_track" />
</selector>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView android:id="@+id/listView1" android:layout_width="fill_parent"
android:layout_height="0dp" android:layout_weight="1" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:orientation="vertical"
android:gravity="bottom"
android:layout_alignParentBottom="true"
android:layout_marginTop="20dp">
<Button
android:onClick="onMoreSamplesPressed"
android:id="@+id/btn_morebutton"
android:text="@string/moreSamplesButtonText"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
</Button>
</LinearLayout>
</LinearLayout>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dip" >
<Switch
android:id="@+id/pin_switch"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:switchMinWidth="20dp"
android:textOn="High"
android:textOff="Low"
android:textSize="20sp"
android:showText="true"
android:thumb="@drawable/thumb"
android:track="@drawable/track" />
</RelativeLayout>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">GPIO Sample</string>
<string name="MainActivityTitle">GPIO Sample</string>
<string name="ledtext">LED</string>
<string name="moreSamplesButtonText">More samples? \nClick here</string>
</resources>

@ -0,0 +1,107 @@
package com.friendlyarm.FriendlyThings;
public class BoardType {
/* getBoardType return value: */
public static final int S3C6410_COMMON = 6410;
public static final int S5PV210_COMMON = 210;
public static final int S5P4412_COMMON = 4412;
//s5p4418
public static final int S5P4418_BASE = 4418;
public static final int NanoPi2 = S5P4418_BASE+0;
public static final int NanoPC_T2 = S5P4418_BASE+1;
public static final int NanoPi_S2 = S5P4418_BASE+2;
public static final int Smart4418 = S5P4418_BASE+3;
public static final int NanoPi2_Fire = S5P4418_BASE+4;
public static final int NanoPi_M2 = S5P4418_BASE+5;
public static final int NanoPi_M2A = S5P4418_BASE+7;
public static final int Smart4418SDK = S5P4418_BASE+0x103;
public static final int S5P4418_MAX = Smart4418SDK;
//s5p6818
public static final int S5P6818_BASE = 6818;
public static final int NanoPC_T3 = S5P6818_BASE+1;
public static final int NanoPi_M3B = S5P6818_BASE+2;
public static final int Smart6818 = S5P6818_BASE+3;
public static final int NanoPC_T3T = S5P6818_BASE+4;
public static final int NanoPi_Fire3 = S5P6818_BASE+5;
public static final int NanoPi_M3 = S5P6818_BASE+7;
public static final int S5P6818_MAX = NanoPi_M3;
//s3c2451
public static final int S3C2451_BASE = 2451;
public static final int S3C2451_COMMON = S3C2451_BASE+0;
//allwinner
public static final int ALLWINNER_BASE = 7000;
public static final int NanoPi_M1 = ALLWINNER_BASE+1;
public static final int NanoPi_NEO = ALLWINNER_BASE+2;
public static final int NanoPi_NEO_Air = ALLWINNER_BASE+3;
public static final int NanoPi_M1_Plus = ALLWINNER_BASE+4;
public static final int NanoPi_A64 = ALLWINNER_BASE+5;
public static final int NanoPi_NEO2 = ALLWINNER_BASE+6;
public static final int NanoPi_M1_Plus2 = ALLWINNER_BASE+7;
public static final int NanoPi_NEO_Plus2 = ALLWINNER_BASE+8;
public static final int NanoPi_NEO_Core = ALLWINNER_BASE+9;
public static final int NanoPi_Duo = ALLWINNER_BASE+10;
public static final int NanoPi_NEO_Core2 = ALLWINNER_BASE+11;
public static final int NanoPi_K1 = ALLWINNER_BASE+12;
public static final int NanoPi_K1_Plus = ALLWINNER_BASE+13;
public static final int NanoPi_Hero = ALLWINNER_BASE+14;
public static final int NanoPi_Duo2 = ALLWINNER_BASE+15;
public static final int NanoPi_R1 = ALLWINNER_BASE+16;
public static final int NanoPi_C3 = ALLWINNER_BASE+17;
public static final int NanoPi_NEO2_Black = ALLWINNER_BASE+18;
public static final int NanoPi_NEO_S = ALLWINNER_BASE+19;
public static final int ZeroPi = ALLWINNER_BASE+20;
public static final int NanoPi_R1S_H3 = ALLWINNER_BASE+21;
public static final int NanoPi_R1S_H5 = ALLWINNER_BASE+22;
public static final int ALLWINNER_MAX = NanoPi_R1S_H5;
//amlogic
public static final int AMLOGIC_BASE = 8000;
public static final int NanoPi_K2 = AMLOGIC_BASE+1;
//rk3399
public static final int RK3399_BASE = 9000;
public static final int NanoPC_T4 = RK3399_BASE+1;
public static final int NanoPi_M4 = RK3399_BASE+2;
public static final int NanoPi_NEO4 = RK3399_BASE+3;
public static final int SOM_RK3399 = RK3399_BASE+4;
public static final int NanoPi_M4v2 = RK3399_BASE+5;
public static final int NanoPi_M4B = RK3399_BASE+6;
public static final int SOM_RK3399v2 = RK3399_BASE+7;
public static final int NanoPi_NEO4v2 = RK3399_BASE+8;
public static final int NanoPi_R4S = RK3399_BASE+9;
public static final int NanoPC_T4B = RK3399_BASE+10;
public static final int NanoPi_R4S_Plus = RK3399_BASE+11;
public static final int NanoPi_R4SE = RK3399_BASE+12;
public static final int RK3399_MAX = NanoPi_R4SE;
//rk3328
public static final int RK3328_BASE = 9500;
public static final int NanoPi_R2S = RK3328_BASE+1;
public static final int NanoPi_NEO3_Black = RK3328_BASE+2;
public static final int NanoPi_NEO3_S = RK3328_BASE+3;
public static final int NanoPi_NEO3 = RK3328_BASE+4;
public static final int NanoPi_R2Pro = RK3328_BASE+5;
public static final int NanoPi_R2C = RK3328_BASE+6;
public static final int NanoPi_R2C_Plus = RK3328_BASE+7;
public static final int NanoPi_R2S_Plus = RK3328_BASE+8;
public static final int Core3328 = RK3328_BASE+9;
public static final int RK3328_MAX = Core3328;
//rk3568
public static final int RK3568_BASE = 9600;
public static final int NanoPi_R5S = RK3568_BASE+1;
public static final int NanoPi_R5C = RK3568_BASE+2;
public static final int NanoPi_R5S_LTS = RK3568_BASE+3;
public static final int RK3568_MAX = NanoPi_R5S_LTS;
//rk3588
public static final int RK3588_BASE = 9700;
public static final int NanoPi_R6S = RK3588_BASE+1;
public static final int NanoPC_T6 = RK3588_BASE+2;
public static final int NanoPi_R6C = RK3588_BASE+3;
public static final int RK3588_MAX = NanoPi_R6C;
}

@ -0,0 +1,23 @@
package com.friendlyarm.FriendlyThings;
public class FileCtlEnum {
/* File Flag */
public final static int O_ACCMODE = 00000003;
public final static int O_RDONLY = 00000000;
public final static int O_WRONLY = 00000001;
public final static int O_RDWR = 00000002;
public final static int O_CREAT = 00000100; /* not fcntl */
public final static int O_EXCL = 00000200; /* not fcntl */
public final static int O_NOCTTY = 00000400; /* not fcntl */
public final static int O_TRUNC = 00001000; /* not fcntl */
public final static int O_APPEND = 00002000;
public final static int O_NONBLOCK = 00004000;
public final static int O_DSYNC = 00010000; /* used to be O_SYNC, see below */
public final static int FASYNC = 00020000; /* fcntl, for BSD compatibility */
public final static int O_DIRECT = 00040000; /* direct disk access hint */
public final static int O_LARGEFILE = 00100000;
public final static int O_DIRECTORY = 00200000; /* must be a directory */
public final static int O_NOFOLLOW = 00400000; /* don't follow links */
public final static int O_NOATIME = 01000000;
public final static int O_CLOEXEC = 02000000; /* set close_on_exec */
}

@ -0,0 +1,43 @@
package com.friendlyarm.FriendlyThings;
/*
GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
and have the following read/write attributes:
/sys/class/gpio/gpioN/
"direction" ... reads as either "in" or "out". This value may
normally be written. Writing as "out" defaults to
initializing the value as low. To ensure glitch free
operation, values "low" and "high" may be written to
configure the GPIO as an output with that initial value.
Note that this attribute *will not exist* if the kernel
doesn't support changing the direction of a GPIO, or
it was exported by kernel code that didn't explicitly
allow userspace to reconfigure this GPIO's direction.
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as high.
If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, either lseek(2) to the beginning of the sysfs
file and read the new value or close the file and re-open it
to read the value.
*/
public class GPIOEnum {
//Direction
public final static int IN = 1;
public final static int OUT = 2;
//Value
public final static int LOW = 0;
public final static int HIGH = 1;
}

@ -0,0 +1,89 @@
package com.friendlyarm.FriendlyThings;
import android.util.Log;
public class HardwareControler
{
/* I/O */
static public native int open(String devName, int flags);
static public native int write(int fd, byte[] data);
static public native int read(int fd, byte[] buf, int len);
static public native int select(int fd, int sec, int usec);
static public native void close(int fd);
static public native int ioctlWithIntValue(int fd, int cmd, int value);
static public native int ioctl(int fd, int cmd, byte[] buf);
/* Serial Port */
static public native int openSerialPort( String devName, long baud, int dataBits, int stopBits );
static public native int openSerialPortEx( String devName
, long baud
, int dataBits
, int stopBits
, String parityBit
, String flowCtrl
);
/* LED */
static public native int setLedState( int ledID, int ledState );
/* PWM */
static public native int PWMPlay(int frequency);
static public native int PWMStop();
static public native int PWMPlayEx(int gpioPin, int frequency);
static public native int PWMStopEx(int gpioPin);
/* ADC */
static public native int readADC();
static public native int readADCWithChannel(int channel);
static public native int[] readADCWithChannels(int[] channels);
/* I2C */
static public native int setI2CSlave(int fd, int slave);
static public native int setI2CTimeout(int fd, int timeout);
static public native int setI2CRetries(int fd, int retries);
static public native int I2CReadByteData(int fd, int pos, int wait_us);
static public native int I2CReadByte(int fd, int wait_us);
static public native int I2CWriteByteData(int fd, int pos, byte byteData, int wait_us);
static public native int I2CWriteByte(int fd, byte byteData, int wait_us);
/* Discard */ static public native int readByteFromI2C(int fd, int pos, int wait_ms);
/* Discard */ static public native int writeByteToI2C(int fd, int pos, byte byteData, int wait_ms);
/* Discard */ static public native int writeByteToI2C2(int fd, byte byteData, int wait_ms);
/* SPI */
static public native int setSPIWriteBitsPerWord( int spi_fd, int bits );
static public native int setSPIReadBitsPerWord( int spi_fd, int bits );
static public native int setSPIBitOrder( int spi_fd, int order);
static public native int setSPIClockDivider( int spi_fd, int divider);
static public native int setSPIMaxSpeed( int spi_fd, int spi_speed);
static public native int setSPIDataMode( int spi_fd, int mode);
static public native int SPItransferOneByte( int spi_fd, byte byteData, int spi_delay, int spi_speed, int spi_bits);
static public native int SPItransferBytes(int spi_fd, byte[] writeData, byte[] readBuff, int spi_delay, int spi_speed, int spi_bits);
static public native int writeBytesToSPI(int spi_fd, byte[] writeData, int spi_delay, int spi_speed, int spi_bits);
static public native int readBytesFromSPI(int spi_fd, byte[] readBuff, int spi_delay, int spi_speed, int spi_bits);
/* GPIO */
static public native int exportGPIOPin(int pin);
static public native int unexportGPIOPin(int pin);
//GPIOEnum.LOW or GPIOEnum.HIGH
static public native int setGPIOValue(int pin, int value);
static public native int getGPIOValue(int pin);
//GPIOEnum.IN or GPIOEnum.OUT
static public native int setGPIODirection(int pin, int direction);
static public native int getGPIODirection(int pin);
/* OldInterface: for EEPROM */
static public native int openI2CDevice();
static public native int writeByteDataToI2C(int fd, int pos, byte byteData);
static public native int readByteDataFromI2C(int fd, int pos);
/* return BoardType.xxx */
static public native int getBoardType();
static {
try {
System.loadLibrary("friendlyarm-things");
} catch (UnsatisfiedLinkError e) {
Log.d("HardwareControler", "libfriendlyarm-things library not found!");
}
}
}

@ -0,0 +1,108 @@
package com.friendlyarm.FriendlyThings;
import android.util.Log;
import android.widget.Toast;
import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.SPIEnum;
import com.friendlyarm.FriendlyThings.GPIOEnum;
import com.friendlyarm.FriendlyThings.FileCtlEnum;
public class SPI {
private static final String TAG = "com.friendlyarm.FriendlyThings.SPI";
private int spi_mode = 0;
private int spi_bits = 8;
private int spi_delay = 0;
private int spi_speed = 500000;
private int spi_byte_order = SPIEnum.LSBFIRST;
private static final String devName = "/dev/spidev1.0";
private int spi_fd = -1;
public void begin() {
spi_fd = HardwareControler.open( devName, FileCtlEnum.O_RDWR );
if (spi_fd >= 0) {
Log.d(TAG, "open " + devName + "ok!");
/* spi init */
HardwareControler.setSPIWriteBitsPerWord( spi_fd, spi_bits );
HardwareControler.setSPIReadBitsPerWord( spi_fd, spi_bits );
} else {
Log.d(TAG, "open " + devName + "failed!");
spi_fd = -1;
}
}
public void end() {
if (spi_fd != -1) {
HardwareControler.close(spi_fd);
spi_fd = -1;
}
}
public void setBitOrder(int order) {
if (spi_fd < 0) {
return ;
}
spi_byte_order = SPIEnum.MSBFIRST;
if(spi_byte_order == SPIEnum.LSBFIRST) {
spi_mode |= SPIEnum.SPI_LSB_FIRST;
} else {
spi_mode &= ~SPIEnum.SPI_LSB_FIRST;
}
HardwareControler.setSPIBitOrder( spi_fd, spi_byte_order );
}
public void setClockDivider(int divider) {
if (spi_fd < 0) {
return ;
}
spi_speed = 66666666/(2*(divider+1));
if(spi_speed > 500000) {
spi_speed = 500000;
}
HardwareControler.setSPIClockDivider( spi_fd, divider);
}
public void setDataMode(int mode) {
if (spi_fd < 0) {
return ;
}
switch(mode)
{
case SPIEnum.SPI_MODE0:
spi_mode &= ~(SPIEnum.SPI_CPHA|SPIEnum.SPI_CPOL);
break;
case SPIEnum.SPI_MODE1:
spi_mode &= ~(SPIEnum.SPI_CPOL);
spi_mode |= (SPIEnum.SPI_CPHA);
break;
case SPIEnum.SPI_MODE2:
spi_mode |= (SPIEnum.SPI_CPOL);
spi_mode &= ~(SPIEnum.SPI_CPHA);
break;
case SPIEnum.SPI_MODE3:
spi_mode |= (SPIEnum.SPI_CPHA|SPIEnum.SPI_CPOL);
break;
default:
Log.e(TAG, "error data mode");
}
HardwareControler.setSPIDataMode( spi_fd, spi_mode );
}
public void setChipSelectPolarity(int cs, int active) {
}
public void chipSelect(int cs) {
}
public byte transfer(int value) {
if (spi_fd < 0) {
return 0;
}
return (byte) HardwareControler.SPItransferOneByte(spi_fd, (byte) value, spi_delay, spi_speed, spi_bits);
}
}

@ -0,0 +1,42 @@
package com.friendlyarm.FriendlyThings;
public class SPIEnum {
// SPIBitOrder
public final static int LSBFIRST = 0; ///< LSB First
public final static int MSBFIRST = 1; ///< MSB First
// SPIMode
public final static int SPI_MODE0 = 0; ///< CPOL = 0, CPHA = 0
public final static int SPI_MODE1 = 1; ///< CPOL = 0, CPHA = 1
public final static int SPI_MODE2 = 2; ///< CPOL = 1, CPHA = 0
public final static int SPI_MODE3 = 3; ///< CPOL = 1, CPHA = 1
public final static int SPI_CPHA = 0x01;
public final static int SPI_CPOL = 0x02;
public final static int SPI_CS_HIGH = 0x04;
public final static int SPI_LSB_FIRST = 0x08;
public final static int SPI_3WIRE = 0x10;
public final static int SPI_LOOP = 0x20;
public final static int SPI_NO_CS = 0x40;
public final static int SPI_READY = 0x80;
// SPIClockDivider
public final static int SPI_CLOCK_DIV65536 = 0; ///< 65536 = 256us = 4kHz
public final static int SPI_CLOCK_DIV32768 = 32768; ///< 32768 = 126us = 8kHz
public final static int SPI_CLOCK_DIV16384 = 16384; ///< 16384 = 64us = 15.625kHz
public final static int SPI_CLOCK_DIV8192 = 8192; ///< 8192 = 32us = 31.25kHz
public final static int SPI_CLOCK_DIV4096 = 4096; ///< 4096 = 16us = 62.5kHz
public final static int SPI_CLOCK_DIV2048 = 2048; ///< 2048 = 8us = 125kHz
public final static int SPI_CLOCK_DIV1024 = 1024; ///< 1024 = 4us = 250kHz
public final static int SPI_CLOCK_DIV512 = 512; ///< 512 = 2us = 500kHz
public final static int SPI_CLOCK_DIV256 = 256; ///< 256 = 1us = 1MHz
public final static int SPI_CLOCK_DIV128 = 128; ///< 128 = 500ns = = 2MHz
public final static int SPI_CLOCK_DIV64 = 64; ///< 64 = 250ns = 4MHz
public final static int SPI_CLOCK_DIV32 = 32; ///< 32 = 125ns = 8MHz
public final static int SPI_CLOCK_DIV16 = 16; ///< 16 = 50ns = 20MHz
public final static int SPI_CLOCK_DIV8 = 8; ///< 8 = 25ns = 40MHz
public final static int SPI_CLOCK_DIV4 = 4; ///< 4 = 12.5ns 80MHz
public final static int SPI_CLOCK_DIV2 = 2; ///< 2 = 6.25ns = 160MHz
public final static int SPI_CLOCK_DIV1 = 1; ///< 0 = 256us = 4kHz
}

@ -0,0 +1,37 @@
package com.friendlyarm.FriendlyThings;
public class WatchDogEnum {
/* include/uapi/linux/watchdog.h */
public final static int WDIOC_GETSUPPORT = 0x80285700;
public final static int WDIOC_GETSTATUS = 0x80045701;
public final static int WDIOC_GETBOOTSTATUS = 0x80045702;
public final static int WDIOC_GETTEMP = 0x80045703;
public final static int WDIOC_SETOPTIONS = 0x80045704;
public final static int WDIOC_KEEPALIVE = 0x80045705;
public final static int WDIOC_SETTIMEOUT = 0xC0045706;
public final static int WDIOC_GETTIMEOUT = 0x80045707;
public final static int WDIOC_SETPRETIMEOUT = 0xC0045708;
public final static int WDIOC_GETPRETIMEOUT = 0x80045709;
public final static int WDIOC_GETTIMELEFT = 0x8004570A;
public final static int WDIOF_UNKNOWN = -1; /* Unknown flag error */
public final static int WDIOS_UNKNOWN = -1; /* Unknown status error */
public final static int WDIOF_OVERHEAT = 0x0001; /* Reset due to CPU overheat */
public final static int WDIOF_FANFAULT = 0x0002; /* Fan failed */
public final static int WDIOF_EXTERN1 = 0x0004; /* External relay 1 */
public final static int WDIOF_EXTERN2 = 0x0008; /* External relay 2 */
public final static int WDIOF_POWERUNDER = 0x0010; /* Power bad/power fault */
public final static int WDIOF_CARDRESET = 0x0020; /* Card previously reset the CPU */
public final static int WDIOF_POWEROVER = 0x0040; /* Power over voltage */
public final static int WDIOF_SETTIMEOUT = 0x0080; /* Set timeout (in seconds) */
public final static int WDIOF_MAGICCLOSE = 0x0100; /* Supports magic close char */
public final static int WDIOF_PRETIMEOUT = 0x0200; /* Pretimeout (in seconds), get/set */
public final static int WDIOF_ALARMONLY = 0x0400; /* Watchdog triggers a management or other external alarm not a reboot */
public final static int WDIOF_KEEPALIVEPING = 0x8000; /* Keep alive ping reply */
public final static int WDIOS_DISABLECARD = 0x0001; /* Turn off the watchdog timer */
public final static int WDIOS_ENABLECARD = 0x0002; /* Turn on the watchdog timer */
public final static int WDIOS_TEMPPANIC = 0x0004; /* Kernel panic on temperature trip */
}

@ -0,0 +1,314 @@
package com.friendlyarm.GPIODemo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import android.net.Uri;
import android.content.Intent;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Switch;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.CompoundButton;
import android.widget.AdapterView.OnItemClickListener;
import java.util.List;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import com.friendlyarm.FriendlyThings.GPIOEnum;
import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.BoardType;
public class GPIODemoMainActivity extends Activity {
private static final String TAG = "GPIODemo";
private Timer timer = new Timer();
private int step = 0;
private Map<String, Integer> demoGPIOPins = new HashMap<String, Integer>();
static int STEP_INIT_GPIO_DIRECTION = 1;
static int STEP_INIT_VIEW = 2;
@Override
public void onDestroy() {
timer.cancel();
super.onDestroy();
}
public void onMoreSamplesPressed(View view) {
Uri uri = Uri.parse("http://wiki.friendlyelec.com/wiki/index.php/FriendlyThings_for_Rockchip");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
private void displayListView() {
Log.d(TAG, "displayListView");
ArrayList<GPIOPin> pinList = new ArrayList<GPIOPin>();
List<Map.Entry<String,Integer>> list = new ArrayList<Map.Entry<String,Integer>>(demoGPIOPins.entrySet());
Collections.sort(list,new Comparator<Map.Entry<String,Integer>>() {
public int compare(Map.Entry<String, Integer> o1,
Map.Entry<String, Integer> o2) {
return o1.getKey().compareTo(o2.getKey());
}
});
Log.d(TAG, "{{{{ DUMP GPIO Values");
for(Map.Entry<String,Integer> entry:list){
int value = HardwareControler.getGPIOValue(entry.getValue());
if (value == GPIOEnum.HIGH) {
Log.d(TAG, entry.getKey() + "(" + String.valueOf(entry.getValue()) + ") = HIGH");
} else {
Log.d(TAG, entry.getKey() + "(" + String.valueOf(entry.getValue()) + ") = LOW");
}
GPIOPin pin = new GPIOPin(entry.getValue(), entry.getKey(), value);
pinList.add(pin);
}
Log.d(TAG, "}}}}");
dataAdapter = new MyCustomAdapter(this, R.layout.listview_item,
pinList);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(dataAdapter);
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
timer.cancel();
displayListView();
break;
}
super.handleMessage(msg);
}
};
private TimerTask init_task = new TimerTask() {
public void run() {
Log.d(TAG, "init_task " + step);
if (step == STEP_INIT_GPIO_DIRECTION) {
for (Integer sysPinNum: demoGPIOPins.values()) {
int currentDirection = HardwareControler.getGPIODirection(sysPinNum);
Log.v(TAG, String.format("currentDirection(%d) == %d", sysPinNum, currentDirection));
if (currentDirection < 0 || currentDirection != GPIOEnum.OUT) {
if (HardwareControler.setGPIODirection(sysPinNum, GPIOEnum.OUT) != 0) {
Log.v(TAG, String.format("setGPIODirection(%d) to OUT failed", sysPinNum));
} else {
Log.v(TAG, String.format("setGPIODirection(%d) to OUT OK", sysPinNum));
}
}
}
step ++;
} else if (step == STEP_INIT_VIEW) {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
}
};
//////////////////////////////////////
MyCustomAdapter dataAdapter = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gpiodemo_main);
setTitle("GPIO Demo");
int boardType = HardwareControler.getBoardType();
if (boardType == BoardType.Smart4418SDK) {
demoGPIOPins.put("GPIOC9", 73);
demoGPIOPins.put("GPIOC10", 74);
demoGPIOPins.put("GPIOC11", 75);
demoGPIOPins.put("GPIOC12", 76);
} else if (boardType == BoardType.NanoPC_T2
|| boardType == BoardType.NanoPC_T3
|| boardType == BoardType.NanoPC_T3T
) {
demoGPIOPins.put("Pin17", 68);
demoGPIOPins.put("Pin18", 71);
demoGPIOPins.put("Pin19", 72);
demoGPIOPins.put("Pin20", 88);
demoGPIOPins.put("Pin21", 92);
demoGPIOPins.put("Pin22", 58);
} else if (boardType == BoardType.NanoPC_T4) {
demoGPIOPins.put("Pin11", 33);
demoGPIOPins.put("Pin12", 50);
demoGPIOPins.put("Pin15", 36);
demoGPIOPins.put("Pin16", 54);
demoGPIOPins.put("Pin18", 55);
demoGPIOPins.put("Pin22", 56);
demoGPIOPins.put("Pin37", 96);
demoGPIOPins.put("Pin38", 125);
demoGPIOPins.put("Pin40", 126);
} else if (boardType == BoardType.NanoPi_M4 || boardType == BoardType.NanoPi_M4v2 || boardType == BoardType.NanoPi_M4B || boardType == BoardType.NanoPi_NEO4 || boardType == BoardType.NanoPi_NEO4v2) {
demoGPIOPins.put("Pin11", 33);
demoGPIOPins.put("Pin12", 50);
demoGPIOPins.put("Pin15", 36);
demoGPIOPins.put("Pin16", 54);
demoGPIOPins.put("Pin18", 55);
demoGPIOPins.put("Pin22", 56);
} else if (boardType == BoardType.SOM_RK3399 || boardType == BoardType.SOM_RK3399v2) {
demoGPIOPins.put("Pin7", 41);
demoGPIOPins.put("Pin9", 42);
} else if (boardType == BoardType.NanoPC_T6) {
demoGPIOPins.put("Pin07", 106); // GPIO3_B2
demoGPIOPins.put("Pin12", 111); // GPIO3_B7
demoGPIOPins.put("Pin15", 39); // GPIO1_A7
demoGPIOPins.put("Pin16", 107); // GPIO3_B3
demoGPIOPins.put("Pin18", 108); // GPIO3_B4
demoGPIOPins.put("Pin26", 40); // GPIO1_B0
//spi0 (m2)
//demoGPIOPins.put("Pin19", 42); // GPIO1_B2
//demoGPIOPins.put("Pin21", 41); // GPIO1_B1
//demoGPIOPins.put("Pin22", 45); // GPIO1_B5
//demoGPIOPins.put("Pin23", 43); // GPIO1_B3
//demoGPIOPins.put("Pin24", 44); // GPIO1_B4
} else if (boardType == BoardType.NanoPi_R6C) {
//i2s1 (m0)
demoGPIOPins.put("Pin07", 128); // GPIO4_A0
demoGPIOPins.put("Pin11", 129); // GPIO4_A1
demoGPIOPins.put("Pin13", 130); // GPIO4_A2
demoGPIOPins.put("Pin15", 133); // GPIO4_A5
demoGPIOPins.put("Pin16", 134); // GPIO4_A6
demoGPIOPins.put("Pin18", 137); // GPIO4_B1
demoGPIOPins.put("Pin22", 138); // GPIO4_B2
} else if (boardType == BoardType.NanoPi_R6S) {
//spi0
demoGPIOPins.put("Pin03", 43); // GPIO1_B3
demoGPIOPins.put("Pin05", 41); // GPIO1_B1
demoGPIOPins.put("Pin06", 44); // GPIO1_B4
demoGPIOPins.put("Pin07", 42); // GPIO1_B2
//uart1 (m1)
demoGPIOPins.put("Pin09", 47); // GPIO1_B7
demoGPIOPins.put("Pin10", 46); // GPIO1_B6
//uart5 (m1)
//demoGPIOPins.put("Pin11", 116); // GPIO3_C4
//demoGPIOPins.put("Pin12", 117); // GPIO3_C5
} else if (boardType == BoardType.NanoPi_R5S || boardType == BoardType.NanoPi_R5S_LTS) {
//spi1
demoGPIOPins.put("Pin03", 115); // GPIO3_C3
demoGPIOPins.put("Pin05", 114); // GPIO3_C2
demoGPIOPins.put("Pin06", 97); // GPIO3_A1
demoGPIOPins.put("Pin07", 113); // GPIO3_C1
//uart9 (m1)
//demoGPIOPins.put("Pin09", 149); // GPIO4_C5
//demoGPIOPins.put("Pin10", 150); // GPIO4_C6
//uart7 (m1)
demoGPIOPins.put("Pin11", 116); // GPIO3_C4
demoGPIOPins.put("Pin12", 117); // GPIO3_C5
} else if (android.os.Build.VERSION.RELEASE.contains("4.1.2")) {
demoGPIOPins.put("LED 1", 281);
demoGPIOPins.put("LED 2", 282);
demoGPIOPins.put("LED 3", 283);
demoGPIOPins.put("LED 4", 284);
}
if (demoGPIOPins.size() == 0) {
Toast.makeText(this, String.format("Not found any GPIO pin."),
Toast.LENGTH_SHORT).show();
} else {
// export all pins
for (Integer sysPinNum: demoGPIOPins.values()) {
if (HardwareControler.exportGPIOPin(sysPinNum) != 0) {
Toast.makeText(this, String.format("exportGPIOPin(%d) failed!", sysPinNum),
Toast.LENGTH_SHORT).show();
}
}
step = STEP_INIT_GPIO_DIRECTION;
timer.schedule(init_task, 300, 200);
}
}
private class MyCustomAdapter extends ArrayAdapter<GPIOPin> {
private ArrayList<GPIOPin> pinList;
public MyCustomAdapter(Context context, int resourceId,
ArrayList<GPIOPin> pinList) {
super(context, resourceId, pinList);
this.pinList = new ArrayList<GPIOPin>();
this.pinList.addAll(pinList);
}
private class ViewHolder {
Switch switchView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.listview_item, null);
viewHolder = new ViewHolder();
viewHolder.switchView = (Switch) convertView.findViewById(R.id.pin_switch);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
// reinit switchView
GPIOPin pin = pinList.get(position);
viewHolder.switchView.setText(pin.getName());
viewHolder.switchView.setChecked(pin.getValue() == GPIOEnum.HIGH);
viewHolder.switchView.setTag(pin);
/*
viewHolder.switchView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!buttonView.isPressed()) {
return;
}
Switch sw = (Switch) buttonView;
GPIOPin newPinData = (GPIOPin) sw.getTag();
if (isChecked) {
newPinData.setValue(GPIOEnum.HIGH);
} else {
newPinData.setValue(GPIOEnum.LOW);
}
if (HardwareControler.setGPIOValue(newPinData.getSysPinNum(),newPinData.getValue()) == 0) {
Log.v(TAG, String.format("setGPIOValue" + newPinData.getName() + " (%d) OK", newPinData.getSysPinNum()));
} else {
Log.v(TAG, String.format("setGPIOValue" + newPinData.getName() + " (%d) Failed", newPinData.getSysPinNum()));
}
pinList.set(position, newPinData);
}
});
*/
viewHolder.switchView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// you might keep a reference to the CheckBox to avoid this class cast
Switch sw = (Switch) v;
GPIOPin newPinData = (GPIOPin) sw.getTag();
if (sw.isChecked()) {
newPinData.setValue(GPIOEnum.HIGH);
} else {
newPinData.setValue(GPIOEnum.LOW);
}
if (HardwareControler.setGPIOValue(newPinData.getSysPinNum(),newPinData.getValue()) == 0) {
Log.v(TAG, String.format("setGPIOValue" + newPinData.getName() + " (%d) OK", newPinData.getSysPinNum()));
} else {
Log.v(TAG, String.format("setGPIOValue" + newPinData.getName() + " (%d) Failed", newPinData.getSysPinNum()));
}
pinList.set(position, newPinData);
}
});
return convertView;
}
}
}

@ -0,0 +1,34 @@
package com.friendlyarm.GPIODemo;
import com.friendlyarm.FriendlyThings.GPIOEnum;
public class GPIOPin {
private int sysPinNum = 0;
private String name = null;
private int value = GPIOEnum.LOW;
public GPIOPin(int sysPinNum, String name, int value) {
super();
this.sysPinNum = sysPinNum;
this.name = name;
this.value = value;
}
public int getSysPinNum() {
return sysPinNum;
}
public void setSysPinNum(int sysPinNum) {
this.sysPinNum = sysPinNum;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return this.value;
}
public void setValue(int newValue) {
this.value = newValue;
}
}

@ -0,0 +1,26 @@
package com.friendlyarm.Utils;
import android.app.Activity;
import android.app.AlertDialog;
import android.widget.Toast;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.content.Context;
import android.content.DialogInterface;
public class CommonFuncs {
public static void showAlertDialog(Context context, String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(message)
.setCancelable(false)
.setPositiveButton("Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
}

@ -0,0 +1,6 @@
#!/bin/bash
adb root
adb remount
adb sync
adb reboot

@ -0,0 +1,4 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.source=1.6

@ -0,0 +1,14 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := LCD1602
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_PRIVILEGED_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -lfriendlyarm-things
include $(BUILD_PACKAGE)

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.friendlyarm.LCD1602Demo"
coreApp="true"
android:sharedUserId="android.uid.system">
<!-- Android4.4, Android7.1 -->
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="25"
android:maxSdkVersion="25" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="MainActivity"
android:label="@string/MainActivityTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/statusView" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:textSize="16px" android:gravity="center"/>
<EditText android:id="@+id/writeEditor" android:layout_width="fill_parent"
android:layout_height="100dip" android:singleLine="false" android:editable="true"
android:gravity="top" android:textSize="14px" />
<Button android:id="@+id/sendButton" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/sendButtonText">
</Button>
</LinearLayout>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">I2C-LCD1602 Sample</string>
<string name="MainActivityTitle">I2C-LCD1602 Sample</string>
<string name="sendButtonText">Apply</string>
</resources>

@ -0,0 +1,107 @@
package com.friendlyarm.FriendlyThings;
public class BoardType {
/* getBoardType return value: */
public static final int S3C6410_COMMON = 6410;
public static final int S5PV210_COMMON = 210;
public static final int S5P4412_COMMON = 4412;
//s5p4418
public static final int S5P4418_BASE = 4418;
public static final int NanoPi2 = S5P4418_BASE+0;
public static final int NanoPC_T2 = S5P4418_BASE+1;
public static final int NanoPi_S2 = S5P4418_BASE+2;
public static final int Smart4418 = S5P4418_BASE+3;
public static final int NanoPi2_Fire = S5P4418_BASE+4;
public static final int NanoPi_M2 = S5P4418_BASE+5;
public static final int NanoPi_M2A = S5P4418_BASE+7;
public static final int Smart4418SDK = S5P4418_BASE+0x103;
public static final int S5P4418_MAX = Smart4418SDK;
//s5p6818
public static final int S5P6818_BASE = 6818;
public static final int NanoPC_T3 = S5P6818_BASE+1;
public static final int NanoPi_M3B = S5P6818_BASE+2;
public static final int Smart6818 = S5P6818_BASE+3;
public static final int NanoPC_T3T = S5P6818_BASE+4;
public static final int NanoPi_Fire3 = S5P6818_BASE+5;
public static final int NanoPi_M3 = S5P6818_BASE+7;
public static final int S5P6818_MAX = NanoPi_M3;
//s3c2451
public static final int S3C2451_BASE = 2451;
public static final int S3C2451_COMMON = S3C2451_BASE+0;
//allwinner
public static final int ALLWINNER_BASE = 7000;
public static final int NanoPi_M1 = ALLWINNER_BASE+1;
public static final int NanoPi_NEO = ALLWINNER_BASE+2;
public static final int NanoPi_NEO_Air = ALLWINNER_BASE+3;
public static final int NanoPi_M1_Plus = ALLWINNER_BASE+4;
public static final int NanoPi_A64 = ALLWINNER_BASE+5;
public static final int NanoPi_NEO2 = ALLWINNER_BASE+6;
public static final int NanoPi_M1_Plus2 = ALLWINNER_BASE+7;
public static final int NanoPi_NEO_Plus2 = ALLWINNER_BASE+8;
public static final int NanoPi_NEO_Core = ALLWINNER_BASE+9;
public static final int NanoPi_Duo = ALLWINNER_BASE+10;
public static final int NanoPi_NEO_Core2 = ALLWINNER_BASE+11;
public static final int NanoPi_K1 = ALLWINNER_BASE+12;
public static final int NanoPi_K1_Plus = ALLWINNER_BASE+13;
public static final int NanoPi_Hero = ALLWINNER_BASE+14;
public static final int NanoPi_Duo2 = ALLWINNER_BASE+15;
public static final int NanoPi_R1 = ALLWINNER_BASE+16;
public static final int NanoPi_C3 = ALLWINNER_BASE+17;
public static final int NanoPi_NEO2_Black = ALLWINNER_BASE+18;
public static final int NanoPi_NEO_S = ALLWINNER_BASE+19;
public static final int ZeroPi = ALLWINNER_BASE+20;
public static final int NanoPi_R1S_H3 = ALLWINNER_BASE+21;
public static final int NanoPi_R1S_H5 = ALLWINNER_BASE+22;
public static final int ALLWINNER_MAX = NanoPi_R1S_H5;
//amlogic
public static final int AMLOGIC_BASE = 8000;
public static final int NanoPi_K2 = AMLOGIC_BASE+1;
//rk3399
public static final int RK3399_BASE = 9000;
public static final int NanoPC_T4 = RK3399_BASE+1;
public static final int NanoPi_M4 = RK3399_BASE+2;
public static final int NanoPi_NEO4 = RK3399_BASE+3;
public static final int SOM_RK3399 = RK3399_BASE+4;
public static final int NanoPi_M4v2 = RK3399_BASE+5;
public static final int NanoPi_M4B = RK3399_BASE+6;
public static final int SOM_RK3399v2 = RK3399_BASE+7;
public static final int NanoPi_NEO4v2 = RK3399_BASE+8;
public static final int NanoPi_R4S = RK3399_BASE+9;
public static final int NanoPC_T4B = RK3399_BASE+10;
public static final int NanoPi_R4S_Plus = RK3399_BASE+11;
public static final int NanoPi_R4SE = RK3399_BASE+12;
public static final int RK3399_MAX = NanoPi_R4SE;
//rk3328
public static final int RK3328_BASE = 9500;
public static final int NanoPi_R2S = RK3328_BASE+1;
public static final int NanoPi_NEO3_Black = RK3328_BASE+2;
public static final int NanoPi_NEO3_S = RK3328_BASE+3;
public static final int NanoPi_NEO3 = RK3328_BASE+4;
public static final int NanoPi_R2Pro = RK3328_BASE+5;
public static final int NanoPi_R2C = RK3328_BASE+6;
public static final int NanoPi_R2C_Plus = RK3328_BASE+7;
public static final int NanoPi_R2S_Plus = RK3328_BASE+8;
public static final int Core3328 = RK3328_BASE+9;
public static final int RK3328_MAX = Core3328;
//rk3568
public static final int RK3568_BASE = 9600;
public static final int NanoPi_R5S = RK3568_BASE+1;
public static final int NanoPi_R5C = RK3568_BASE+2;
public static final int NanoPi_R5S_LTS = RK3568_BASE+3;
public static final int RK3568_MAX = NanoPi_R5S_LTS;
//rk3588
public static final int RK3588_BASE = 9700;
public static final int NanoPi_R6S = RK3588_BASE+1;
public static final int NanoPC_T6 = RK3588_BASE+2;
public static final int NanoPi_R6C = RK3588_BASE+3;
public static final int RK3588_MAX = NanoPi_R6C;
}

@ -0,0 +1,23 @@
package com.friendlyarm.FriendlyThings;
public class FileCtlEnum {
/* File Flag */
public final static int O_ACCMODE = 00000003;
public final static int O_RDONLY = 00000000;
public final static int O_WRONLY = 00000001;
public final static int O_RDWR = 00000002;
public final static int O_CREAT = 00000100; /* not fcntl */
public final static int O_EXCL = 00000200; /* not fcntl */
public final static int O_NOCTTY = 00000400; /* not fcntl */
public final static int O_TRUNC = 00001000; /* not fcntl */
public final static int O_APPEND = 00002000;
public final static int O_NONBLOCK = 00004000;
public final static int O_DSYNC = 00010000; /* used to be O_SYNC, see below */
public final static int FASYNC = 00020000; /* fcntl, for BSD compatibility */
public final static int O_DIRECT = 00040000; /* direct disk access hint */
public final static int O_LARGEFILE = 00100000;
public final static int O_DIRECTORY = 00200000; /* must be a directory */
public final static int O_NOFOLLOW = 00400000; /* don't follow links */
public final static int O_NOATIME = 01000000;
public final static int O_CLOEXEC = 02000000; /* set close_on_exec */
}

@ -0,0 +1,43 @@
package com.friendlyarm.FriendlyThings;
/*
GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
and have the following read/write attributes:
/sys/class/gpio/gpioN/
"direction" ... reads as either "in" or "out". This value may
normally be written. Writing as "out" defaults to
initializing the value as low. To ensure glitch free
operation, values "low" and "high" may be written to
configure the GPIO as an output with that initial value.
Note that this attribute *will not exist* if the kernel
doesn't support changing the direction of a GPIO, or
it was exported by kernel code that didn't explicitly
allow userspace to reconfigure this GPIO's direction.
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as high.
If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, either lseek(2) to the beginning of the sysfs
file and read the new value or close the file and re-open it
to read the value.
*/
public class GPIOEnum {
//Direction
public final static int IN = 1;
public final static int OUT = 2;
//Value
public final static int LOW = 0;
public final static int HIGH = 1;
}

@ -0,0 +1,89 @@
package com.friendlyarm.FriendlyThings;
import android.util.Log;
public class HardwareControler
{
/* I/O */
static public native int open(String devName, int flags);
static public native int write(int fd, byte[] data);
static public native int read(int fd, byte[] buf, int len);
static public native int select(int fd, int sec, int usec);
static public native void close(int fd);
static public native int ioctlWithIntValue(int fd, int cmd, int value);
static public native int ioctl(int fd, int cmd, byte[] buf);
/* Serial Port */
static public native int openSerialPort( String devName, long baud, int dataBits, int stopBits );
static public native int openSerialPortEx( String devName
, long baud
, int dataBits
, int stopBits
, String parityBit
, String flowCtrl
);
/* LED */
static public native int setLedState( int ledID, int ledState );
/* PWM */
static public native int PWMPlay(int frequency);
static public native int PWMStop();
static public native int PWMPlayEx(int gpioPin, int frequency);
static public native int PWMStopEx(int gpioPin);
/* ADC */
static public native int readADC();
static public native int readADCWithChannel(int channel);
static public native int[] readADCWithChannels(int[] channels);
/* I2C */
static public native int setI2CSlave(int fd, int slave);
static public native int setI2CTimeout(int fd, int timeout);
static public native int setI2CRetries(int fd, int retries);
static public native int I2CReadByteData(int fd, int pos, int wait_us);
static public native int I2CReadByte(int fd, int wait_us);
static public native int I2CWriteByteData(int fd, int pos, byte byteData, int wait_us);
static public native int I2CWriteByte(int fd, byte byteData, int wait_us);
/* Discard */ static public native int readByteFromI2C(int fd, int pos, int wait_ms);
/* Discard */ static public native int writeByteToI2C(int fd, int pos, byte byteData, int wait_ms);
/* Discard */ static public native int writeByteToI2C2(int fd, byte byteData, int wait_ms);
/* SPI */
static public native int setSPIWriteBitsPerWord( int spi_fd, int bits );
static public native int setSPIReadBitsPerWord( int spi_fd, int bits );
static public native int setSPIBitOrder( int spi_fd, int order);
static public native int setSPIClockDivider( int spi_fd, int divider);
static public native int setSPIMaxSpeed( int spi_fd, int spi_speed);
static public native int setSPIDataMode( int spi_fd, int mode);
static public native int SPItransferOneByte( int spi_fd, byte byteData, int spi_delay, int spi_speed, int spi_bits);
static public native int SPItransferBytes(int spi_fd, byte[] writeData, byte[] readBuff, int spi_delay, int spi_speed, int spi_bits);
static public native int writeBytesToSPI(int spi_fd, byte[] writeData, int spi_delay, int spi_speed, int spi_bits);
static public native int readBytesFromSPI(int spi_fd, byte[] readBuff, int spi_delay, int spi_speed, int spi_bits);
/* GPIO */
static public native int exportGPIOPin(int pin);
static public native int unexportGPIOPin(int pin);
//GPIOEnum.LOW or GPIOEnum.HIGH
static public native int setGPIOValue(int pin, int value);
static public native int getGPIOValue(int pin);
//GPIOEnum.IN or GPIOEnum.OUT
static public native int setGPIODirection(int pin, int direction);
static public native int getGPIODirection(int pin);
/* OldInterface: for EEPROM */
static public native int openI2CDevice();
static public native int writeByteDataToI2C(int fd, int pos, byte byteData);
static public native int readByteDataFromI2C(int fd, int pos);
/* return BoardType.xxx */
static public native int getBoardType();
static {
try {
System.loadLibrary("friendlyarm-things");
} catch (UnsatisfiedLinkError e) {
Log.d("HardwareControler", "libfriendlyarm-things library not found!");
}
}
}

@ -0,0 +1,108 @@
package com.friendlyarm.FriendlyThings;
import android.util.Log;
import android.widget.Toast;
import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.SPIEnum;
import com.friendlyarm.FriendlyThings.GPIOEnum;
import com.friendlyarm.FriendlyThings.FileCtlEnum;
public class SPI {
private static final String TAG = "com.friendlyarm.FriendlyThings.SPI";
private int spi_mode = 0;
private int spi_bits = 8;
private int spi_delay = 0;
private int spi_speed = 500000;
private int spi_byte_order = SPIEnum.LSBFIRST;
private static final String devName = "/dev/spidev1.0";
private int spi_fd = -1;
public void begin() {
spi_fd = HardwareControler.open( devName, FileCtlEnum.O_RDWR );
if (spi_fd >= 0) {
Log.d(TAG, "open " + devName + "ok!");
/* spi init */
HardwareControler.setSPIWriteBitsPerWord( spi_fd, spi_bits );
HardwareControler.setSPIReadBitsPerWord( spi_fd, spi_bits );
} else {
Log.d(TAG, "open " + devName + "failed!");
spi_fd = -1;
}
}
public void end() {
if (spi_fd != -1) {
HardwareControler.close(spi_fd);
spi_fd = -1;
}
}
public void setBitOrder(int order) {
if (spi_fd < 0) {
return ;
}
spi_byte_order = SPIEnum.MSBFIRST;
if(spi_byte_order == SPIEnum.LSBFIRST) {
spi_mode |= SPIEnum.SPI_LSB_FIRST;
} else {
spi_mode &= ~SPIEnum.SPI_LSB_FIRST;
}
HardwareControler.setSPIBitOrder( spi_fd, spi_byte_order );
}
public void setClockDivider(int divider) {
if (spi_fd < 0) {
return ;
}
spi_speed = 66666666/(2*(divider+1));
if(spi_speed > 500000) {
spi_speed = 500000;
}
HardwareControler.setSPIClockDivider( spi_fd, divider);
}
public void setDataMode(int mode) {
if (spi_fd < 0) {
return ;
}
switch(mode)
{
case SPIEnum.SPI_MODE0:
spi_mode &= ~(SPIEnum.SPI_CPHA|SPIEnum.SPI_CPOL);
break;
case SPIEnum.SPI_MODE1:
spi_mode &= ~(SPIEnum.SPI_CPOL);
spi_mode |= (SPIEnum.SPI_CPHA);
break;
case SPIEnum.SPI_MODE2:
spi_mode |= (SPIEnum.SPI_CPOL);
spi_mode &= ~(SPIEnum.SPI_CPHA);
break;
case SPIEnum.SPI_MODE3:
spi_mode |= (SPIEnum.SPI_CPHA|SPIEnum.SPI_CPOL);
break;
default:
Log.e(TAG, "error data mode");
}
HardwareControler.setSPIDataMode( spi_fd, spi_mode );
}
public void setChipSelectPolarity(int cs, int active) {
}
public void chipSelect(int cs) {
}
public byte transfer(int value) {
if (spi_fd < 0) {
return 0;
}
return (byte) HardwareControler.SPItransferOneByte(spi_fd, (byte) value, spi_delay, spi_speed, spi_bits);
}
}

@ -0,0 +1,42 @@
package com.friendlyarm.FriendlyThings;
public class SPIEnum {
// SPIBitOrder
public final static int LSBFIRST = 0; ///< LSB First
public final static int MSBFIRST = 1; ///< MSB First
// SPIMode
public final static int SPI_MODE0 = 0; ///< CPOL = 0, CPHA = 0
public final static int SPI_MODE1 = 1; ///< CPOL = 0, CPHA = 1
public final static int SPI_MODE2 = 2; ///< CPOL = 1, CPHA = 0
public final static int SPI_MODE3 = 3; ///< CPOL = 1, CPHA = 1
public final static int SPI_CPHA = 0x01;
public final static int SPI_CPOL = 0x02;
public final static int SPI_CS_HIGH = 0x04;
public final static int SPI_LSB_FIRST = 0x08;
public final static int SPI_3WIRE = 0x10;
public final static int SPI_LOOP = 0x20;
public final static int SPI_NO_CS = 0x40;
public final static int SPI_READY = 0x80;
// SPIClockDivider
public final static int SPI_CLOCK_DIV65536 = 0; ///< 65536 = 256us = 4kHz
public final static int SPI_CLOCK_DIV32768 = 32768; ///< 32768 = 126us = 8kHz
public final static int SPI_CLOCK_DIV16384 = 16384; ///< 16384 = 64us = 15.625kHz
public final static int SPI_CLOCK_DIV8192 = 8192; ///< 8192 = 32us = 31.25kHz
public final static int SPI_CLOCK_DIV4096 = 4096; ///< 4096 = 16us = 62.5kHz
public final static int SPI_CLOCK_DIV2048 = 2048; ///< 2048 = 8us = 125kHz
public final static int SPI_CLOCK_DIV1024 = 1024; ///< 1024 = 4us = 250kHz
public final static int SPI_CLOCK_DIV512 = 512; ///< 512 = 2us = 500kHz
public final static int SPI_CLOCK_DIV256 = 256; ///< 256 = 1us = 1MHz
public final static int SPI_CLOCK_DIV128 = 128; ///< 128 = 500ns = = 2MHz
public final static int SPI_CLOCK_DIV64 = 64; ///< 64 = 250ns = 4MHz
public final static int SPI_CLOCK_DIV32 = 32; ///< 32 = 125ns = 8MHz
public final static int SPI_CLOCK_DIV16 = 16; ///< 16 = 50ns = 20MHz
public final static int SPI_CLOCK_DIV8 = 8; ///< 8 = 25ns = 40MHz
public final static int SPI_CLOCK_DIV4 = 4; ///< 4 = 12.5ns 80MHz
public final static int SPI_CLOCK_DIV2 = 2; ///< 2 = 6.25ns = 160MHz
public final static int SPI_CLOCK_DIV1 = 1; ///< 0 = 256us = 4kHz
}

@ -0,0 +1,37 @@
package com.friendlyarm.FriendlyThings;
public class WatchDogEnum {
/* include/uapi/linux/watchdog.h */
public final static int WDIOC_GETSUPPORT = 0x80285700;
public final static int WDIOC_GETSTATUS = 0x80045701;
public final static int WDIOC_GETBOOTSTATUS = 0x80045702;
public final static int WDIOC_GETTEMP = 0x80045703;
public final static int WDIOC_SETOPTIONS = 0x80045704;
public final static int WDIOC_KEEPALIVE = 0x80045705;
public final static int WDIOC_SETTIMEOUT = 0xC0045706;
public final static int WDIOC_GETTIMEOUT = 0x80045707;
public final static int WDIOC_SETPRETIMEOUT = 0xC0045708;
public final static int WDIOC_GETPRETIMEOUT = 0x80045709;
public final static int WDIOC_GETTIMELEFT = 0x8004570A;
public final static int WDIOF_UNKNOWN = -1; /* Unknown flag error */
public final static int WDIOS_UNKNOWN = -1; /* Unknown status error */
public final static int WDIOF_OVERHEAT = 0x0001; /* Reset due to CPU overheat */
public final static int WDIOF_FANFAULT = 0x0002; /* Fan failed */
public final static int WDIOF_EXTERN1 = 0x0004; /* External relay 1 */
public final static int WDIOF_EXTERN2 = 0x0008; /* External relay 2 */
public final static int WDIOF_POWERUNDER = 0x0010; /* Power bad/power fault */
public final static int WDIOF_CARDRESET = 0x0020; /* Card previously reset the CPU */
public final static int WDIOF_POWEROVER = 0x0040; /* Power over voltage */
public final static int WDIOF_SETTIMEOUT = 0x0080; /* Set timeout (in seconds) */
public final static int WDIOF_MAGICCLOSE = 0x0100; /* Supports magic close char */
public final static int WDIOF_PRETIMEOUT = 0x0200; /* Pretimeout (in seconds), get/set */
public final static int WDIOF_ALARMONLY = 0x0400; /* Watchdog triggers a management or other external alarm not a reboot */
public final static int WDIOF_KEEPALIVEPING = 0x8000; /* Keep alive ping reply */
public final static int WDIOS_DISABLECARD = 0x0001; /* Turn off the watchdog timer */
public final static int WDIOS_ENABLECARD = 0x0002; /* Turn on the watchdog timer */
public final static int WDIOS_TEMPPANIC = 0x0004; /* Kernel panic on temperature trip */
}

@ -0,0 +1,228 @@
package com.friendlyarm.LCD1602Demo;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.os.Bundle;
import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.FileCtlEnum;
import com.friendlyarm.FriendlyThings.BoardType;
import com.friendlyarm.LCD1602Demo.R;
/* for thread */
import android.os.Message;
import android.os.Handler;
import android.os.Looper;
public class MainActivity extends Activity implements OnClickListener {
EditText writeEditor;
TextView statusView;
private Handler messageHandler;
Thread writeThread = null;
int devFD = -1;
final int MAX_LINE_SIZE = 16;
private class MessageHandler extends Handler {
public MessageHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
String result = (String) msg.obj;
if (result.equals("ERROR")) {
statusView.setText("Status: Error");
} else if (result.equals("DONE")) {
statusView.setText("Status: Done");
} else {
statusView.setText("Status: Processing");
}
}
}
@Override
public void onDestroy() {
if (devFD >= 0) {
HardwareControler.close(devFD);
devFD = -1;
}
super.onDestroy();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainactivity);
writeEditor = (EditText) findViewById(R.id.writeEditor);
writeEditor.setText("Don't give up and don't give in.");
statusView = (TextView) findViewById(R.id.statusView);
Button writeButton = (Button)findViewById(R.id.sendButton);
writeButton.setOnClickListener(this);
Looper looper = Looper.myLooper();
messageHandler = new MessageHandler(looper);
String i2cDevName = "/dev/i2c-0";
int boardType = HardwareControler.getBoardType();
if (mBoardType > BoardType.RK3399_BASE && mBoardType <= BoardType.RK3399_MAX) {
i2cDevName = "/dev/i2c-2";
}
devFD = HardwareControler.open(i2cDevName, FileCtlEnum.O_RDWR);
if (devFD < 0) {
statusView.setText("Fail to open " + i2cDevName + " device.");
writeEditor.setEnabled(false);
writeButton.setEnabled(false);
} else {
// for LCD1602 (chip: pcf8574)
if (HardwareControler.setI2CSlave(devFD, 0x27) < 0) {
statusView.setText("Fail to set " + i2cDevName + " slave.");
writeEditor.setEnabled(false);
writeButton.setEnabled(false);
} else {
statusView.setText("Status: Ready");
}
}
}
private int LCD1602Init() throws InterruptedException {
Thread.sleep(0,1000*15);
if (PCF8574.writeCmd4(devFD, (byte)(0x03 << 4)) == -1) {
return -1;
}
Thread.sleep(0,100*41);
if (PCF8574.writeCmd4(devFD, (byte)(0x03 << 4)) == -1) {
return -1;
}
Thread.sleep(0,100);
if (PCF8574.writeCmd4(devFD, (byte)(0x03 << 4)) == -1) {
return -1;
}
if (PCF8574.writeCmd4(devFD, (byte)(0x02 << 4)) == -1) {
return -1;
}
if (PCF8574.writeCmd8(devFD, (byte)(0x28)) == -1) {
return -1;
}
if (PCF8574.writeCmd8(devFD, (byte)(0x0c)) == -1) {
return -1;
}
Thread.sleep(0,2000);
if (PCF8574.writeCmd8(devFD, (byte)(0x06)) == -1) {
return -1;
}
if (PCF8574.writeCmd8(devFD, (byte)(0x02)) == -1) {
return -1;
}
Thread.sleep(0,2000);
return 0;
}
private int LCD1602DispStr(byte x, byte y, String str) throws InterruptedException
{
byte addr;
addr = (byte)(((y + 2) * 0x40) + x);
if (PCF8574.writeCmd8(devFD, addr) == -1) {
return -1;
}
byte[] strBytes = str.getBytes();
byte b;
for (int i = 0; i < strBytes.length && i<MAX_LINE_SIZE; i++) {
b = strBytes[i];
if (PCF8574.writeData8(devFD, b) == -1) {
return -1;
}
}
return 0;
}
private int LCD1602DispLines(String line1, String line2) throws InterruptedException {
int ret = LCD1602DispStr((byte)0, (byte)0, line1);
if (ret != -1 && line2.length() > 0) {
ret = LCD1602DispStr((byte)0, (byte)1, line2);
}
return ret;
}
private int LCD1602Clear() throws InterruptedException {
if (PCF8574.writeCmd8(devFD, (byte)0x01) == -1) {
return -1;
}
return 0;
}
private boolean lcd1602Inited = false;
private void sendMessage(String msg) {
Message message = Message.obtain();
message.obj = msg;
messageHandler.sendMessage(message);
}
private void startWriteEEPROMThread(final String displayText) {
statusView.setText("Status: Processing");
new Thread() {
@Override
public void run() {
if (!lcd1602Inited) {
try {
if (LCD1602Init() == 0) {
lcd1602Inited = true;
}
} catch (Exception e) {
sendMessage("ERROR");
return ;
}
}
if (!lcd1602Inited) {
sendMessage("ERROR");
return ;
}
try {
LCD1602Clear();
Thread.sleep(100, 0);
String line1 = "";
String line2 = "";
for (int i=0; i<displayText.length(); i++) {
if (line1.length() >= MAX_LINE_SIZE) {
if (line2.length() >= MAX_LINE_SIZE) {
break;
} else {
line2 = line2 + displayText.charAt(i);
}
} else {
line1 = line1 + displayText.charAt(i);
}
}
if (LCD1602DispLines(line1, line2) == -1) {
sendMessage("ERROR");
return ;
}
} catch (Exception e) {
sendMessage("ERROR");
return ;
}
sendMessage("DONE");
}
}.start();
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.sendButton:
startWriteEEPROMThread(writeEditor.getText().toString());
break;
default:
break;
}
}
}

@ -0,0 +1,64 @@
package com.friendlyarm.LCD1602Demo;
import com.friendlyarm.FriendlyThings.HardwareControler;
public class PCF8574 {
static final byte RS = 0x01;
static final byte En = 0x04;
static final byte BL = 0x08;
static int pulseEnable(int devFD, byte data) throws InterruptedException {
if (HardwareControler.I2CWriteByte(devFD, (byte)(data | En), 1) != 0) {
return -1;
}
if (HardwareControler.I2CWriteByte(devFD, (byte)(data & ~En), 0) != 0) {
return -1;
}
return 0;
}
static int writeCmd4(int devFD, byte command) throws InterruptedException {
if (HardwareControler.I2CWriteByte(devFD, (byte)(command | BL), 0) != 0) {
return -1;
}
if (pulseEnable(devFD, (byte)(command | BL)) != 0) {
return -1;
}
return 0;
}
static int writeCmd8(int devFD, byte command) throws InterruptedException {
byte command_H = (byte) (command & 0xf0);
byte command_L = (byte) ((command << 4) & 0xf0);
if (writeCmd4(devFD, command_H) == -1) {
return -1;
}
if (writeCmd4(devFD, command_L) == -1) {
return -1;
}
return 0;
}
static int writeData4(int devFD, byte data) throws InterruptedException {
if (HardwareControler.I2CWriteByte(devFD, (byte)(data | RS | BL), 0) != 0) {
return -1;
}
if (pulseEnable(devFD, (byte)(data | RS | BL)) == -1) {
return -1;
}
return 0;
}
static int writeData8(int devFD, byte data) throws InterruptedException {
byte data_H = (byte) (data & 0xf0);
byte data_L = (byte) ((data << 4) & 0xf0);
if (writeData4(devFD, data_H) == -1) {
return -1;
}
if (writeData4(devFD, data_L) == -1) {
return -1;
}
return 0;
}
}

@ -0,0 +1,26 @@
package com.friendlyarm.Utils;
import android.app.Activity;
import android.app.AlertDialog;
import android.widget.Toast;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.content.Context;
import android.content.DialogInterface;
public class CommonFuncs {
public static void showAlertDialog(Context context, String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(message)
.setCancelable(false)
.setPositiveButton("Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
}

@ -0,0 +1,14 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := PWMDemo
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_PRIVILEGED_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -lfriendlyarm-things
include $(BUILD_PACKAGE)

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.friendlyarm.PWMDemo"
coreApp="true"
android:sharedUserId="android.uid.system">
<!-- Android4.4, Android7.1 -->
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="25"
android:maxSdkVersion="25" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="PWMTestingActivity"
android:label="@string/PWMTestingActivityTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/txtEnable"
android:id="@+id/checkbox_enable"
android:checked="true"
android:onClick="onCheckboxEnableClicked"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/txtFreq"
android:id="@+id/text_freq"
android:layout_marginTop="10dp"/>
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/seekbar_pwm_freq"
android:progress="7"
android:min="0"
android:max="11"
android:longClickable="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/txtDutyCycle"
android:id="@+id/text_cycle"
android:layout_marginTop="10dp"/>
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:progress="50"
android:max="100"
android:id="@+id/seekbar_cycle"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/txtApply"
android:id="@+id/button_apply"
android:layout_marginTop="40dp"
android:onClick="onApplyPressed"/>
</LinearLayout>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">PWM Sample</string>
<string name="PWMTestingActivityTitle">PWM Sample</string>
<string name="txtEnable">Enable</string>
<string name="txtFreq">Freq</string>
<string name="txtDutyCycle">Duty cycle</string>
<string name="txtApply">Apply</string>
</resources>

@ -0,0 +1,107 @@
package com.friendlyarm.FriendlyThings;
public class BoardType {
/* getBoardType return value: */
public static final int S3C6410_COMMON = 6410;
public static final int S5PV210_COMMON = 210;
public static final int S5P4412_COMMON = 4412;
//s5p4418
public static final int S5P4418_BASE = 4418;
public static final int NanoPi2 = S5P4418_BASE+0;
public static final int NanoPC_T2 = S5P4418_BASE+1;
public static final int NanoPi_S2 = S5P4418_BASE+2;
public static final int Smart4418 = S5P4418_BASE+3;
public static final int NanoPi2_Fire = S5P4418_BASE+4;
public static final int NanoPi_M2 = S5P4418_BASE+5;
public static final int NanoPi_M2A = S5P4418_BASE+7;
public static final int Smart4418SDK = S5P4418_BASE+0x103;
public static final int S5P4418_MAX = Smart4418SDK;
//s5p6818
public static final int S5P6818_BASE = 6818;
public static final int NanoPC_T3 = S5P6818_BASE+1;
public static final int NanoPi_M3B = S5P6818_BASE+2;
public static final int Smart6818 = S5P6818_BASE+3;
public static final int NanoPC_T3T = S5P6818_BASE+4;
public static final int NanoPi_Fire3 = S5P6818_BASE+5;
public static final int NanoPi_M3 = S5P6818_BASE+7;
public static final int S5P6818_MAX = NanoPi_M3;
//s3c2451
public static final int S3C2451_BASE = 2451;
public static final int S3C2451_COMMON = S3C2451_BASE+0;
//allwinner
public static final int ALLWINNER_BASE = 7000;
public static final int NanoPi_M1 = ALLWINNER_BASE+1;
public static final int NanoPi_NEO = ALLWINNER_BASE+2;
public static final int NanoPi_NEO_Air = ALLWINNER_BASE+3;
public static final int NanoPi_M1_Plus = ALLWINNER_BASE+4;
public static final int NanoPi_A64 = ALLWINNER_BASE+5;
public static final int NanoPi_NEO2 = ALLWINNER_BASE+6;
public static final int NanoPi_M1_Plus2 = ALLWINNER_BASE+7;
public static final int NanoPi_NEO_Plus2 = ALLWINNER_BASE+8;
public static final int NanoPi_NEO_Core = ALLWINNER_BASE+9;
public static final int NanoPi_Duo = ALLWINNER_BASE+10;
public static final int NanoPi_NEO_Core2 = ALLWINNER_BASE+11;
public static final int NanoPi_K1 = ALLWINNER_BASE+12;
public static final int NanoPi_K1_Plus = ALLWINNER_BASE+13;
public static final int NanoPi_Hero = ALLWINNER_BASE+14;
public static final int NanoPi_Duo2 = ALLWINNER_BASE+15;
public static final int NanoPi_R1 = ALLWINNER_BASE+16;
public static final int NanoPi_C3 = ALLWINNER_BASE+17;
public static final int NanoPi_NEO2_Black = ALLWINNER_BASE+18;
public static final int NanoPi_NEO_S = ALLWINNER_BASE+19;
public static final int ZeroPi = ALLWINNER_BASE+20;
public static final int NanoPi_R1S_H3 = ALLWINNER_BASE+21;
public static final int NanoPi_R1S_H5 = ALLWINNER_BASE+22;
public static final int ALLWINNER_MAX = NanoPi_R1S_H5;
//amlogic
public static final int AMLOGIC_BASE = 8000;
public static final int NanoPi_K2 = AMLOGIC_BASE+1;
//rk3399
public static final int RK3399_BASE = 9000;
public static final int NanoPC_T4 = RK3399_BASE+1;
public static final int NanoPi_M4 = RK3399_BASE+2;
public static final int NanoPi_NEO4 = RK3399_BASE+3;
public static final int SOM_RK3399 = RK3399_BASE+4;
public static final int NanoPi_M4v2 = RK3399_BASE+5;
public static final int NanoPi_M4B = RK3399_BASE+6;
public static final int SOM_RK3399v2 = RK3399_BASE+7;
public static final int NanoPi_NEO4v2 = RK3399_BASE+8;
public static final int NanoPi_R4S = RK3399_BASE+9;
public static final int NanoPC_T4B = RK3399_BASE+10;
public static final int NanoPi_R4S_Plus = RK3399_BASE+11;
public static final int NanoPi_R4SE = RK3399_BASE+12;
public static final int RK3399_MAX = NanoPi_R4SE;
//rk3328
public static final int RK3328_BASE = 9500;
public static final int NanoPi_R2S = RK3328_BASE+1;
public static final int NanoPi_NEO3_Black = RK3328_BASE+2;
public static final int NanoPi_NEO3_S = RK3328_BASE+3;
public static final int NanoPi_NEO3 = RK3328_BASE+4;
public static final int NanoPi_R2Pro = RK3328_BASE+5;
public static final int NanoPi_R2C = RK3328_BASE+6;
public static final int NanoPi_R2C_Plus = RK3328_BASE+7;
public static final int NanoPi_R2S_Plus = RK3328_BASE+8;
public static final int Core3328 = RK3328_BASE+9;
public static final int RK3328_MAX = Core3328;
//rk3568
public static final int RK3568_BASE = 9600;
public static final int NanoPi_R5S = RK3568_BASE+1;
public static final int NanoPi_R5C = RK3568_BASE+2;
public static final int NanoPi_R5S_LTS = RK3568_BASE+3;
public static final int RK3568_MAX = NanoPi_R5S_LTS;
//rk3588
public static final int RK3588_BASE = 9700;
public static final int NanoPi_R6S = RK3588_BASE+1;
public static final int NanoPC_T6 = RK3588_BASE+2;
public static final int NanoPi_R6C = RK3588_BASE+3;
public static final int RK3588_MAX = NanoPi_R6C;
}

@ -0,0 +1,23 @@
package com.friendlyarm.FriendlyThings;
public class FileCtlEnum {
/* File Flag */
public final static int O_ACCMODE = 00000003;
public final static int O_RDONLY = 00000000;
public final static int O_WRONLY = 00000001;
public final static int O_RDWR = 00000002;
public final static int O_CREAT = 00000100; /* not fcntl */
public final static int O_EXCL = 00000200; /* not fcntl */
public final static int O_NOCTTY = 00000400; /* not fcntl */
public final static int O_TRUNC = 00001000; /* not fcntl */
public final static int O_APPEND = 00002000;
public final static int O_NONBLOCK = 00004000;
public final static int O_DSYNC = 00010000; /* used to be O_SYNC, see below */
public final static int FASYNC = 00020000; /* fcntl, for BSD compatibility */
public final static int O_DIRECT = 00040000; /* direct disk access hint */
public final static int O_LARGEFILE = 00100000;
public final static int O_DIRECTORY = 00200000; /* must be a directory */
public final static int O_NOFOLLOW = 00400000; /* don't follow links */
public final static int O_NOATIME = 01000000;
public final static int O_CLOEXEC = 02000000; /* set close_on_exec */
}

@ -0,0 +1,43 @@
package com.friendlyarm.FriendlyThings;
/*
GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
and have the following read/write attributes:
/sys/class/gpio/gpioN/
"direction" ... reads as either "in" or "out". This value may
normally be written. Writing as "out" defaults to
initializing the value as low. To ensure glitch free
operation, values "low" and "high" may be written to
configure the GPIO as an output with that initial value.
Note that this attribute *will not exist* if the kernel
doesn't support changing the direction of a GPIO, or
it was exported by kernel code that didn't explicitly
allow userspace to reconfigure this GPIO's direction.
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as high.
If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, either lseek(2) to the beginning of the sysfs
file and read the new value or close the file and re-open it
to read the value.
*/
public class GPIOEnum {
//Direction
public final static int IN = 1;
public final static int OUT = 2;
//Value
public final static int LOW = 0;
public final static int HIGH = 1;
}

@ -0,0 +1,89 @@
package com.friendlyarm.FriendlyThings;
import android.util.Log;
public class HardwareControler
{
/* I/O */
static public native int open(String devName, int flags);
static public native int write(int fd, byte[] data);
static public native int read(int fd, byte[] buf, int len);
static public native int select(int fd, int sec, int usec);
static public native void close(int fd);
static public native int ioctlWithIntValue(int fd, int cmd, int value);
static public native int ioctl(int fd, int cmd, byte[] buf);
/* Serial Port */
static public native int openSerialPort( String devName, long baud, int dataBits, int stopBits );
static public native int openSerialPortEx( String devName
, long baud
, int dataBits
, int stopBits
, String parityBit
, String flowCtrl
);
/* LED */
static public native int setLedState( int ledID, int ledState );
/* PWM */
static public native int PWMPlay(int frequency);
static public native int PWMStop();
static public native int PWMPlayEx(int gpioPin, int frequency);
static public native int PWMStopEx(int gpioPin);
/* ADC */
static public native int readADC();
static public native int readADCWithChannel(int channel);
static public native int[] readADCWithChannels(int[] channels);
/* I2C */
static public native int setI2CSlave(int fd, int slave);
static public native int setI2CTimeout(int fd, int timeout);
static public native int setI2CRetries(int fd, int retries);
static public native int I2CReadByteData(int fd, int pos, int wait_us);
static public native int I2CReadByte(int fd, int wait_us);
static public native int I2CWriteByteData(int fd, int pos, byte byteData, int wait_us);
static public native int I2CWriteByte(int fd, byte byteData, int wait_us);
/* Discard */ static public native int readByteFromI2C(int fd, int pos, int wait_ms);
/* Discard */ static public native int writeByteToI2C(int fd, int pos, byte byteData, int wait_ms);
/* Discard */ static public native int writeByteToI2C2(int fd, byte byteData, int wait_ms);
/* SPI */
static public native int setSPIWriteBitsPerWord( int spi_fd, int bits );
static public native int setSPIReadBitsPerWord( int spi_fd, int bits );
static public native int setSPIBitOrder( int spi_fd, int order);
static public native int setSPIClockDivider( int spi_fd, int divider);
static public native int setSPIMaxSpeed( int spi_fd, int spi_speed);
static public native int setSPIDataMode( int spi_fd, int mode);
static public native int SPItransferOneByte( int spi_fd, byte byteData, int spi_delay, int spi_speed, int spi_bits);
static public native int SPItransferBytes(int spi_fd, byte[] writeData, byte[] readBuff, int spi_delay, int spi_speed, int spi_bits);
static public native int writeBytesToSPI(int spi_fd, byte[] writeData, int spi_delay, int spi_speed, int spi_bits);
static public native int readBytesFromSPI(int spi_fd, byte[] readBuff, int spi_delay, int spi_speed, int spi_bits);
/* GPIO */
static public native int exportGPIOPin(int pin);
static public native int unexportGPIOPin(int pin);
//GPIOEnum.LOW or GPIOEnum.HIGH
static public native int setGPIOValue(int pin, int value);
static public native int getGPIOValue(int pin);
//GPIOEnum.IN or GPIOEnum.OUT
static public native int setGPIODirection(int pin, int direction);
static public native int getGPIODirection(int pin);
/* OldInterface: for EEPROM */
static public native int openI2CDevice();
static public native int writeByteDataToI2C(int fd, int pos, byte byteData);
static public native int readByteDataFromI2C(int fd, int pos);
/* return BoardType.xxx */
static public native int getBoardType();
static {
try {
System.loadLibrary("friendlyarm-things");
} catch (UnsatisfiedLinkError e) {
Log.d("HardwareControler", "libfriendlyarm-things library not found!");
}
}
}

@ -0,0 +1,108 @@
package com.friendlyarm.FriendlyThings;
import android.util.Log;
import android.widget.Toast;
import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.SPIEnum;
import com.friendlyarm.FriendlyThings.GPIOEnum;
import com.friendlyarm.FriendlyThings.FileCtlEnum;
public class SPI {
private static final String TAG = "com.friendlyarm.FriendlyThings.SPI";
private int spi_mode = 0;
private int spi_bits = 8;
private int spi_delay = 0;
private int spi_speed = 500000;
private int spi_byte_order = SPIEnum.LSBFIRST;
private static final String devName = "/dev/spidev1.0";
private int spi_fd = -1;
public void begin() {
spi_fd = HardwareControler.open( devName, FileCtlEnum.O_RDWR );
if (spi_fd >= 0) {
Log.d(TAG, "open " + devName + "ok!");
/* spi init */
HardwareControler.setSPIWriteBitsPerWord( spi_fd, spi_bits );
HardwareControler.setSPIReadBitsPerWord( spi_fd, spi_bits );
} else {
Log.d(TAG, "open " + devName + "failed!");
spi_fd = -1;
}
}
public void end() {
if (spi_fd != -1) {
HardwareControler.close(spi_fd);
spi_fd = -1;
}
}
public void setBitOrder(int order) {
if (spi_fd < 0) {
return ;
}
spi_byte_order = SPIEnum.MSBFIRST;
if(spi_byte_order == SPIEnum.LSBFIRST) {
spi_mode |= SPIEnum.SPI_LSB_FIRST;
} else {
spi_mode &= ~SPIEnum.SPI_LSB_FIRST;
}
HardwareControler.setSPIBitOrder( spi_fd, spi_byte_order );
}
public void setClockDivider(int divider) {
if (spi_fd < 0) {
return ;
}
spi_speed = 66666666/(2*(divider+1));
if(spi_speed > 500000) {
spi_speed = 500000;
}
HardwareControler.setSPIClockDivider( spi_fd, divider);
}
public void setDataMode(int mode) {
if (spi_fd < 0) {
return ;
}
switch(mode)
{
case SPIEnum.SPI_MODE0:
spi_mode &= ~(SPIEnum.SPI_CPHA|SPIEnum.SPI_CPOL);
break;
case SPIEnum.SPI_MODE1:
spi_mode &= ~(SPIEnum.SPI_CPOL);
spi_mode |= (SPIEnum.SPI_CPHA);
break;
case SPIEnum.SPI_MODE2:
spi_mode |= (SPIEnum.SPI_CPOL);
spi_mode &= ~(SPIEnum.SPI_CPHA);
break;
case SPIEnum.SPI_MODE3:
spi_mode |= (SPIEnum.SPI_CPHA|SPIEnum.SPI_CPOL);
break;
default:
Log.e(TAG, "error data mode");
}
HardwareControler.setSPIDataMode( spi_fd, spi_mode );
}
public void setChipSelectPolarity(int cs, int active) {
}
public void chipSelect(int cs) {
}
public byte transfer(int value) {
if (spi_fd < 0) {
return 0;
}
return (byte) HardwareControler.SPItransferOneByte(spi_fd, (byte) value, spi_delay, spi_speed, spi_bits);
}
}

@ -0,0 +1,42 @@
package com.friendlyarm.FriendlyThings;
public class SPIEnum {
// SPIBitOrder
public final static int LSBFIRST = 0; ///< LSB First
public final static int MSBFIRST = 1; ///< MSB First
// SPIMode
public final static int SPI_MODE0 = 0; ///< CPOL = 0, CPHA = 0
public final static int SPI_MODE1 = 1; ///< CPOL = 0, CPHA = 1
public final static int SPI_MODE2 = 2; ///< CPOL = 1, CPHA = 0
public final static int SPI_MODE3 = 3; ///< CPOL = 1, CPHA = 1
public final static int SPI_CPHA = 0x01;
public final static int SPI_CPOL = 0x02;
public final static int SPI_CS_HIGH = 0x04;
public final static int SPI_LSB_FIRST = 0x08;
public final static int SPI_3WIRE = 0x10;
public final static int SPI_LOOP = 0x20;
public final static int SPI_NO_CS = 0x40;
public final static int SPI_READY = 0x80;
// SPIClockDivider
public final static int SPI_CLOCK_DIV65536 = 0; ///< 65536 = 256us = 4kHz
public final static int SPI_CLOCK_DIV32768 = 32768; ///< 32768 = 126us = 8kHz
public final static int SPI_CLOCK_DIV16384 = 16384; ///< 16384 = 64us = 15.625kHz
public final static int SPI_CLOCK_DIV8192 = 8192; ///< 8192 = 32us = 31.25kHz
public final static int SPI_CLOCK_DIV4096 = 4096; ///< 4096 = 16us = 62.5kHz
public final static int SPI_CLOCK_DIV2048 = 2048; ///< 2048 = 8us = 125kHz
public final static int SPI_CLOCK_DIV1024 = 1024; ///< 1024 = 4us = 250kHz
public final static int SPI_CLOCK_DIV512 = 512; ///< 512 = 2us = 500kHz
public final static int SPI_CLOCK_DIV256 = 256; ///< 256 = 1us = 1MHz
public final static int SPI_CLOCK_DIV128 = 128; ///< 128 = 500ns = = 2MHz
public final static int SPI_CLOCK_DIV64 = 64; ///< 64 = 250ns = 4MHz
public final static int SPI_CLOCK_DIV32 = 32; ///< 32 = 125ns = 8MHz
public final static int SPI_CLOCK_DIV16 = 16; ///< 16 = 50ns = 20MHz
public final static int SPI_CLOCK_DIV8 = 8; ///< 8 = 25ns = 40MHz
public final static int SPI_CLOCK_DIV4 = 4; ///< 4 = 12.5ns 80MHz
public final static int SPI_CLOCK_DIV2 = 2; ///< 2 = 6.25ns = 160MHz
public final static int SPI_CLOCK_DIV1 = 1; ///< 0 = 256us = 4kHz
}

@ -0,0 +1,37 @@
package com.friendlyarm.FriendlyThings;
public class WatchDogEnum {
/* include/uapi/linux/watchdog.h */
public final static int WDIOC_GETSUPPORT = 0x80285700;
public final static int WDIOC_GETSTATUS = 0x80045701;
public final static int WDIOC_GETBOOTSTATUS = 0x80045702;
public final static int WDIOC_GETTEMP = 0x80045703;
public final static int WDIOC_SETOPTIONS = 0x80045704;
public final static int WDIOC_KEEPALIVE = 0x80045705;
public final static int WDIOC_SETTIMEOUT = 0xC0045706;
public final static int WDIOC_GETTIMEOUT = 0x80045707;
public final static int WDIOC_SETPRETIMEOUT = 0xC0045708;
public final static int WDIOC_GETPRETIMEOUT = 0x80045709;
public final static int WDIOC_GETTIMELEFT = 0x8004570A;
public final static int WDIOF_UNKNOWN = -1; /* Unknown flag error */
public final static int WDIOS_UNKNOWN = -1; /* Unknown status error */
public final static int WDIOF_OVERHEAT = 0x0001; /* Reset due to CPU overheat */
public final static int WDIOF_FANFAULT = 0x0002; /* Fan failed */
public final static int WDIOF_EXTERN1 = 0x0004; /* External relay 1 */
public final static int WDIOF_EXTERN2 = 0x0008; /* External relay 2 */
public final static int WDIOF_POWERUNDER = 0x0010; /* Power bad/power fault */
public final static int WDIOF_CARDRESET = 0x0020; /* Card previously reset the CPU */
public final static int WDIOF_POWEROVER = 0x0040; /* Power over voltage */
public final static int WDIOF_SETTIMEOUT = 0x0080; /* Set timeout (in seconds) */
public final static int WDIOF_MAGICCLOSE = 0x0100; /* Supports magic close char */
public final static int WDIOF_PRETIMEOUT = 0x0200; /* Pretimeout (in seconds), get/set */
public final static int WDIOF_ALARMONLY = 0x0400; /* Watchdog triggers a management or other external alarm not a reboot */
public final static int WDIOF_KEEPALIVEPING = 0x8000; /* Keep alive ping reply */
public final static int WDIOS_DISABLECARD = 0x0001; /* Turn off the watchdog timer */
public final static int WDIOS_ENABLECARD = 0x0002; /* Turn on the watchdog timer */
public final static int WDIOS_TEMPPANIC = 0x0004; /* Kernel panic on temperature trip */
}

@ -0,0 +1,223 @@
package com.friendlyarm.PWMDemo;
import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.BoardType;
import com.friendlyarm.PWMDemo.R;
import com.friendlyarm.Utils.CommonFuncs;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.widget.TextView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedWriter;
import android.os.Message;
import android.os.Handler;
import android.os.Looper;
import java.io.*;
public class PWMTestingActivity extends Activity {
/** Called when the activity is first created. */
private int mBoardType;
private static final String TAG = "PWMDemo";
private boolean mEnable = true;
private TextView mTextViewFreq, mTextViewCycle;
private SeekBar mSeekBarFreq, mSeekBarCycle;
private CheckBox mCheckBoxEnable;
private Button mApplyButton;
private String pwmChip;
MessageHandler mMessageHandler;
private String[] mFreqTexts = { "1Hz","5Hz","10Hz","50Hz","100Hz","500Hz","1KHz","5KHz","10KHz","20KHz","50KHz", "100KHz" };
private int[] mFreqs = {1,5,10,50,100,500,1000,5000,10000,20000,50000,100000};
int mFreqIndex=8;
int mOldFreqIndex=mFreqIndex;
int mCycle=50; //0~100
private class MessageHandler extends Handler {
Activity parent;
public MessageHandler(Looper looper, Activity v) {
super(looper);
parent = v;
}
@Override
public void handleMessage(Message msg) {
String result = (String) msg.obj;
if (result.equals("START")) {
Toast.makeText(parent, String.format("Please wait..."),
Toast.LENGTH_SHORT).show();
enableUI(false);
} else if (result.equals("DONE")) {
Toast.makeText(parent, String.format("Done"),
Toast.LENGTH_SHORT).show();
enableUI(true);
} else {
Toast.makeText(parent, result,
Toast.LENGTH_SHORT).show();
}
}
}
private void sendMessage(String msg) {
Message message = Message.obtain();
message.obj = msg;
mMessageHandler.sendMessage(message);
}
private void enableUI(boolean b) {
mSeekBarFreq.setEnabled(b);
mSeekBarCycle.setEnabled(b);
mCheckBoxEnable.setEnabled(b);
mApplyButton.setEnabled(b);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pwmtestingactivity);
Looper looper = Looper.myLooper();
mMessageHandler = new MessageHandler(looper, this);
mTextViewFreq = (TextView)findViewById(R.id.text_freq);
mTextViewCycle = (TextView)findViewById(R.id.text_cycle);
mSeekBarFreq = (SeekBar)findViewById(R.id.seekbar_pwm_freq);
mSeekBarCycle = (SeekBar)findViewById(R.id.seekbar_cycle);
mCheckBoxEnable = (CheckBox)findViewById(R.id.checkbox_enable);
mApplyButton = (Button)findViewById(R.id.button_apply);
mSeekBarFreq.setProgress(mFreqIndex);
mSeekBarCycle.setProgress(mCycle);
mCheckBoxEnable.setChecked(mEnable);
mSeekBarFreq.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
mOldFreqIndex = mFreqIndex;
mFreqIndex = i;
setGuiText();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mSeekBarCycle.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
mCycle = i;
setGuiText();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
setGuiText();
mBoardType = HardwareControler.getBoardType();
if (mBoardType > BoardType.RK3399_BASE && mBoardType <= BoardType.RK3399_MAX) {
pwmChip = "pwmchip1";
} else if (mBoardType > BoardType.RK3588_BASE && mBoardType <= BoardType.RK3588_MAX) {
pwmChip = "pwmchip1";
} else {
pwmChip = "pwmchip0";
}
applyPWMSetting();
}
void writeNumToFile(String fileName, long v) {
Log.d(TAG, "#### Write " + Long.toString(v) + " to " + fileName);
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
writer.write(Long.toString(v));
writer.close();
} catch(IOException ie) {
ie.printStackTrace();
Log.e(TAG, "Write file error: " + fileName);
Log.e(TAG, ie.toString());
sendMessage("Fail to write: " + fileName + "(value: " + Long.toString(v) + ")");
}
}
private void applyPWMSetting() {
new Thread() {
@Override
public void run() {
try {
sendMessage("START");
File file = new File("/sys/class/pwm/" + pwmChip + "/pwm0/enable");
if (file.exists()) {
writeNumToFile("/sys/class/pwm/" + pwmChip + "/pwm0/enable", 0);
Thread.sleep(100);
} else {
writeNumToFile("/sys/class/pwm/" + pwmChip + "/export", 0);
Thread.sleep(1000);
}
if (mEnable) {
long period = 1000000000/mFreqs[mFreqIndex];
if (mOldFreqIndex >= mFreqIndex) {
writeNumToFile("/sys/class/pwm/" + pwmChip + "/pwm0/period", period);
Thread.sleep(100);
writeNumToFile("/sys/class/pwm/" + pwmChip + "/pwm0/duty_cycle", (long)(period * (mCycle/100.0)));
Thread.sleep(100);
} else {
writeNumToFile("/sys/class/pwm/" + pwmChip + "/pwm0/duty_cycle", (long)(period * (mCycle/100.0)));
Thread.sleep(100);
writeNumToFile("/sys/class/pwm/" + pwmChip + "/pwm0/period", period);
Thread.sleep(100);
}
writeNumToFile("/sys/class/pwm/" + pwmChip + "/pwm0/enable", 1);
Thread.sleep(100);
}
sendMessage("DONE");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
private void setGuiText(){
mTextViewFreq.setText(getString(R.string.txtFreq) + " (" + mFreqTexts[mFreqIndex] + ")");
mTextViewCycle.setText(getString(R.string.txtDutyCycle) + " (" + String.valueOf(mCycle) + "%)");
}
@Override
public void onDestroy() {
writeNumToFile("/sys/class/pwm/" + pwmChip + "/pwm0/enable", 0);
writeNumToFile("/sys/class/pwm/" + pwmChip + "/pwm0/duty_cycle", 0);
try {
Thread.sleep(100,0);
} catch (InterruptedException e) {
e.printStackTrace();
}
writeNumToFile("/sys/class/pwm/" + pwmChip + "/unexport", 0);
super.onDestroy();
}
public void onApplyPressed(View view) {
applyPWMSetting();
}
public void onCheckboxEnableClicked(View view) {
mEnable = ((CheckBox)view).isChecked();
}
}

@ -0,0 +1,27 @@
package com.friendlyarm.Utils;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.ScrollView;
public class BorderScrollView extends ScrollView
{
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(android.graphics.Color.GRAY);
canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint);
canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint);
canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1, this.getHeight() - 1, paint);
canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1, this.getHeight() - 1, paint);
}
public BorderScrollView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
}

@ -0,0 +1,26 @@
package com.friendlyarm.Utils;
import android.app.Activity;
import android.app.AlertDialog;
import android.widget.Toast;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.content.Context;
import android.content.DialogInterface;
public class CommonFuncs {
public static void showAlertDialog(Context context, String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(message)
.setCancelable(false)
.setPositiveButton("Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
}

@ -0,0 +1,3 @@
#!/bin/bash
adb root; adb remount; adb sync; adb reboot;

@ -0,0 +1,14 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := RTCDemo
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_PRIVILEGED_MODULE := true
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -lfriendlyarm-things
include $(BUILD_PACKAGE)

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.friendlyarm.RTCDemo"
coreApp="true"
android:sharedUserId="android.uid.system">
<!-- Android4.4, Android7.1 -->
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="25"
android:maxSdkVersion="25" />
<application
android:allowBackup="true"
android:icon="@drawable/icon"
android:label="@string/app_name">
<activity
android:name="RTCDemoMainActivity"
android:label="@string/app_name"
android:windowSoftInputMode="stateHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/txtDateLabel"
android:layout_marginTop="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text_date"
android:textSize="24dp"
android:layout_marginTop="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/txtTimeLabel"
android:layout_marginTop="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text_time"
android:textSize="24dp"
android:layout_marginTop="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text_autoWakeUpLabel"
android:layout_marginTop="10dp"/>
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/seekbar_autowakeup"
android:progress="120"
android:max="3600"
android:longClickable="true"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/txtEnableAutoWakeUp"
android:id="@+id/button_enableAutoWakeUp"
android:layout_marginTop="40dp"
android:onClick="onEnableAutoWakeUpPressed"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text_result"
android:textSize="24dp"
android:layout_marginTop="10dp"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/txtPoweroff"
android:layout_marginTop="40dp"
android:onClick="onPoweroffPressed"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:orientation="vertical"
android:gravity="bottom"
android:layout_alignParentBottom="true"
android:layout_marginTop="20dp">
<Button
android:onClick="onMoreSamplesPressed"
android:id="@+id/btn_morebutton"
android:text="@string/moreSamplesButtonText"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
</Button>
</LinearLayout>
</LinearLayout>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">RTC Sample</string>
<string name="txtDateLabel">RTC Date</string>
<string name="txtTimeLabel">RTC Time</string>
<string name="txtAutoWakeUpLabel">Auto Wake Up</string>
<string name="txtEnableAutoWakeUp">Enable Auto Wake Up</string>
<string name="txtPoweroff">Power off</string>
<string name="moreSamplesButtonText">More samples? \nClick here</string>
</resources>

@ -0,0 +1,107 @@
package com.friendlyarm.FriendlyThings;
public class BoardType {
/* getBoardType return value: */
public static final int S3C6410_COMMON = 6410;
public static final int S5PV210_COMMON = 210;
public static final int S5P4412_COMMON = 4412;
//s5p4418
public static final int S5P4418_BASE = 4418;
public static final int NanoPi2 = S5P4418_BASE+0;
public static final int NanoPC_T2 = S5P4418_BASE+1;
public static final int NanoPi_S2 = S5P4418_BASE+2;
public static final int Smart4418 = S5P4418_BASE+3;
public static final int NanoPi2_Fire = S5P4418_BASE+4;
public static final int NanoPi_M2 = S5P4418_BASE+5;
public static final int NanoPi_M2A = S5P4418_BASE+7;
public static final int Smart4418SDK = S5P4418_BASE+0x103;
public static final int S5P4418_MAX = Smart4418SDK;
//s5p6818
public static final int S5P6818_BASE = 6818;
public static final int NanoPC_T3 = S5P6818_BASE+1;
public static final int NanoPi_M3B = S5P6818_BASE+2;
public static final int Smart6818 = S5P6818_BASE+3;
public static final int NanoPC_T3T = S5P6818_BASE+4;
public static final int NanoPi_Fire3 = S5P6818_BASE+5;
public static final int NanoPi_M3 = S5P6818_BASE+7;
public static final int S5P6818_MAX = NanoPi_M3;
//s3c2451
public static final int S3C2451_BASE = 2451;
public static final int S3C2451_COMMON = S3C2451_BASE+0;
//allwinner
public static final int ALLWINNER_BASE = 7000;
public static final int NanoPi_M1 = ALLWINNER_BASE+1;
public static final int NanoPi_NEO = ALLWINNER_BASE+2;
public static final int NanoPi_NEO_Air = ALLWINNER_BASE+3;
public static final int NanoPi_M1_Plus = ALLWINNER_BASE+4;
public static final int NanoPi_A64 = ALLWINNER_BASE+5;
public static final int NanoPi_NEO2 = ALLWINNER_BASE+6;
public static final int NanoPi_M1_Plus2 = ALLWINNER_BASE+7;
public static final int NanoPi_NEO_Plus2 = ALLWINNER_BASE+8;
public static final int NanoPi_NEO_Core = ALLWINNER_BASE+9;
public static final int NanoPi_Duo = ALLWINNER_BASE+10;
public static final int NanoPi_NEO_Core2 = ALLWINNER_BASE+11;
public static final int NanoPi_K1 = ALLWINNER_BASE+12;
public static final int NanoPi_K1_Plus = ALLWINNER_BASE+13;
public static final int NanoPi_Hero = ALLWINNER_BASE+14;
public static final int NanoPi_Duo2 = ALLWINNER_BASE+15;
public static final int NanoPi_R1 = ALLWINNER_BASE+16;
public static final int NanoPi_C3 = ALLWINNER_BASE+17;
public static final int NanoPi_NEO2_Black = ALLWINNER_BASE+18;
public static final int NanoPi_NEO_S = ALLWINNER_BASE+19;
public static final int ZeroPi = ALLWINNER_BASE+20;
public static final int NanoPi_R1S_H3 = ALLWINNER_BASE+21;
public static final int NanoPi_R1S_H5 = ALLWINNER_BASE+22;
public static final int ALLWINNER_MAX = NanoPi_R1S_H5;
//amlogic
public static final int AMLOGIC_BASE = 8000;
public static final int NanoPi_K2 = AMLOGIC_BASE+1;
//rk3399
public static final int RK3399_BASE = 9000;
public static final int NanoPC_T4 = RK3399_BASE+1;
public static final int NanoPi_M4 = RK3399_BASE+2;
public static final int NanoPi_NEO4 = RK3399_BASE+3;
public static final int SOM_RK3399 = RK3399_BASE+4;
public static final int NanoPi_M4v2 = RK3399_BASE+5;
public static final int NanoPi_M4B = RK3399_BASE+6;
public static final int SOM_RK3399v2 = RK3399_BASE+7;
public static final int NanoPi_NEO4v2 = RK3399_BASE+8;
public static final int NanoPi_R4S = RK3399_BASE+9;
public static final int NanoPC_T4B = RK3399_BASE+10;
public static final int NanoPi_R4S_Plus = RK3399_BASE+11;
public static final int NanoPi_R4SE = RK3399_BASE+12;
public static final int RK3399_MAX = NanoPi_R4SE;
//rk3328
public static final int RK3328_BASE = 9500;
public static final int NanoPi_R2S = RK3328_BASE+1;
public static final int NanoPi_NEO3_Black = RK3328_BASE+2;
public static final int NanoPi_NEO3_S = RK3328_BASE+3;
public static final int NanoPi_NEO3 = RK3328_BASE+4;
public static final int NanoPi_R2Pro = RK3328_BASE+5;
public static final int NanoPi_R2C = RK3328_BASE+6;
public static final int NanoPi_R2C_Plus = RK3328_BASE+7;
public static final int NanoPi_R2S_Plus = RK3328_BASE+8;
public static final int Core3328 = RK3328_BASE+9;
public static final int RK3328_MAX = Core3328;
//rk3568
public static final int RK3568_BASE = 9600;
public static final int NanoPi_R5S = RK3568_BASE+1;
public static final int NanoPi_R5C = RK3568_BASE+2;
public static final int NanoPi_R5S_LTS = RK3568_BASE+3;
public static final int RK3568_MAX = NanoPi_R5S_LTS;
//rk3588
public static final int RK3588_BASE = 9700;
public static final int NanoPi_R6S = RK3588_BASE+1;
public static final int NanoPC_T6 = RK3588_BASE+2;
public static final int NanoPi_R6C = RK3588_BASE+3;
public static final int RK3588_MAX = NanoPi_R6C;
}

@ -0,0 +1,23 @@
package com.friendlyarm.FriendlyThings;
public class FileCtlEnum {
/* File Flag */
public final static int O_ACCMODE = 00000003;
public final static int O_RDONLY = 00000000;
public final static int O_WRONLY = 00000001;
public final static int O_RDWR = 00000002;
public final static int O_CREAT = 00000100; /* not fcntl */
public final static int O_EXCL = 00000200; /* not fcntl */
public final static int O_NOCTTY = 00000400; /* not fcntl */
public final static int O_TRUNC = 00001000; /* not fcntl */
public final static int O_APPEND = 00002000;
public final static int O_NONBLOCK = 00004000;
public final static int O_DSYNC = 00010000; /* used to be O_SYNC, see below */
public final static int FASYNC = 00020000; /* fcntl, for BSD compatibility */
public final static int O_DIRECT = 00040000; /* direct disk access hint */
public final static int O_LARGEFILE = 00100000;
public final static int O_DIRECTORY = 00200000; /* must be a directory */
public final static int O_NOFOLLOW = 00400000; /* don't follow links */
public final static int O_NOATIME = 01000000;
public final static int O_CLOEXEC = 02000000; /* set close_on_exec */
}

@ -0,0 +1,43 @@
package com.friendlyarm.FriendlyThings;
/*
GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
and have the following read/write attributes:
/sys/class/gpio/gpioN/
"direction" ... reads as either "in" or "out". This value may
normally be written. Writing as "out" defaults to
initializing the value as low. To ensure glitch free
operation, values "low" and "high" may be written to
configure the GPIO as an output with that initial value.
Note that this attribute *will not exist* if the kernel
doesn't support changing the direction of a GPIO, or
it was exported by kernel code that didn't explicitly
allow userspace to reconfigure this GPIO's direction.
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as high.
If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, either lseek(2) to the beginning of the sysfs
file and read the new value or close the file and re-open it
to read the value.
*/
public class GPIOEnum {
//Direction
public final static int IN = 1;
public final static int OUT = 2;
//Value
public final static int LOW = 0;
public final static int HIGH = 1;
}

@ -0,0 +1,89 @@
package com.friendlyarm.FriendlyThings;
import android.util.Log;
public class HardwareControler
{
/* I/O */
static public native int open(String devName, int flags);
static public native int write(int fd, byte[] data);
static public native int read(int fd, byte[] buf, int len);
static public native int select(int fd, int sec, int usec);
static public native void close(int fd);
static public native int ioctlWithIntValue(int fd, int cmd, int value);
static public native int ioctl(int fd, int cmd, byte[] buf);
/* Serial Port */
static public native int openSerialPort( String devName, long baud, int dataBits, int stopBits );
static public native int openSerialPortEx( String devName
, long baud
, int dataBits
, int stopBits
, String parityBit
, String flowCtrl
);
/* LED */
static public native int setLedState( int ledID, int ledState );
/* PWM */
static public native int PWMPlay(int frequency);
static public native int PWMStop();
static public native int PWMPlayEx(int gpioPin, int frequency);
static public native int PWMStopEx(int gpioPin);
/* ADC */
static public native int readADC();
static public native int readADCWithChannel(int channel);
static public native int[] readADCWithChannels(int[] channels);
/* I2C */
static public native int setI2CSlave(int fd, int slave);
static public native int setI2CTimeout(int fd, int timeout);
static public native int setI2CRetries(int fd, int retries);
static public native int I2CReadByteData(int fd, int pos, int wait_us);
static public native int I2CReadByte(int fd, int wait_us);
static public native int I2CWriteByteData(int fd, int pos, byte byteData, int wait_us);
static public native int I2CWriteByte(int fd, byte byteData, int wait_us);
/* Discard */ static public native int readByteFromI2C(int fd, int pos, int wait_ms);
/* Discard */ static public native int writeByteToI2C(int fd, int pos, byte byteData, int wait_ms);
/* Discard */ static public native int writeByteToI2C2(int fd, byte byteData, int wait_ms);
/* SPI */
static public native int setSPIWriteBitsPerWord( int spi_fd, int bits );
static public native int setSPIReadBitsPerWord( int spi_fd, int bits );
static public native int setSPIBitOrder( int spi_fd, int order);
static public native int setSPIClockDivider( int spi_fd, int divider);
static public native int setSPIMaxSpeed( int spi_fd, int spi_speed);
static public native int setSPIDataMode( int spi_fd, int mode);
static public native int SPItransferOneByte( int spi_fd, byte byteData, int spi_delay, int spi_speed, int spi_bits);
static public native int SPItransferBytes(int spi_fd, byte[] writeData, byte[] readBuff, int spi_delay, int spi_speed, int spi_bits);
static public native int writeBytesToSPI(int spi_fd, byte[] writeData, int spi_delay, int spi_speed, int spi_bits);
static public native int readBytesFromSPI(int spi_fd, byte[] readBuff, int spi_delay, int spi_speed, int spi_bits);
/* GPIO */
static public native int exportGPIOPin(int pin);
static public native int unexportGPIOPin(int pin);
//GPIOEnum.LOW or GPIOEnum.HIGH
static public native int setGPIOValue(int pin, int value);
static public native int getGPIOValue(int pin);
//GPIOEnum.IN or GPIOEnum.OUT
static public native int setGPIODirection(int pin, int direction);
static public native int getGPIODirection(int pin);
/* OldInterface: for EEPROM */
static public native int openI2CDevice();
static public native int writeByteDataToI2C(int fd, int pos, byte byteData);
static public native int readByteDataFromI2C(int fd, int pos);
/* return BoardType.xxx */
static public native int getBoardType();
static {
try {
System.loadLibrary("friendlyarm-things");
} catch (UnsatisfiedLinkError e) {
Log.d("HardwareControler", "libfriendlyarm-things library not found!");
}
}
}

@ -0,0 +1,108 @@
package com.friendlyarm.FriendlyThings;
import android.util.Log;
import android.widget.Toast;
import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.SPIEnum;
import com.friendlyarm.FriendlyThings.GPIOEnum;
import com.friendlyarm.FriendlyThings.FileCtlEnum;
public class SPI {
private static final String TAG = "com.friendlyarm.FriendlyThings.SPI";
private int spi_mode = 0;
private int spi_bits = 8;
private int spi_delay = 0;
private int spi_speed = 500000;
private int spi_byte_order = SPIEnum.LSBFIRST;
private static final String devName = "/dev/spidev1.0";
private int spi_fd = -1;
public void begin() {
spi_fd = HardwareControler.open( devName, FileCtlEnum.O_RDWR );
if (spi_fd >= 0) {
Log.d(TAG, "open " + devName + "ok!");
/* spi init */
HardwareControler.setSPIWriteBitsPerWord( spi_fd, spi_bits );
HardwareControler.setSPIReadBitsPerWord( spi_fd, spi_bits );
} else {
Log.d(TAG, "open " + devName + "failed!");
spi_fd = -1;
}
}
public void end() {
if (spi_fd != -1) {
HardwareControler.close(spi_fd);
spi_fd = -1;
}
}
public void setBitOrder(int order) {
if (spi_fd < 0) {
return ;
}
spi_byte_order = SPIEnum.MSBFIRST;
if(spi_byte_order == SPIEnum.LSBFIRST) {
spi_mode |= SPIEnum.SPI_LSB_FIRST;
} else {
spi_mode &= ~SPIEnum.SPI_LSB_FIRST;
}
HardwareControler.setSPIBitOrder( spi_fd, spi_byte_order );
}
public void setClockDivider(int divider) {
if (spi_fd < 0) {
return ;
}
spi_speed = 66666666/(2*(divider+1));
if(spi_speed > 500000) {
spi_speed = 500000;
}
HardwareControler.setSPIClockDivider( spi_fd, divider);
}
public void setDataMode(int mode) {
if (spi_fd < 0) {
return ;
}
switch(mode)
{
case SPIEnum.SPI_MODE0:
spi_mode &= ~(SPIEnum.SPI_CPHA|SPIEnum.SPI_CPOL);
break;
case SPIEnum.SPI_MODE1:
spi_mode &= ~(SPIEnum.SPI_CPOL);
spi_mode |= (SPIEnum.SPI_CPHA);
break;
case SPIEnum.SPI_MODE2:
spi_mode |= (SPIEnum.SPI_CPOL);
spi_mode &= ~(SPIEnum.SPI_CPHA);
break;
case SPIEnum.SPI_MODE3:
spi_mode |= (SPIEnum.SPI_CPHA|SPIEnum.SPI_CPOL);
break;
default:
Log.e(TAG, "error data mode");
}
HardwareControler.setSPIDataMode( spi_fd, spi_mode );
}
public void setChipSelectPolarity(int cs, int active) {
}
public void chipSelect(int cs) {
}
public byte transfer(int value) {
if (spi_fd < 0) {
return 0;
}
return (byte) HardwareControler.SPItransferOneByte(spi_fd, (byte) value, spi_delay, spi_speed, spi_bits);
}
}

@ -0,0 +1,42 @@
package com.friendlyarm.FriendlyThings;
public class SPIEnum {
// SPIBitOrder
public final static int LSBFIRST = 0; ///< LSB First
public final static int MSBFIRST = 1; ///< MSB First
// SPIMode
public final static int SPI_MODE0 = 0; ///< CPOL = 0, CPHA = 0
public final static int SPI_MODE1 = 1; ///< CPOL = 0, CPHA = 1
public final static int SPI_MODE2 = 2; ///< CPOL = 1, CPHA = 0
public final static int SPI_MODE3 = 3; ///< CPOL = 1, CPHA = 1
public final static int SPI_CPHA = 0x01;
public final static int SPI_CPOL = 0x02;
public final static int SPI_CS_HIGH = 0x04;
public final static int SPI_LSB_FIRST = 0x08;
public final static int SPI_3WIRE = 0x10;
public final static int SPI_LOOP = 0x20;
public final static int SPI_NO_CS = 0x40;
public final static int SPI_READY = 0x80;
// SPIClockDivider
public final static int SPI_CLOCK_DIV65536 = 0; ///< 65536 = 256us = 4kHz
public final static int SPI_CLOCK_DIV32768 = 32768; ///< 32768 = 126us = 8kHz
public final static int SPI_CLOCK_DIV16384 = 16384; ///< 16384 = 64us = 15.625kHz
public final static int SPI_CLOCK_DIV8192 = 8192; ///< 8192 = 32us = 31.25kHz
public final static int SPI_CLOCK_DIV4096 = 4096; ///< 4096 = 16us = 62.5kHz
public final static int SPI_CLOCK_DIV2048 = 2048; ///< 2048 = 8us = 125kHz
public final static int SPI_CLOCK_DIV1024 = 1024; ///< 1024 = 4us = 250kHz
public final static int SPI_CLOCK_DIV512 = 512; ///< 512 = 2us = 500kHz
public final static int SPI_CLOCK_DIV256 = 256; ///< 256 = 1us = 1MHz
public final static int SPI_CLOCK_DIV128 = 128; ///< 128 = 500ns = = 2MHz
public final static int SPI_CLOCK_DIV64 = 64; ///< 64 = 250ns = 4MHz
public final static int SPI_CLOCK_DIV32 = 32; ///< 32 = 125ns = 8MHz
public final static int SPI_CLOCK_DIV16 = 16; ///< 16 = 50ns = 20MHz
public final static int SPI_CLOCK_DIV8 = 8; ///< 8 = 25ns = 40MHz
public final static int SPI_CLOCK_DIV4 = 4; ///< 4 = 12.5ns 80MHz
public final static int SPI_CLOCK_DIV2 = 2; ///< 2 = 6.25ns = 160MHz
public final static int SPI_CLOCK_DIV1 = 1; ///< 0 = 256us = 4kHz
}

@ -0,0 +1,37 @@
package com.friendlyarm.FriendlyThings;
public class WatchDogEnum {
/* include/uapi/linux/watchdog.h */
public final static int WDIOC_GETSUPPORT = 0x80285700;
public final static int WDIOC_GETSTATUS = 0x80045701;
public final static int WDIOC_GETBOOTSTATUS = 0x80045702;
public final static int WDIOC_GETTEMP = 0x80045703;
public final static int WDIOC_SETOPTIONS = 0x80045704;
public final static int WDIOC_KEEPALIVE = 0x80045705;
public final static int WDIOC_SETTIMEOUT = 0xC0045706;
public final static int WDIOC_GETTIMEOUT = 0x80045707;
public final static int WDIOC_SETPRETIMEOUT = 0xC0045708;
public final static int WDIOC_GETPRETIMEOUT = 0x80045709;
public final static int WDIOC_GETTIMELEFT = 0x8004570A;
public final static int WDIOF_UNKNOWN = -1; /* Unknown flag error */
public final static int WDIOS_UNKNOWN = -1; /* Unknown status error */
public final static int WDIOF_OVERHEAT = 0x0001; /* Reset due to CPU overheat */
public final static int WDIOF_FANFAULT = 0x0002; /* Fan failed */
public final static int WDIOF_EXTERN1 = 0x0004; /* External relay 1 */
public final static int WDIOF_EXTERN2 = 0x0008; /* External relay 2 */
public final static int WDIOF_POWERUNDER = 0x0010; /* Power bad/power fault */
public final static int WDIOF_CARDRESET = 0x0020; /* Card previously reset the CPU */
public final static int WDIOF_POWEROVER = 0x0040; /* Power over voltage */
public final static int WDIOF_SETTIMEOUT = 0x0080; /* Set timeout (in seconds) */
public final static int WDIOF_MAGICCLOSE = 0x0100; /* Supports magic close char */
public final static int WDIOF_PRETIMEOUT = 0x0200; /* Pretimeout (in seconds), get/set */
public final static int WDIOF_ALARMONLY = 0x0400; /* Watchdog triggers a management or other external alarm not a reboot */
public final static int WDIOF_KEEPALIVEPING = 0x8000; /* Keep alive ping reply */
public final static int WDIOS_DISABLECARD = 0x0001; /* Turn off the watchdog timer */
public final static int WDIOS_ENABLECARD = 0x0002; /* Turn on the watchdog timer */
public final static int WDIOS_TEMPPANIC = 0x0004; /* Kernel panic on temperature trip */
}

@ -0,0 +1,224 @@
package com.friendlyarm.RTCDemo;
import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.BoardType;
import com.friendlyarm.RTCDemo.R;
import com.friendlyarm.Utils.CommonFuncs;
import android.net.Uri;
import android.content.Intent;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.widget.TextView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Handler;
import android.os.Message;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import android.os.IPowerManager;
import android.os.PowerManager;
import android.os.ServiceManager;
import android.content.Context;
import android.os.RemoteException;
import java.io.*;
public class RTCDemoMainActivity extends Activity {
private static final String TAG = "RTCDemo";
private TextView mDateTextView;
private TextView mTimeTextView;
private TextView mAutoWakeUpTextView;
private SeekBar mAutoWakeUpSeekBar;
private Button mEnableButton;
private TextView mResultTextView;
private int mWakeUpSeconds = 120;
final int MSG_SHOW_DATETIME = 1;
final int MSG_SHOW_WAKEUP_TIMEOUT = 2;
private int mWakeUpSecondsCountDown = mWakeUpSeconds;
public void onMoreSamplesPressed(View view) {
Uri uri = Uri.parse("http://wiki.friendlyelec.com/wiki/index.php/FriendlyThings_for_Rockchip");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
private static boolean writeToFile(String fileName, String v) {
Log.d(TAG, "#### Write " + v + " to " + fileName);
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
writer.write(v);
writer.close();
return true;
} catch(IOException ie) {
ie.printStackTrace();
Log.e(TAG, "Write file error: " + fileName);
Log.e(TAG, ie.toString());
}
return false;
}
private static String readFromFile(String path, String fileName) {
File file = new File(path,fileName);
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String str = br.readLine().trim();
br.close();
return str;
}
catch (IOException e) {
//You'll need to add proper error handling here
}
return "";
}
private Timer timer = new Timer();
private TimerTask task = new TimerTask() {
public void run() {
Message message = new Message();
message.what = MSG_SHOW_DATETIME;
handler.sendMessage(message);
}
};
private Timer timerForWakeUp = null;
private TimerTask taskForWakeUp = null;
private int mBoardType = HardwareControler.getBoardType();
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SHOW_DATETIME:
if (mBoardType > BoardType.RK3399_BASE && mBoardType <= BoardType.RK3399_MAX
|| mBoardType > BoardType.RK3568_BASE && mBoardType <= BoardType.RK3568_MAX
|| mBoardType > BoardType.RK3588_BASE && mBoardType <= BoardType.RK3588_MAX) {
mDateTextView.setText(readFromFile("/sys/class/rtc/rtc0/","date"));
mTimeTextView.setText(readFromFile("/sys/class/rtc/rtc0/","time"));
}
break;
case MSG_SHOW_WAKEUP_TIMEOUT:
mWakeUpSecondsCountDown --;
if (mWakeUpSecondsCountDown < 0) {
mWakeUpSecondsCountDown = 0;
mEnableButton.setEnabled(true);
mAutoWakeUpSeekBar.setEnabled(true);
mResultTextView.setText("");
timerForWakeUp.cancel();
timerForWakeUp = null;
taskForWakeUp.cancel();
taskForWakeUp = null;
return ;
}
mResultTextView.setText("The board will wake up automatically after " + String.valueOf(mWakeUpSecondsCountDown) + " seconds");
break;
}
super.handleMessage(msg);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mDateTextView = (TextView)findViewById(R.id.text_date);
mTimeTextView = (TextView)findViewById(R.id.text_time);
mAutoWakeUpTextView = (TextView)findViewById(R.id.text_autoWakeUpLabel);
mAutoWakeUpSeekBar = (SeekBar)findViewById(R.id.seekbar_autowakeup);
mEnableButton = (Button)findViewById(R.id.button_enableAutoWakeUp);
mResultTextView = (TextView)findViewById(R.id.text_result);
if (mBoardType > BoardType.RK3399_BASE && mBoardType <= BoardType.RK3399_MAX) {
//rk3399
} else {
mAutoWakeUpTextView.setVisibility(View.INVISIBLE);
mAutoWakeUpSeekBar.setVisibility(View.INVISIBLE);
mEnableButton.setVisibility(View.INVISIBLE);
}
mAutoWakeUpSeekBar.setProgress(mWakeUpSeconds);
mAutoWakeUpSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (i > 0) {
mWakeUpSeconds = i;
}
setGuiText();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
timer.schedule(task, 0, 1000);
setGuiText();
}
private void setGuiText(){
mAutoWakeUpTextView.setText(getString(R.string.txtAutoWakeUpLabel) + " (After " + String.valueOf(mWakeUpSeconds) + "s)");
}
public void onEnableAutoWakeUpPressed(View view) {
if (mBoardType > BoardType.RK3399_BASE && mBoardType <= BoardType.RK3399_MAX
|| mBoardType > BoardType.RK3568_BASE && mBoardType <= BoardType.RK3568_MAX
|| mBoardType > BoardType.RK3588_BASE && mBoardType <= BoardType.RK3588_MAX) {
if (writeToFile("/sys/class/rtc/rtc0/wakealarm", "+" + String.valueOf(mWakeUpSeconds))) {
Toast.makeText(this, String.format("Performed successfully"),
Toast.LENGTH_SHORT).show();
mWakeUpSecondsCountDown = mWakeUpSeconds;
mResultTextView.setText("The board will wake up automatically after " + String.valueOf(mWakeUpSecondsCountDown) + " seconds");
mEnableButton.setEnabled(false);
mAutoWakeUpSeekBar.setEnabled(false);
if (timerForWakeUp == null) {
timerForWakeUp = new Timer();
}
if (taskForWakeUp == null) {
taskForWakeUp = new TimerTask() {
public void run() {
Message message = new Message();
message.what = MSG_SHOW_WAKEUP_TIMEOUT;
handler.sendMessage(message);
}
};
}
timerForWakeUp.schedule(taskForWakeUp, 0, 1000);
} else {
Toast.makeText(this, String.format("Failed"),
Toast.LENGTH_SHORT).show();
}
}
}
public void onPoweroffPressed(View view) {
Thread thr = new Thread("Shutdown") {
@Override
public void run() {
IPowerManager pm = IPowerManager.Stub.asInterface(
ServiceManager.getService(Context.POWER_SERVICE));
try {
pm.shutdown(false, PowerManager.SHUTDOWN_USER_REQUESTED, false);
} catch (RemoteException e) {
}
}
};
thr.start();
}
}

@ -0,0 +1,26 @@
package com.friendlyarm.Utils;
import android.app.Activity;
import android.app.AlertDialog;
import android.widget.Toast;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.content.Context;
import android.content.DialogInterface;
public class CommonFuncs {
public static void showAlertDialog(Context context, String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(message)
.setCancelable(false)
.setPositiveButton("Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
}

@ -0,0 +1,3 @@
#!/bin/bash
adb root; adb remount; adb sync; adb reboot;

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save