Difference between revisions of "FriendlyThings for Rockchip"

From FriendlyELEC WiKi
Jump to: navigation, search
(updated by API)
 
(22 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[FriendlyThings for RK3399/zh|查看中文]]<br /><br />
+
[[FriendlyThings for Rockchip/zh|查看中文]]<br /><br />
Note: the steps and methods presented here apply to all FriendlyElec's RK3399 based boards. For steps and methods that apply to other platforms refer to  [[FriendlyThings]]
+
Note: the steps and methods presented here apply to all FriendlyElec's Rockchip based boards. For steps and methods that apply to other platforms refer to  [[FriendlyThings]]
 
<br />
 
<br />
 
{{FriendlyThings Introduction}}
 
{{FriendlyThings Introduction}}
{{FriendlyThings AndroidVersion for RK3399}}
+
{{FriendlyThings AndroidVersion for Rockchip}}
{{FriendlyThings Boards for RK3399}}
+
{{FriendlyThings Boards for Rockchip}}
 
{{FriendlyThings Installation Guide}}
 
{{FriendlyThings Installation Guide}}
 
==APIs in libfriendlyarm-things.so Library==
 
==APIs in libfriendlyarm-things.so Library==
 
Refer to this wiki site:[[FriendlyThings APIs]]
 
Refer to this wiki site:[[FriendlyThings APIs]]
  
==Access RK3399 Based Boards' Hardware under Android==
+
==Access Hardware on Android==
 
===Serial Port===
 
===Serial Port===
Currently the only available serial port for users is UART4 and its device name is "/dev/ttyS4". Other serial ports are already taken. Here is a list of the serial ports and their functions. If you need more serial ports you can convert USB ports to serial ports:
+
The kernel has enabled the following serial ports for testing by default (should be based on kernel dts configuration), to use more serial ports you can configure the kernel dts yourself:
::{| class="wikitable"
+
{| class="wikitable"  
|-
+
|Serial || Function
+
 
|-
 
|-
|UART0  || used for Bluetooth
+
! CPU
 +
! Model
 +
! Port
 +
! Device Node
 
|-
 
|-
|UART1  || used for Gbps Ethernet 
+
| RK3588
 +
| NanoPC-T6
 +
| UART6
 +
| /dev/ttyS6
 
|-
 
|-
|UART2  || used for serial debug port
+
| RK3588S
 +
| NanoPi-R6S/R6C
 +
| UART5
 +
| /dev/ttyS5
 
|-
 
|-
|UART3  || used for Gbps Ethernet
+
| RK3568
 +
| NanoPi-R5S
 +
| UART9
 +
| /dev/ttyS9
 
|-
 
|-
|UART4  || available for users and its device name is "/dev/ttyS4" (Note: it is only available in ROMs generated on June 18,2018 or after)
+
| RK3399
 +
| NanoPC-T4
 +
| UART4
 +
| /dev/ttyS4
 
|}
 
|}
  
 
====APIs for Accessing Serial Ports====
 
====APIs for Accessing Serial Ports====
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
HardwareControler.openSerialPortEx //open a serial port
+
HardwareControler.openSerialPortEx //opens a serial port.
HardwareControler.select  //轮询串口是否有数据可写或可读
+
HardwareControler.select  //polls a serial port's status and checks if it has data to be read or if data can be written to it.
HardwareControler.read    //读取串口数据
+
HardwareControler.read    //reads data from a serial port.
HardwareControler.write    //写数据到串口
+
HardwareControler.write    //writes data to a serial port.
HardwareControler.close    //关闭设备
+
HardwareControler.close    //closes a serial port.
 
</syntaxhighlight>
 
</syntaxhighlight>
接口说明请参考:[[FriendlyThings APIs]]
+
For more details refer to :[[FriendlyThings APIs]]
  
  
 
===GPIO===
 
===GPIO===
通过 sysfs 方式控制来 GPIO,是先访问 /sys/class/gpio 目录,向 export 文件写入 GPIO编号,使得该 GPIO 的操作接口从内核空间暴露到用户空间,然后就可以操作引脚的 direction value 等,direction 控制 GPIO 方向,而 value 可控制 GPIO 输出或获得 GPIO 输入。<br />
+
You can access GPIO by calling sysfs APIs. You need to access the "/sys/class/gpio" directory, write a GPIO index number you want to access to the export file, and set the GPIO's direction and value.<br />
 
<br />
 
<br />
下面中列出RK3399可直接操作的GPIO编号:
+
The following lists the pins that the kernel configures as GPIO (should be based on kernel dts configuration):
* NanoPC T4
+
Here is a list of GPIOs FriendlyElec's RK3399 boards support:
 +
====NanoPC T6====
 
