GPIO and I2C driver for Android

Although this is documented for the Olimex A20, it actually applies to all Android builds as it is simply a JNI and a JAVA file that allows you to read and write to the I2C bus and control GPIO pins.

I have source code here on my website that you can download and use. There are 3 files. is the Java code for your project and is the functions you will call from your application to do I2C or GPIO. is the JNI C source code that you need to build. You will need the NDK from Android for this. I’ll explain this in a subsequent update when I have time. is a sample file showing how to make calls in Android.


To build the JNI you need the Android NDK (Native Development Kit) which allows you to build C/C++ code that can be executed within your JAVA code.

You need make sure that you chmod 777 the GPIO in your file otherwise you get an exception and the port does not change. Also make sure I2C is chmod 777 too.

By Dave McLaughlin

Creating your own INITLOGO.RLE files

If you follow the details below, you will be able to make your own INITLOGO.RLE file that will appear after the Allwinner logo and before the animation starts.

You will need the ImageMagick suit of tools to add the convert tool. With Ubuntu 10.04 this should already be installed but if not, use the following command to install it.

sudo apt-get install imagemagick

I started with a Windows BMP file that has to be 800 x 480 in size. I then used the following command to convert this to PNG.

convert initlogo.bmp initlogo.png

Then I use the following to convert the image to a RAW format that is the correct size for the RLE encoding later.

convert -depth 16 initlogo.png rgb:initlogo.raw

Next you need to use the pre-compiled rgb2565 that is located in the out/host/linux-x86/bin directory in the Android build. I copied the file to the home/bin directory so that it would run from the PATH I have already setup as part of my Linux installation. Just make sure you can run this file without adding a path to it 🙂

rgb2565 < initlogo.raw > initlogo.rle

You should now have a file that is 1,536,000 bytes in size. If not, check all the commands again. If the file is not this size, it won’t work.


NOW. The only issue I have seen is that the colours are not retained so you need to experiment a little with colours but it looks good enough for now.

By Dave McLaughlin

Using the default 7″ LCD from Olimex

UPDATE 30/9/14

I have had a few messages that calibration is not possible because the package TSCalibration2 is not part of the system. I recall that I deleted this but can’t remember where it was located. Doing a search on the original Olimex code finds nothing.

The good new is that there is only 1 change required to add the calibration to the build. See below where I have added this to the olinuxino-a20,mk file


A number of people have been asking on the Olimex forum on how to get the Olimex 7″ LCD working with resistive touch.

As my source uses the Fusion F07A-0102 I thought I would help in how to make changes to the build to swap to the sun7i touch.

As long as you can build my source, you do not have to make any changes to the linux kernel as I left the module build in there for both touch panels. Display driver timing and touch select is a simple change to the FEX file and comment and uncomment in the init file. Here is the process.

Open the FEX file in the following directory:


Locate the entry [rtp_para] and make sure rtp_used=1

Locate the entry [ctp_para] and make sure ctp_used=0

Locate the entry [lcd0_para] and set the values as this:

lcd_used = 1
lcd_x = 800
lcd_y = 480
lcd_dclk_freq = 33
lcd_pwm_not_used = 0
lcd_pwm_ch = 0
lcd_pwm_freq = 10000
lcd_pwm_pol = 1
lcd_if = 0
lcd_hbp = 46
lcd_ht = 1055
lcd_vbp = 23
lcd_vt = 1050
lcd_hv_if = 0
lcd_hv_smode = 0
lcd_hv_s888_if = 0
lcd_hv_syuv_if = 0
lcd_hv_vspw = 1
lcd_hv_hspw = 30
lcd_lvds_ch = 0
lcd_lvds_mode = 0
lcd_lvds_bitwidth = 0
lcd_lvds_io_cross = 0
lcd_cpu_if = 0
lcd_frm = 1
lcd_io_cfg0 = 268435456
lcd_gamma_correction_en = 0
lcd_gamma_tbl_0 = 0x0
lcd_gamma_tbl_1 = 0x10101
lcd_gamma_tbl_255 = 0xffffff
lcd_bl_en_used = 1
lcd_bl_en = port:PH07<1><0><default><1>
lcd_power_used = 1
lcd_power = port:PH08<1><0><default><1>
lcd_pwm_used = 1
lcd_pwm = port:PB02<2><0><default><default>