::{| class="wikitable"
 
::{| class="wikitable"
 
|-
 
|-
| style="background: PaleTurquoise; color: black" | '''物理序号'''
+
| style="background: PaleTurquoise; color: black" | '''Physical Index'''
| style="background: PaleTurquoise; color: black" |'''GPIO编号'''
+
| style="background: PaleTurquoise; color: black" |'''GPIO Index'''
 +
|-
 +
|Pin7||106
 +
|-
 +
|Pin12||111
 +
|-
 +
|Pin15||39
 +
|-
 +
|Pin16||107
 +
|-
 +
|Pin18||108
 +
|-
 +
|Pin26||40
 +
|-
 +
|}
 +
====NanoPi R6C====
 +
::{| class="wikitable"
 +
|-
 +
| style="background: PaleTurquoise; color: black" | '''Physical Index'''
 +
| style="background: PaleTurquoise; color: black" |'''GPIO Index'''
 +
|-
 +
|Pin7||128
 +
|-
 +
|Pin11||129
 +
|-
 +
|Pin13||130
 +
|-
 +
|Pin15||133
 +
|-
 +
|Pin16||134
 +
|-
 +
|Pin18||137
 +
|-
 +
|Pin22||138
 +
|-
 +
|}
 +
====NanoPi R6S====
 +
::{| class="wikitable"
 +
|-
 +
| style="background: PaleTurquoise; color: black" | '''Physical Index'''
 +
| style="background: PaleTurquoise; color: black" |'''GPIO Index'''
 +
|-
 +
|Pin3||43
 +
|-
 +
|Pin5||41
 +
|-
 +
|Pin6||44
 +
|-
 +
|Pin7||42
 +
|-
 +
|Pin9||47
 +
|-
 +
|Pin10||46
 +
|-
 +
|}
 +
====NanoPi R5S====
 +
::{| class="wikitable"
 +
|-
 +
| style="background: PaleTurquoise; color: black" | '''Physical Index'''
 +
| style="background: PaleTurquoise; color: black" |'''GPIO Index'''
 +
|-
 +
|Pin3||115
 +
|-
 +
|Pin5||114
 +
|-
 +
|Pin6||97
 +
|-
 +
|Pin7||113
 +
|-
 +
|Pin11||116
 +
|-
 +
|Pin12||117
 +
|-
 +
|}
 +
====NanoPC T4====
 +
::{| class="wikitable"
 +
|-
 +
| style="background: PaleTurquoise; color: black" | '''Physical Index'''
 +
| style="background: PaleTurquoise; color: black" |'''GPIO Index'''
 
|-
 
|-
 
|Pin11||33
 
|Pin11||33
Line 66: Line 158:
 
|Pin40||126
 
|Pin40||126
 
|}
 
|}
* NanoPi M4和NanoPi NEO4
+
====NanoPi M4/M4v2/M4B/NEO4====
 
::{| class="wikitable"
 
::{| class="wikitable"
 
|-
 
|-
| style="background: PaleTurquoise; color: black" | '''物理序号'''
+
| style="background: PaleTurquoise; color: black" | '''Physical Index'''
| style="background: PaleTurquoise; color: black" |'''Linux索引号'''
+
| style="background: PaleTurquoise; color: black" |'''Linux Index'''
 
|-
 
|-
 
|Pin11||33
 
|Pin11||33
Line 83: Line 175:
 
|-
 
|-
 
|Pin22||56
 
|Pin22||56
 +
|}
 +
====SOM-RK3399/SOM-RK3399v2====
 +
::{| class="wikitable"
 +
|-
 +
| style="background: PaleTurquoise; color: black" | '''Physical Index'''
 +
| style="background: PaleTurquoise; color: black" |'''GPIO Index'''
 +
|-
 +
|Pin7||41
 +
|-
 +
|Pin9||42
 
|}
 
|}
  
====GPIO接口说明====
+
====APIs for Accessing GPIO====
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
HardwareControler.exportGPIOPin      //导出GPIO
+
HardwareControler.exportGPIOPin      //exports a GPIO.
HardwareControler.setGPIODirection  //改变GPIO的方向
+
HardwareControler.setGPIODirection  //sets a GPIO's direction.
HardwareControler.getGPIODirection  //获得当前GPIO的方向
+
HardwareControler.getGPIODirection  //gets a GPIO's direction.
HardwareControler.setGPIOValue    //向引脚输出高电平或低电平
+
HardwareControler.setGPIOValue    //sets a GPIO's value.
HardwareControler.getGPIOValue    //获得引脚的输入(当前的值)
+
HardwareControler.getGPIOValue    //gets a GPIO's value
HardwareControler.unexportGPIOPin //取消导出
+
HardwareControler.unexportGPIOPin //unexports a GPIO.
 
</syntaxhighlight>
 
</syntaxhighlight>
接口说明请参考:[[FriendlyThings APIs]]
+
For more details refer to:[[FriendlyThings APIs]]
  
====GPIO示例说明====
+
====Testing GPIO====
可以用LED配件来测试GPIO示例,在界面上对引脚输出高电平时,LED亮,低电平时,LCD灭。
+
You can use a FriendlyElec's LED module to test GPIOs. Set a HIGH to turn on the LED and a LOW to turn off the LED.<br />
 
[[File:rk3399-android-gpio.png|frameless|GPIO]]
 
[[File:rk3399-android-gpio.png|frameless|GPIO]]
 
===ADC===
 
===ADC===
 
+
You can access ADC like accessing files on Android.
RK3399引出了三路ADC,channel为0, 2, 3,对应的文件节点为:
+
====RK3588====
 +
The file node corresponding to channel2 is shown below, this ADC can be used to query the input voltage of USB-C:
 
::{| class="wikitable"
 
::{| class="wikitable"
 
|-
 
|-
| style="background: PaleTurquoise; color: black" | '''频道'''
+
| style="background: PaleTurquoise; color: black" | '''Channel'''
| style="background: PaleTurquoise; color: black" |'''文件节点'''
+
| style="background: PaleTurquoise; color: black" |'''Node'''
 +
|-
 +
|Channel 2||/sys/devices/platform/fec10000.saradc/iio:device0/in_voltage2_raw
 +
|}
 +
====RK3568====
 +
The file node for channel2 is shown below, this ADC can be used to query the input voltage of USB-C:
 +
::{| class="wikitable"
 +
|-
 +
| style="background: PaleTurquoise; color: black" | '''Channel'''
 +
| style="background: PaleTurquoise; color: black" |'''Node'''
 +
|-
 +
|Channel 2||/sys/devices/platform/fe720000.saradc/iio:device0/in_voltage2_raw
 +
|}
 +
====RK3399====
 +
RK3399 populates three ADC channels 0, 2 and 3 and here is a list of the channels and their corresponding nodes:
 +
::{| class="wikitable"
 +
|-
 +
| style="background: PaleTurquoise; color: black" | '''Channel'''
 +
| style="background: PaleTurquoise; color: black" |'''Node'''
 
|-
 
|-
 
|Channel 0||/sys/devices/platform/ff100000.saradc/iio:device0/in_voltage0_raw
 
|Channel 0||/sys/devices/platform/ff100000.saradc/iio:device0/in_voltage0_raw
Line 113: Line 234:
 
|Channel 3||/sys/devices/platform/ff100000.saradc/iio:device0/in_voltage3_raw
 
|Channel 3||/sys/devices/platform/ff100000.saradc/iio:device0/in_voltage3_raw
 
|}
 
|}
 
在 Android 下用标准的文件读取接口就可以读取,你可以将一个可调电阻配件连接到开发板上进行测试。
 
 
 
===PWM===
 
===PWM===
RK3399开发板也是通过sysfs方式来控制PWM,直接操作 /sys/class/pwm/pwmchip1 下的文件节点即可,下面以在命令行操作PWM风扇风速作为示例:
+
====NanoPC-T6====
 
+
Pin32 is configured as PWM by default
====PWM接口说明====
+
====NanoPi-R6C====
* 将PWM0暴露到用户空间
+
Pin29 is configured as PWM by default
 +
====RK3399====
 +
<b>Note: The PWM interface is already used by the fan by default. If you want to control the PWM by yourself, you need to disable the fan first, <br />
 +
Please refer to: </b>[[Template:RK3399 Android PWMFan]]<br />
 +
<br />
 +
You can access PWMs by calling sysfs APIs. You can access the nodes under the "/sys/class/pwm/pwmchip1" directory. Here is code sample to control a PWM fan:
 +
=====APIs for Accessing PWM=====
 +
* Export PWM0 to users
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
echo 0 > /sys/class/pwm/pwmchip1/export
 
echo 0 > /sys/class/pwm/pwmchip1/export
 
</syntaxhighlight>
 
</syntaxhighlight>
* 通过设置PWM的period和duty_cycle来控制风速
+
* Control a PWM fan's speed by setting the PWM's period and duty_cycle.
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
echo 0 > /sys/class/pwm/pwmchip1/pwm0/enable
 
echo 0 > /sys/class/pwm/pwmchip1/pwm0/enable
Line 131: Line 256:
 
echo 45000 > /sys/class/pwm/pwmchip1/pwm0/duty_cycle
 
echo 45000 > /sys/class/pwm/pwmchip1/pwm0/duty_cycle
 
</syntaxhighlight>
 
</syntaxhighlight>
====PWM示例说明====
+
=====Testing PWM=====
可以连接一个PWM风扇(3针)到NanoPC-T4的风扇接口来测试PWM示例。
+
Connect a PWM fan(3 pins) to a NanoPC-T4's fan port to test it.<br />
 
[[File:rk3399-android-pwm.png|frameless|PWM]]
 
[[File:rk3399-android-pwm.png|frameless|PWM]]
  
 
===I2C===
 
===I2C===
 
+
====RK3399====
运行I2C Demo需要将一个LCD1602的模块连接到NanoPC-T4的以下引脚:
+
To test I2C we connected a FriendlyElec's LCD1602 module to a NanoPC-T4 and ran the I2C demo program:
 