Locate the file init.sun7i.rc in the android4.2/device/softwinner/olinuxino-a20 directory and edit the following line to remove the comment. (delete the #) It will be around line 212

insmod /system/vendor/modules/sunxi-ts.ko

This will start the sun7i touch screen driver using the ANALOG inputs on the CPU.

Comment out this line at around line 215

#  insmod /system/vendor/modules/fusion_F0710A.ko

This will disable the CTP driver that I use for capacitive touch.

In the same directory, edit the file as below. This is around line 24. The last line here will be fusion_F0710A.ko so change this to sunxi_ts.ko as below.

# for recovery
 device/softwinner/olinuxino-a20/recovery.fstab:recovery.fstab \
 device/softwinner/olinuxino-a20/modules/modules/disp.ko:disp.ko \
 device/softwinner/olinuxino-a20/modules/modules/lcd.ko:lcd.ko \
 device/softwinner/olinuxino-a20/modules/modules/hdmi.ko:hdmi.ko \
 device/softwinner/olinuxino-a20/modules/modules/hdcp.ko:hdcp.ko \
 device/softwinner/olinuxino-a20/modules/modules/sw_device.ko:sw_device.ko \

Open the file in the device/softwinner/olinuxino-a20 directory and insert the TSCalibration2 file here. It will autostart when Android starts if there is no calibration data. This will create a file called POINTERCAL in the data directory so you can get it to recalibrate on power up by deleting this file.

 gps.exDroid \
 TSCalibration2 \

Now build the Android source with make -j4 and then pack and you should now have an image that will use the resistive touch and drive the LCD with the correct timing. If your LCD is slightly different, you make need to change the FEX settings and then run pack again. No need to do any build if only making changes to the FEX file.

By Dave McLaughlin

Generic RIL to give PPP and SMS

The Olimex supplier RIL Daemon gives you PPP with a GPRS modem connected but I could not get the SMS or USSD to work. I could send SMS but never receive anything.

I found a Huawei Generic RIL on the internet here

This compiled OK but I could not get it to dial out on PPP, it just kept failing to get a connection.  I finally had to modify this to use the SCRIPT method of connection and now I have a working RIL. This is in the latest source that I uploaded.

You can look into the code and see how I did this but for now I will explain how to build the system to use it. It requires nothing more than to open and edit the SYSTEM.PROP file in the following directory


In here you will see these lines

rild.libargs=-d /dev/ttyUSB2 -v /dev/ttyUSB1
#rild.libargs=-d /dev/ttyUSB2

In the sample above,the Huawei Generic library is selected. If you want to switch back to the softwinner one, simple comment and uncomment as required.

With this and using the Huawei library, build the system and you should now have SMS send and receive. You can also do USSD from the phone app too.

NOTE The last thing I am working on is the fact that the messages appear to remain in the SIM memory so once this fills up, the system won’t receive any more. On boot up, I have added a delete of all existing SMS. This is done well before the device is on the network so any new outstanding messages will arrive as normal. It’s still work in progress to sort this out so that the SIM messages are deleted once they are read by the Android system. I’ll update here once the fix is found but if anyone else works it out, let me know.

By Dave McLaughlin

Latest Source Uploaded

The latest source was uploaded to the Google Drive and includes a working RIL that supports PPP and SMS at the same time.

The Huawei Generic RIL was used to replace the Allwinner RIL which would not send or receive SMS.

The new one also supports USSD but needs the phone interface to use this so the build includes this now.

The only outstanding issue is that SMS’s don’t seem to be removed from the SIM so I am still working on code to sort this. You can use the Messaging App to read and delete these from the settings menu. For now I delete any SMS’s stored on boot up as they have already been read. This is done before the system is connected to the network so any new SMS waiting to be delivered are not affected.

I’ll post up the fix once I have it working and fully tested.

Get the code here. Android Source

By Dave McLaughlin

External Battery backed Real Time Clock (RTC) for A20 with Android

I decided that the built in A20 RTC was of no use because there was no way to add a battery backup to the board as Olimex had not brought out the RTC_VDD line from the processor.

As the DS1307, or in my case, the DS1338 was already supported by a kernel driver it should have been a simple process to remove the rtc-sun7i driver and rebuild the kernel with the rtc-ds1307 driver instead.

Well, the rtc-ds1307 driver inclusion was easy as I only had to locate it in the menuconfig for the kernel and enable it with <*>0 so that it would be built as part of the kernel. I didn’t want a module as it should be part of the OS and run on startup.

Well, after building the kernel, it would indeed run on startup and showed up on the dmesg output but rtc0 failed to be created in dev.

It took quite a bit of searching the internet and playing around but I finally figured it out and I was able to add the driver to the kernel and have it startup and create the rtc0 device.

Adding the i2c_board_info

As I2C devices are not auto detected in the system, you have to tell it what they are and where to find them. Locate the following file and edit the sun7i_init function at the bottom.


And insert the following after the sw_pdev_init() function.

 i2c_register_board_info(0, __rtc_i2c_board_info, ARRAY_SIZE(__rtc_i2c_board_info));

The first variable is the I2C bus your RTC is located on. For those who want to use the MOD_RTC on a UEXT, just change this line to match the I2C bus of that socket.

Now add the following at the top of the file, anywhere before the start of the other functions.

static struct i2c_board_info __rtc_i2c_board_info[] =  {
        I2C_BOARD_INFO("ds1307", 0x68),

Next add a #include <linux.i2c.h> to the top of the file so that we include the necessary drivers.

Now rebuild your kernel and then extract-bsp to the Android build and then make Android and pack and flash to your device. You should now have a working RTC but this time, it will be battery backed.

Any issues, pop them in the comments below.

By Dave McLaughlin

7″ Capacitive Touch for A20

I selected the Touch Revolution Fusion F07A-0102 capacitive touch display to work with the A20.

It’s not a drop in replacement hardware wise so I’ve built a custom PCB to connect to the A20 LCD connector. In theory this will work with any of the Olinuxino boards that use the same LCD connector. There is a separate connector for the touch as the existing LCD connector does not have the required I2C interface. In fact, I developed this on Android but there is no reason it won’t work with Linux using the same driver changes.

Out of the box, the display part works without any changes to the build if you already have it configured for the Olimex A13 7″ LCD. It is however much brighter due mainly to the fact that there is less light being lost through the touch panel as you do with resistive panels.

F0710A LCD running with A20.

F07A-0102 LCD running with A20.

PCB for F07A-0102 Cap LCD

PCB for F07A-0102 Cap LCD

The PCB can be fitted with horizontal or vertical connectors. I chose the Samtec horizontal ones as I have no clearance in the enclosure to mount a vertical connector.

For the touch there is a bit of work to add the driver that is supplied by Touch Revolution as it requires changes to work with the AllWinner drivers.

First job was to add the driver to the code and compile it as a module. You just need to follow the Touch Revolution manual for this ignoring the second bit about adding the board modules. These don’t exist in the AllWinner system due to the sys_config.fex configuration method used.

To add this to the Linux kernel as a module, cd in to the linux3.4 directory and type in the following:

make ARCH=arm menuconfig

Navigate down to the drivers entry and then locate sw_touchscreen. In there select the Fusion_F0710A and set if for <m> for module.

Now exit this and save and cd .. back to the lichee directory. Now do the normal build on this with ./ -psun7i_android

Once this builds check that there is a fusion_F0710a.ko file in the linux3.4/output/lib/modules directory and if there is, it is time to make the changes so that it will work with the A20.

Download the following file and drop it in the directory below, over writing the existing file.


Open the sysconfig.fex file for the board and edit the ctp_para section as follows. Also, make sure that ctp_detect_use in the ctp_list_para  section is set for 0 (no detection)

; ctp_int_port EINT12 on PI16 (SPI1_CS0)
; ctp_twi_id TWI2 (dev) TWI0 (release)
ctp_used = 1
ctp_name = "fusion_F0710A"
ctp_twi_id = 1
ctp_twi_addr = 0x10
ctp_screen_max_x = 800
ctp_screen_max_y = 480
ctp_revert_x_flag = 1
ctp_revert_y_flag = 0
ctp_exchange_x_y_flag = 0
ctp_int_port = port:PI16<0><1><default><default>
ctp_wakeup = port:PB13<1><default><default><default>

The ctp_wakeup is not actually used on the first build but I found that leaving this blank caused the system to fail bootup so I set this to an unused GPIO pin. I’ll be enabling this in the new boards and it will use the SPI1_CLK line for this. SPI it not used with the Android build. As the fex file allows configuration, you can move it to any I2C and IO pins. I’ll be moving this to I2C-0 on the final hardware but using I2C-1 for testing via the UEXT connector.

Make sure that the resistive settings are set for used as off.

rtp_used = 0

Then you need to edit the init.sun7i.rc file in the Android build. We need to display the current resistive panel. Locate this line and put a # at the start of it or simply delete this line altogether.

# insmod /system/vendor/modules/sunxi-ts.ko

We don’t need to INSMOD our Fusion driver as the kernel will do this when it detects the ctp panel in the settings when init_input is run. We need though to add our panel to the detection list. Not sure this is actually needed but I added it anyway. Locate the file sw_device.c in linux-3.4/drivers/input and edit it to add this line to the ctps[] structure. Just add it to the end of the existing list.

        {"fusion_F0710A", {      0x10},   0x0D, {0x00                    }, 0},

The Touch Revolution document refers to changing the name of the qwert.idc file to fusion0710A.idc and copying this to the platform. What I did was create a copy of this file and then in the file I added this line to the PRODUCT_COPY_FILES entry. You can put this at the end of the list and put a \ on the line above or do as I did and insert the line below above the last entry.

device/softwinner/olinuxino-a20/fusion0710A.idc:system/usr/idc/fusion0710A.idc \

GPIO Driver

One last change needed is to fix the GPIO interrupt driver as I found that it was outputing an error each time I touched the screen. It shouldn’t be as the interrupt was being handled correctly and passing back the correct IRQ_HANDLED flag. This fix will stop it from doing this.

Locate the file gpio_eint.c in the following directory:


Edit the function right at the end called gpio_irq_hdl. The following line needs to be changed.

if (pdev_id->handler(pdev_id->parg)) {

to this

if (pdev_id->handler(pdev_id->parg) != IRQ_HANDLED) {

IRQ_HANDLED is defined as (1<<0) so when the IRQ handler for the screen returns this line would always be true and show a failed handler. This in fact would be incorrect.

If you build the code now it will support touch.

As of March 22nd I’ve not been able to get pinch to zoom working and the driver does appear to send 2 touch commands to the kernel so not sure what’s wrong yet. Still working on this.


As of 27th March, I have made a couple of small changes that fix and issue where I could not swipe down from the task bar. It’s caused by legacy resistive touch support still on the system and this was causing incorrect position data to be sent to the kernel.

If your system has the pointercal file in the data directory from previous use of a resistive touch panel, delete this file and change the sys_config.fex file to remove the invert on the X position. Rebuild and deploy the updated build and you will now have a fully working touch with pull down from the task bar.



10″ Support

The 10″ panel from Touch Revolution has the same I2C for the touch and should work with this same code. There will be changes needed for the LCD as the 10″ LCD uses LVDS but as the A20 is configurable for LVDS it remains only to configure the output and create a suitable PCB for it. The current PCB shape is not suitable for the 10″ panel.

By Dave McLaughlin

PPP now working with existing RIL and Huawei Generic RIL

I’ve finally gotten PPP to work. I had missed out the chat driver that handles the PPP connection. In fact, I had removed this thinking it was a chat type app like WhatsApp. Ooops.

Anyway, for those with the existing code from the download, here is the change you need to do.

Locate this file:


And add the following line to the second PRODUCT_PACKES += entry.

chat \

This will make sure that chat is used.

It also works with the existing softwinnder RIL and the Huawei RIL.

I also got SMS to partially work. It seems to work sending the first time then nothing after this. Same with receive, so I am still working on this part. You need to locate the AT+CNMI line in the source or in the file with a hex editor and change this to 1,2,0,0,0 to get it working the same as I have. The existing setting is set not to pass through SMS to the module.

I’ll document later when I get SMS working and I will be updating the source code on the Google Drive with the fully working version soon.

By Dave McLaughlin

Source Code for Build is now available

I have put on Google Drive the source for the build. It has a few specials so you’ll need to do some little changes to meet your own needs but if you have a 7″ LCD then this will build and work straight off on the A20.

I’ll try to document what you need to do below any changes as I go along.

I have included a rather nice BootAnimation that is set for 800 x 480 display.

3G Library

The 3G library from Softwinner does not handle SMS for some reason. the CNMI command found in the binary file is set to now send any unsolicited SMS message and there is no CMGL command to request them so it appears that the library is for PPP only. It does send SMS.

I started to try and port the HuaweiGenericRil.lib to the platform but so far still no SMS receive. It’s a work in progress.

To enable and disable to 2 libraries, navigate to the android4.2/device/softwinner/olinuxino-a20 directory and in there you will find a system.prop file. Open this and edit the following lines but changing the comment marker to the library you don’t want to use.


For example, I have it for the Huawei library as supplied.

Everything else should give you a working Android platform and if you have any feedback of questions, then please feel free to post a comment about it.

Reflashing the Image

When you reflash the image to the SD or NAND (I use SD for now until development is completed) choose the NO option in Phoenixsuit and then your exisitng configuration and data is untouched.

By Dave McLaughlin