::{| class="wikitable"
 
::{| class="wikitable"
 
|-
 
|-
| style="background: PaleTurquoise; color: black" | '''物理序号'''
+
| style="background: PaleTurquoise; color: black" | '''Physical Index'''
| style="background: PaleTurquoise; color: black" |'''I2C功能'''
+
| style="background: PaleTurquoise; color: black" |'''I2C Functions'''
 
|-
 
|-
 
|Pin3||I2C2_SDA(3V)
 
|Pin3||I2C2_SDA(3V)
Line 152: Line 277:
 
|}
 
|}
  
如下图所示:<br />
+
Here is a hardware setting:<br />
 
[[File:NanoPC-T4+OLED.jpg|frameless|450px]]
 
[[File:NanoPC-T4+OLED.jpg|frameless|450px]]
  
 
===RTC===
 
===RTC===
通过 /sys/class/rtc/rtc0/下面的接口来操作RTC,比如查看当前RTC的日期和时间:<br />
+
'''Note: Scheduled power on/off is only supported on certain models, such as NanoPC-T4.'''<br />
 +
You can access RTC by calling APIs under the "/sys/class/rtc/rtc0/" directory. For instance you can check the current RTC time by running the following commands:<br />
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
cat /sys/class/rtc/rtc0/date
 
cat /sys/class/rtc/rtc0/date
Line 163: Line 289:
 
# 08:20:14
 
# 08:20:14
 
</syntaxhighlight>
 
</syntaxhighlight>
设置开机时间,如设置120秒后开机:
+
Set power-on time. For instance power on in 120 seconds:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
#120秒后定时开机
+
#Power on in 120 seconds
 
echo +120 >  /sys/class/rtc/rtc0/wakealarm
 
echo +120 >  /sys/class/rtc/rtc0/wakealarm
 
</syntaxhighlight>
 
</syntaxhighlight>
Line 171: Line 297:
  
 
===Watch dog===
 
===Watch dog===
看门狗的操作比较简单,打开设备 /dev/watchdog 并定时写入字符即可,如果系统出现问题导致没有写入字符,设备会过一段时间自动重启:
+
It is quite straightforward to access the watch dog. You can simply open the "/dev/watchdog" device and write characters to it.If for any reason no characters can be written to the device the system will reboot in a moment:
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
 
mWatchDogFD = HardwareControler.open("/dev/watchdog", FileCtlEnum.O_WRONLY);
 
mWatchDogFD = HardwareControler.open("/dev/watchdog", FileCtlEnum.O_WRONLY);
Line 177: Line 303:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
[[File:rk3399-android-watchdog.png|frameless|WatchDog]]
 
[[File:rk3399-android-watchdog.png|frameless|WatchDog]]
 +
 
===SPI===
 
===SPI===
====启用SPI====
+
====RK3399====
SPI由于与UART4共用引脚,所以需要修改内核DTS文件,修改方法如下: <br />
+
=====Enable SPI=====
编辑内核目录下的dts文件 arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi:
+
The SPI and UART4 share the same pins. You need to modify the kernel's DTS file to enable the SPI by running the following commands:<br />
 +
Edit the DTS file: arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi:
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
 
cd ANDROID_SOURCE/kernel
 
cd ANDROID_SOURCE/kernel
 
vim arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi
 
vim arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi
 
</syntaxhighlight>
 
</syntaxhighlight>
其中,ANDROID_SOURCE请替换为真实的 Android7或Android8源代码目录。
+
You need to replace "ANDROID_SOURCE" to your real source. In our system it is either Android7's or Android8's source code directory.
  
首先找到 spi1 的定义:
+
Locate spi1's definition:
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
 
&spi1 {
 
&spi1 {
     status = "disabled";  // 将其中的 disabled 改为 okay
+
     status = "disabled";  // change "disabled" to "okay"
 
</syntaxhighlight>
 
</syntaxhighlight>
然后再在 rk3399-nanopi4-common.dtsi 文件到找到 uart4 的定义:
+
Locate uart4's definition in the rk3399-nanopi4-common.dtsi file:
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
 
&uart4 {
 
&uart4 {
     status = "okay";  // 将其中的 okay 改为 disabled
+
     status = "okay";  // change "okay" to "disabled"
 
</syntaxhighlight>
 
</syntaxhighlight>
最后重新编译内核:
+
Compile kernel:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
cd ANDROID_SOURCE/
 
cd ANDROID_SOURCE/
 
./build-nanopc-t4.sh -K -M
 
./build-nanopc-t4.sh -K -M
 
</syntaxhighlight>
 
</syntaxhighlight>
更新 rockdev/Image-nanopc_t4/resource.img 到开发板即可,可以将resource.img拷贝到安装有 eflasher 系统的TF卡中,位置是FriendlyARM分区的androidX 目录,替换里面的resource.img文件,然后用TF卡重刷系统。
+
Use the newly generated "rockdev/Image-nanopc_t4/resource.img" image file to update your system.  
  
====SPI示例====
+
=====Testing SPI=====
SPI示例默认没有预装,需要手动编译,方法是修改Android源代码的以下文件:<br />
+
By default the SPI is not enabled in your system. You need to manually enable it by making changes to your Android source code:<br />
 
vendor/friendlyelec/apps# vi device-partial.mk<br />
 
vendor/friendlyelec/apps# vi device-partial.mk<br />
去掉前面的注释:<br />
+
Remove the comment:<br />
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
# PRODUCT_PACKAGES += SPI-OLED
 
# PRODUCT_PACKAGES += SPI-OLED
 
</syntaxhighlight>
 
</syntaxhighlight>
然后重新编译 Android源代码。<br />
+
Compile Android source code<br />
 
<br />
 
<br />
运行SPI示例需要在NanoPC-T4上连接一个 SPI接口的OLED,规格为0.96寸的128x64屏。<br />
+
We connected a FriendlyElec's OLED module which had a 0.96" LCD with a resolution of 128 x 64 and a SPI interface to a NanoPC-T4 and tested it.<br />
 
<br />
 
<br />
屏幕上有7个引脚,与开发板用母对母杜邦线连接,接法如下表:<br />
+
The LCD module had 7 pins and here is hardware setup:<br />
 
::{| class="wikitable"
 
::{| class="wikitable"
 
|-
 
|-
| style="background: PaleTurquoise; color: black" | '''OLED引脚'''
+
| style="background: PaleTurquoise; color: black" | '''OLED Pin'''
| style="background: PaleTurquoise; color: black" |'''功能'''
+
| style="background: PaleTurquoise; color: black" |'''Function'''
| style="background: PaleTurquoise; color: black" |'''NanoPC-T4引脚编号'''
+
| style="background: PaleTurquoise; color: black" |'''NanoPC-T4 Pin'''
| style="background: PaleTurquoise; color: black" |'''备注'''
+
| style="background: PaleTurquoise; color: black" |'''Comment'''
 
|-
 
|-
 
|GND|| ||Pin6  GND ||
 
|GND|| ||Pin6  GND ||
Line 227: Line 355:
 
|VCC|| ||Pin2  VCC5V ||
 
|VCC|| ||Pin2  VCC5V ||
 
|-
 
|-
|DO||SCLK||Pin23 (SPI1_CLK(3V) ||时钟信号,由主设备产生
+
|DO||SCLK||Pin23 (SPI1_CLK(3V) ||Clock generated by master device
 
|-
 
|-
|DI||MOSI||Pin19 (SPI1_TXD) ||主设备数据输出,从设备数据输入
+
|DI||MOSI||Pin19 (SPI1_TXD) ||Output from master device and input to slave device
 
|-
 
|-
 
|RES|| ||Pin16 (GPIO1_C6(3V)) ||
 
|RES|| ||Pin16 (GPIO1_C6(3V)) ||
Line 235: Line 363:
 
|D/C|| ||Pin12 (GPIO1_C2) ||
 
|D/C|| ||Pin12 (GPIO1_C2) ||
 
|-
 
|-
|CS||CS0||Pin24 (SPI1_CSn0) ||从设备使能信号,由主设备控制
+
|CS||CS0||Pin24 (SPI1_CSn0) || Signal to enable slave device, set by master device
 
|}
 
|}
 
<br />
 
<br />
====SPI接口说明====
+
====APIs for Accessing SPI====
请参考:[[FriendlyThings APIs]]
+
For more details refer to:[[FriendlyThings APIs]]
  
==示例程序下载地址==
+
==Download Links to Code Samples==
所有硬件访问的示例程序均已集成到 Android 的源代码当中,位于 Android7.1.2 Android8.1 源代码的以下目录:vendor/friendlyelec/apps,也可以单独网上下载,下表中列出各个 Demo 的源代码地址:
+
All the code samples are included in FriendlyElec's Android source code and are under the "vendor/friendlyelec/apps" directory in Android7.1.2 and Android8.1. Or you can download individual code samples. Here is a list of code samples and their download links:
 
{{FriendlyThings Android8 Demos}}
 
{{FriendlyThings Android8 Demos}}
 
{{FriendlyThings Android7 Demos}}
 
{{FriendlyThings Android7 Demos}}

Latest revision as of 11:28, 17 August 2023

查看中文

Note: the steps and methods presented here apply to all FriendlyElec's Rockchip based boards. For steps and methods that apply to other platforms refer to FriendlyThings

1 Introduction

FriendlyThings is an Android SDK developed by FriendlyElec to access hardware. Users can use it to access various hardware resources Uart, SPI, I2C, GPIO etc on a FriendlyElec ARM board under Android. This SDK is based on Android-NDK. Users can use it to develop popular IoT applications without directly interacting with drivers.


2 Android Versions

The Android BSPs provided by FriendlyElec already have FriendlyThings SDK(libfriendlyarm-things.so), as shown below:

  • Android 12 (rk3568 & rk3588)

BSP source code download link: http://112.124.9.243:3000/friendlyelec/rk35xx-android12
Latest ROM download link: http://download.friendlyelec.com/NanoPC-T6

  • Android 7.1.2-rk3399

BSP source code download link: https://gitlab.com/friendlyelec/rk3399-nougat
BSP source code location on the network disk: sources/rk3399-android-7.git-YYYYMMDD.tgz
Latest ROM download link: http://download.friendlyelec.com/NanoPC-T4

  • Android 8.1-rk3399

BSP source code download link: https://gitlab.com/friendlyelec/rk3399-android-8.1
BSP source code location on the network disk: sources/rk3399-android-8.1.git-YYYYMMDD.tgz
Latest ROM download link: http://download.friendlyelec.com/NanoPC-T4

3 List of Applicable Boards

FriendlyThings SDK(libfriendlyarm-things.so) works with the following FriendlyElec RK3399/RK3568/RK3588 based boards:

  • NanoPC-T6
  • NanoPi-R6S/R6C
  • NanoPi-R5S/R5C
  • NanoPC-T4
  • NanoPi M4 (an external eMMC module is needed)
  • NanoPi NEO4 (an external eMMC module is needed)

FriendlyThings might also work with other FriendlyElec boards such as Samsung S5P4418/S5P6818, Samsung S5PV210, Allwinner H3/H5 etc. For more details refer to FriendlyThings

4 Quick Start

4.1 Step 1: Include libfriendlyarm-things.so in APP

Clone the following library locally:

git clone https://github.com/friendlyarm/friendlythings-sdk

Copy all the files under the libs directory to your working directory and create a "com/friendlyarm" directory in your Android project's src directory, copy the whole "java/FriendlyThings" to your newly created "com/friendlyarm" directory. The whole project directory will look like this(Note:AndroidStudio's project may be a little bit different):

YourProject/
├── AndroidManifest.xml
├── libs
│   ├── arm64-v8a
│   │   └── libfriendlyarm-things.so
│   └── armeabi
│       └── libfriendlyarm-things.so
├── src
│   └── com
│       └── friendlyarm
│           ├── FriendlyThings
│           │   ├── BoardType.java
│           │   ├── FileCtlEnum.java
│           │   ├── GPIOEnum.java
│           │   ├── HardwareControler.java
│           │   ├── SPIEnum.java
│           │   ├── SPI.java
│           │   └── WatchDogEnum.java

Import the following components and the major APIs are included in the HardwareControler.java file:

import com.friendlyarm.FriendlyThings.HardwareControler;
import com.friendlyarm.FriendlyThings.SPIEnum;
import com.friendlyarm.FriendlyThings.GPIOEnum;
import com.friendlyarm.FriendlyThings.FileCtlEnum;
import com.friendlyarm.FriendlyThings.BoardType;

4.2 Step 2: Give APP System Right

Your app needs the system right to access hardware resources;
Give your app the system right by making changes in the AndroidManifest.xml file and the Android.mk file;
It is better to include your app in your Android source code and compile them together. If your app is not compiled together with your Android source code you have to go through tedious steps to compile your app and sign your app to give it the system right.

4.2.1 Modify AndroidManifest.xml

Add the following line in the manifest node in the AndroidManifest.xml file:

android:sharedUserId="android.uid.system"

4.2.2 Modify Android.mk

Create an Android.mk file(the simplest way is to copy a sample Android.mk file), modify the Android.mk file by adding a line LOCAL_CERTIFICATE := platform :

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
 
LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
LOCAL_PACKAGE_NAME := Project Name
 
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -lfriendlyarm-hardware
 
include $(BUILD_PACKAGE)

4.3 Final Step: Compile Your APP Together with Android Source Code

Go to Android source code's root directory and run "setenv.sh" to export environmental variables, enter your app's directory and run "mm" to compile:
For example: compile the GPIO_LED_Demo on RK3399:

cd rk3399-android-8.1
. setenv.sh
cd vendor/friendlyelec/apps/GPIO_LED_Demo
mm

4.4 Sample project in Android Studio

https://github.com/friendlyarm/AndroidStudio-GPIODemo

5 APIs in libfriendlyarm-things.so Library

Refer to this wiki site:FriendlyThings APIs

6 Access Hardware on Android

6.1 Serial Port

The kernel has enabled the following serial ports for testing by default (should be based on kernel dts configuration), to use more serial ports you can configure the kernel dts yourself:

CPU Model Port Device Node
RK3588 NanoPC-T6 UART6 /dev/ttyS6
RK3588S NanoPi-R6S/R6C UART5 /dev/ttyS5
RK3568 NanoPi-R5S UART9 /dev/ttyS9
RK3399 NanoPC-T4 UART4 /dev/ttyS4

6.1.1 APIs for Accessing Serial Ports

HardwareControler.openSerialPortEx //opens a serial port.
HardwareControler.select   //polls a serial port's status and checks if it has data to be read or if data can be written to it.
HardwareControler.read     //reads data from a serial port.
HardwareControler.write    //writes data to a serial port.
HardwareControler.close    //closes a serial port.

For more details refer to :FriendlyThings APIs


6.2 GPIO

You can access GPIO by calling sysfs APIs. You need to access the "/sys/class/gpio" directory, write a GPIO index number you want to access to the export file, and set the GPIO's direction and value.

The following lists the pins that the kernel configures as GPIO (should be based on kernel dts configuration): Here is a list of GPIOs FriendlyElec's RK3399 boards support:

6.2.1 NanoPC T6

Physical Index GPIO Index
Pin7 106
Pin12 111
Pin15 39
Pin16 107
Pin18 108
Pin26 40

6.2.2 NanoPi R6C

Physical Index GPIO Index
Pin7 128
Pin11 129
Pin13 130
Pin15 133
Pin16 134
Pin18 137
Pin22 138

6.2.3 NanoPi R6S

Physical Index GPIO Index
Pin3 43
Pin5 41
Pin6 44
Pin7 42
Pin9 47
Pin10 46

6.2.4 NanoPi R5S

Physical Index GPIO Index
Pin3 115
Pin5 114
Pin6 97
Pin7 113
Pin11 116
Pin12 117

6.2.5 NanoPC T4

Physical Index GPIO Index
Pin11 33
Pin12 50
Pin15 36
Pin16 54
Pin18 55
Pin22 56
Pin37 96
Pin38 125
Pin40 126

6.2.6 NanoPi M4/M4v2/M4B/NEO4

Physical Index Linux Index
Pin11 33
Pin12 50
Pin15 36
Pin16 54
Pin18 55
Pin22 56

6.2.7 SOM-RK3399/SOM-RK3399v2

Physical Index GPIO Index
Pin7 41
Pin9 42

6.2.8 APIs for Accessing GPIO

HardwareControler.exportGPIOPin      //exports a GPIO.
HardwareControler.setGPIODirection   //sets a GPIO's direction.
HardwareControler.getGPIODirection   //gets a GPIO's direction.
HardwareControler.setGPIOValue    //sets a GPIO's value.
HardwareControler.getGPIOValue    //gets a GPIO's value
HardwareControler.unexportGPIOPin //unexports a GPIO.

For more details refer to:FriendlyThings APIs

6.2.9 Testing GPIO

You can use a FriendlyElec's LED module to test GPIOs. Set a HIGH to turn on the LED and a LOW to turn off the LED.
GPIO

6.3 ADC

You can access ADC like accessing files on Android.

6.3.1 RK3588

The file node corresponding to channel2 is shown below, this ADC can be used to query the input voltage of USB-C:

Channel Node
Channel 2 /sys/devices/platform/fec10000.saradc/iio:device0/in_voltage2_raw

6.3.2 RK3568

The file node for channel2 is shown below, this ADC can be used to query the input voltage of USB-C:

Channel Node
Channel 2 /sys/devices/platform/fe720000.saradc/iio:device0/in_voltage2_raw

6.3.3 RK3399

RK3399 populates three ADC channels 0, 2 and 3 and here is a list of the channels and their corresponding nodes:

Channel Node
Channel 0 /sys/devices/platform/ff100000.saradc/iio:device0/in_voltage0_raw
Channel 2 /sys/devices/platform/ff100000.saradc/iio:device0/in_voltage2_raw
Channel 3 /sys/devices/platform/ff100000.saradc/iio:device0/in_voltage3_raw

6.4 PWM

6.4.1 NanoPC-T6

Pin32 is configured as PWM by default

6.4.2 NanoPi-R6C

Pin29 is configured as PWM by default

6.4.3 RK3399

Note: The PWM interface is already used by the fan by default. If you want to control the PWM by yourself, you need to disable the fan first,
Please refer to:
Template:RK3399 Android PWMFan

You can access PWMs by calling sysfs APIs. You can access the nodes under the "/sys/class/pwm/pwmchip1" directory. Here is code sample to control a PWM fan:

6.4.3.1 APIs for Accessing PWM
  • Export PWM0 to users
echo 0 > /sys/class/pwm/pwmchip1/export
  • Control a PWM fan's speed by setting the PWM's period and duty_cycle.
echo 0 > /sys/class/pwm/pwmchip1/pwm0/enable
echo 50000 > /sys/class/pwm/pwmchip1/pwm0/period
echo 1 > /sys/class/pwm/pwmchip1/pwm0/enable
echo 45000 > /sys/class/pwm/pwmchip1/pwm0/duty_cycle
6.4.3.2 Testing PWM

Connect a PWM fan(3 pins) to a NanoPC-T4's fan port to test it.
PWM

6.5 I2C

6.5.1 RK3399

To test I2C we connected a FriendlyElec's LCD1602 module to a NanoPC-T4 and ran the I2C demo program:

Physical Index I2C Functions
Pin3 I2C2_SDA(3V)
Pin4 VCC5V0_SYS
Pin5 I2C2_SCL(3V)
Pin6 GND

Here is a hardware setting:
NanoPC-T4+OLED.jpg

6.6 RTC

Note: Scheduled power on/off is only supported on certain models, such as NanoPC-T4.
You can access RTC by calling APIs under the "/sys/class/rtc/rtc0/" directory. For instance you can check the current RTC time by running the following commands:

cat /sys/class/rtc/rtc0/date
# 2018-10-20                                                              
cat /sys/class/rtc/rtc0/time                                            
# 08:20:14

Set power-on time. For instance power on in 120 seconds:

#Power on in 120 seconds
echo +120 >  /sys/class/rtc/rtc0/wakealarm

RTC

6.7 Watch dog

It is quite straightforward to access the watch dog. You can simply open the "/dev/watchdog" device and write characters to it.If for any reason no characters can be written to the device the system will reboot in a moment:

mWatchDogFD = HardwareControler.open("/dev/watchdog", FileCtlEnum.O_WRONLY);
HardwareControler.write(mWatchDogFD, "a".getBytes());

WatchDog

6.8 SPI

6.8.1 RK3399

6.8.1.1 Enable SPI

The SPI and UART4 share the same pins. You need to modify the kernel's DTS file to enable the SPI by running the following commands:
Edit the DTS file: arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi:

cd ANDROID_SOURCE/kernel
vim arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi

You need to replace "ANDROID_SOURCE" to your real source. In our system it is either Android7's or Android8's source code directory.

Locate spi1's definition:

&spi1 {
    status = "disabled";  // change "disabled" to "okay"

Locate uart4's definition in the rk3399-nanopi4-common.dtsi file:

&uart4 {
    status = "okay";   // change "okay" to "disabled"

Compile kernel:

cd ANDROID_SOURCE/
./build-nanopc-t4.sh -K -M

Use the newly generated "rockdev/Image-nanopc_t4/resource.img" image file to update your system.

6.8.1.2 Testing SPI

By default the SPI is not enabled in your system. You need to manually enable it by making changes to your Android source code:
vendor/friendlyelec/apps# vi device-partial.mk
Remove the comment:

# PRODUCT_PACKAGES += SPI-OLED

Compile Android source code

We connected a FriendlyElec's OLED module which had a 0.96" LCD with a resolution of 128 x 64 and a SPI interface to a NanoPC-T4 and tested it.

The LCD module had 7 pins and here is hardware setup:

OLED Pin Function NanoPC-T4 Pin Comment
GND Pin6 GND
VCC Pin2 VCC5V
DO SCLK Pin23 (SPI1_CLK(3V) Clock generated by master device
DI MOSI Pin19 (SPI1_TXD) Output from master device and input to slave device
RES Pin16 (GPIO1_C6(3V))
D/C Pin12 (GPIO1_C2)
CS CS0 Pin24 (SPI1_CSn0) Signal to enable slave device, set by master device


6.8.2 APIs for Accessing SPI

For more details refer to:FriendlyThings APIs

7 Download Links to Code Samples

All the code samples are included in FriendlyElec's Android source code and are under the "vendor/friendlyelec/apps" directory in Android7.1.2 and Android8.1. Or you can download individual code samples. Here is a list of code samples and their download links:

7.1 Android8.1

7.1.1 Applicable Boards

  • NanoPC-T4/NanoPi-M4/NanoPi-NEO4
Android8.1 Demos
Serial Port

https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/SerialPortDemo

GPIO

https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/GPIO_LED_Demo

ADC

https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/ADCDemo

PWM

https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/PWMDemo

I2C

https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/I2C_LCD1602_Demo

RTC

https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/RTC_Demo-RK3399

Watch dog

https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/WatchDogDemo-RK3399

SPI

https://gitlab.com/friendlyelec/rk3399-android-8.1/tree/master/vendor/friendlyelec/apps/SPI_OLED_Demo

7.2 Android7.1.2

7.2.1 Applicable Boards

  • NanoPC-T4/NanoPi-M4/NanoPi-NEO4
Android7.1.2 Demos
Serial Port

https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/SerialPortDemo

GPIO

https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/GPIO_LED_Demo

ADC

https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/ADCDemo

PWM

https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/PWMDemo

I2C

https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/I2C_LCD1602_Demo

RTC

https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/RTC_Demo-RK3399

Watch dog

https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/WatchDogDemo-RK3399

SPI

https://gitlab.com/friendlyelec/rk3399-nougat/tree/nanopc-t4-nougat/vendor/friendlyelec/apps/SPI_OLED_Demo