Error Writing on I2C Bus with Device I/O Library

Sergio Lopes Junior - Embrapa Arroz e Feijao - CNPAF sergio.lopes at embrapa.br
Fri Feb 3 14:54:34 UTC 2017


Hi guys, 


We have encountered an error using the Device I/O library to access an Analog Digital Converter - ADC (MCP3424 chip) 
by I2C bus with recent versions of java (above version 1.8.0_71). 


We are using the Toradex iMX6 DualLite 512MB IT card (https://www.toradex.com/en/computer-on-modules/colibri-arm-family/nxp-freescale-imx6). 
This board uses a linux based on OpenEmbedded (http://www.openembedded.org/wiki/Main_Page) and 
has an ARMv7 architecture: 


uname -a 
Linux colibri-imx6 3.10.17-dirty #16 SMP Thu Jan 7 09:48:46 BRST 2016 armv7l GNU/Linux 




Whenever an attempt is made to write to the I2C bus, the jdk.dio.UnavailableDeviceException exception is thrown 
with the message "Locked by other application". To analyze the error we wrote an example application with the 
class DeviceIOSamples and copied all its files to the / opt / deviceIOSamples directory on the Toradex card: 

ls -l /opt/deviceIOSamples 
-rw-r--r-- 1 root root 3569 Feb 2 16:43 DeviceIOSamples-0.0.1.jar 
-rwxr-xr-x 1 root root 427 Feb 2 16:19 deviceIOSamples.sh 
-rw-r--r-- 1 root root 197907 Feb 1 13:54 dio.jar 
-rw-r--r-- 1 root root 1326 Feb 2 13:29 dio.properties 
-rw-r--r-- 1 root root 2406 Dec 16 11:51 java.policy 
-rw-r--r-- 1 root root 138324 Feb 1 13:54 libdio.so 


When running the application with jdk version 1.8.0_71 (jdk1.8.0_71-b15), everything works correctly: 

java -version 
java version "1.8.0_71" 
Java(TM) SE Runtime Environment (build 1.8.0_71-b15) 
Java HotSpot(TM) Client VM (build 25.71-b15, mixed mode) 


cd /opt/deviceIOSamples 


./deviceIOSamples.sh 
---------------------------------------------------- 
I2C Device Test (MCP3424 ADC Chip) 
Channel = 3, resolution = 18 bits and pga = x1 
---------------------------------------------------- 
1 - opening adc device 
2 - send configuration to adc device 
3 - reading bytes referring to the conversion performed by the adc device 
4 - successful conversion of analogue value 
---------------------------------------------------- 
Analog Value = 0.6563593750000001 mV 
---------------------------------------------------- 


When changing the java to any version after 1.8.0_71 the error appears: 

java -version 
java version "1.8.0_121" 
Java(TM) SE Runtime Environment (build 1.8.0_121-b13) 
Java HotSpot(TM) Client VM (build 25.121-b13, mixed mode) 


cd /opt/deviceIOSamples 


./deviceIOSamples.sh 
---------------------------------------------------- 
I2C Device Test (MCP3424 ADC Chip) 
Channel = 3, resolution = 18 bits and pga = x1 
---------------------------------------------------- 
1 - opening adc device 
2 - send configuration to adc device 
---------------------------------------------------- 
jdk.dio.UnavailableDeviceException: Locked by other application 
at com.oracle.dio.impl.AbstractPeripheral.conditionalLock(AbstractPeripheral.java:99) 
at com.oracle.dio.i2cbus.impl.I2CSlaveImpl.transfer(I2CSlaveImpl.java:224) 
at com.oracle.dio.i2cbus.impl.I2CSlaveImpl.write(I2CSlaveImpl.java:168) 
at com.oracle.dio.i2cbus.impl.I2CSlaveImpl.write(I2CSlaveImpl.java:178) 
at DeviceIOSamples.main(DeviceIOSamples.java:28) 
---------------------------------------------------- 



We already tested several versions of java after version 1.8.0_71 and in all them, the same error appears when writing on the I2C bus. 
We have reached a deadlock in the project regarding the use of the Device I/O library, because we need to use I2C devices. 
If we can not solve this problem, we will have to abandon it and move on to another hardware access strategy. 


Has anyone had this or could you help us? Any help will be very welcome. 




Thank you, 


Sergio Lopes Jr. 

Software developer at Embrapa Rice and Bean, 
Goiânia / GO - Brazil. 




>>>>>>>>>>>>>>> Compilation of the Device I / O library: <<<<<<<<<<<<<<< 

The compilation of the Device I / O library was performed with linaro on linux Ubuntu 32 bit: 

sudo apt-get update 
sudo apt-get upgrade 
wget -c https://releases.linaro.org/components/toolchain/binaries/latest-6/arm-linux-gnueabihf/gcc-linaro-6.2.1-2016.11-i686_arm-linux-gnueabihf.tar.xz 
sudo tar -xvf gcc-linaro-6.2.1-2016.11-i686_arm-linux-gnueabihf.tar.xz -C /opt 
sudo mv /opt/gcc-linaro-6.2.1-2016.11-i686_arm-linux-gnueabihf /opt/gcc-linaro 
export PATH=/opt/gcc-linaro/bin:$PATH 
export PI_TOOLS=/opt/gcc-linaro 
export CROSS_COMPILE=arm-linux-gnueabihf- 


Download file jdk-8u121-linux-x64.tar.gz no endereço http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html?ssSourceSiteId=otnpt 
sudo tar -zxvf jdk-8u121-linux-x64.tar.gz -C /opt 
sudo mv /opt/jdk1.8.0_121 /opt/java 
export JAVA_HOME=/opt/java 
export PATH=$JAVA_HOME/bin:$PATH 


hg clone http://hg.openjdk.java.net/dio/dev dio 
cd dio 
Replace the lines in the Makefile: 
TARGET_CC := $(TARGET_TOOLCHAIN)/bin/gcc 
TARGET_CXX := $(TARGET_TOOLCHAIN)/bin/g++ 
TARGET_LD := $(TARGET_TOOLCHAIN)/bin/gcc 
For: 
TARGET_CC := $(TARGET_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc 
TARGET_CXX := $(TARGET_TOOLCHAIN)/bin/arm-linux-gnueabihf-g++ 
TARGET_LD := $(TARGET_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc 
make ARCH=arm 
Copy the dio/build/jar/dio.jar and dio/build/so/libdio.so files to the application directory 





>>>>>>>>>>>>>>> Sample application class (DeviceIOSamples.java): <<<<<<<<<<<<<<< 


import java.nio.ByteBuffer; 
import java.time.ZonedDateTime; 


import jdk.dio.DeviceManager; 
import jdk.dio.i2cbus.I2CDevice; 


public class DeviceIOSamples { 

public static void main(String[] args) { 

System.out.println("----------------------------------------------------"); 
System.out.println("I2C Device Test (MCP3424 ADC Chip)"); 
System.out.println("Channel = 3, resolution = 18 bits and pga = x1"); 
System.out.println("----------------------------------------------------"); 
try { 
// MCP3424 chip configuration 
// bit 7 : Operation set bit. 0 = set configuration and 1 = start a new conversion. 
// bit 6-5: Channel Selection Bits. 00 = channel 1, 01 = channel 2, 10 = channel 3 and 11 = channel 4. 
// bit 4 : Conversion Mode Bit. 1 = Continuous Conversion Mode (Default) and 0 = One-Shot Conversion Mode. 
// bit 3-2: Sample Rate Selection Bit. 00 = 240 SPS (12 bits), 01 = 60 SPS (14 bits), 10 = 15 SPS (16 bits) and 11 = 3.75 SPS (18 bits). 
// bit 1-0: PGA Gain Selection Bits. 00 = x1, 01 = x2, 10 = x4 and 11 = x8. 


// opening adc device (MCP3424 chip) 
// 100 = deviceType:i2cbus.I2CDevice, name:ADC_1, controllerNumber:1, address:0x68 (dio.properties) 
System.out.println("1 - opening adc device"); 
I2CDevice i2cDevice = (I2CDevice) DeviceManager.open(100); 

// send configuration to adc device (operation = start-new-conversion, channel = 3, conversion-mode = one-shot , resolution = 18 bits and pga = x1) 
System.out.println("2 - send configuration to adc device"); 
i2cDevice.write(0b11001100); 


// reading bytes referring to the conversion performed by the adc device 
System.out.println("3 - reading bytes referring to the conversion performed by the adc device"); 
int timeout = 1000; // timeout for analog value conversion in ms 
ByteBuffer buffer = ByteBuffer.allocate(4); 
int adcValue = 0; 
double voltage = 0; 
long startTime = ZonedDateTime.now().toInstant().toEpochMilli(); 
long currentTime = startTime; 
while (true) { 

// checking that exceeded the timeout for the operation 
currentTime = ZonedDateTime.now().toInstant().toEpochMilli(); 
if ((currentTime - startTime) > timeout) { 
throw new Exception("Exceeded the timeout for analog value conversion"); 
} 

// clear buffer 
buffer.clear(); 


// reading bytes from ADC 
i2cDevice.read(buffer); 


// checking that successfully performed reading 
if ((buffer.get(3) >>> 7) == 1){ 
continue; 
}; 

// calculating voltage value 
adcValue = ((buffer.get(0) & 0b00000011) << 16) | ((buffer.get(1) & 0xFF) << 8) | (buffer.get(2) & 0xFF); 
voltage = (((adcValue * (0.0000078125 / 0.5))) * 2.471) * 1000; 

// checking that it is valid voltage 
if (voltage >= 0) { 
break; 
} 
} 

// successful conversion of analogue value 
System.out.println("4 - successful conversion of analogue value"); 
System.out.println("----------------------------------------------------"); 
System.out.println("Analog Value = " + voltage + " mV"); 
System.out.println("----------------------------------------------------"); 

} catch (Exception e) { 

// error in conversion of analogue value 
System.out.println("----------------------------------------------------"); 
e.printStackTrace(); 
System.out.println("----------------------------------------------------"); 
} 
} 
} 




>>>>>>>>>>>>>>>>>> Device I/O Properties File (dio.properties): <<<<<<<<<<<<<<<<<<<< 


# DEFAULT CONFIG 
gpio.GPIOPin = direction:0, mode:1, trigger:0, initValue:0, predefined:true 
uart.UART = baudRate:9600, parity:0, dataBits:8, stopBits:1, flowControl:0, predefined:true 
i2cbus.I2CDevice = addressSize:7, clockFrequency:-1, predefined:true 


# ADC device (chip MCP3424): 
# - i2c address : 0x68 
# - resolution : 18 bits 
# - conversion mode : one-shot 
# - programmable gain amplifier (PGA) : 1 
# - channels address : 1 = 0x50, 2 = 0x70, 3 = 0x10 and 4 = 0x30. 
100 = deviceType:i2cbus.I2CDevice, name:ADC_1, controllerNumber:1, address:0x68 




>>>>>>>>>>>>>>>>>>>>>> Java Police File (java.policy): <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 


grant { 
permission "java.util.PropertyPermission" "jdk.dio.registry", "read"; 
permission "java.io.FilePermission" "./dio.properties-raspberrypi", "read,write"; 
permission "java.lang.RuntimePermission" "loadLibrary.dio"; 
permission "java.util.PropertyPermission" "user.dir", "read"; 
permission jdk.dio.DeviceMgmtPermission "*:*", "open"; 
permission jdk.dio.adc.ADCPermission "*:*"; 
permission jdk.dio.atcmd.ATPermission "*:*"; 
permission jdk.dio.counter.CounterPermission "*:*"; 
permission jdk.dio.dac.DACPermission "*:*"; 
permission jdk.dio.generic.GenericPermission "*:*"; 
permission jdk.dio.gpio.GPIOPinPermission "*:*", "open,setdirection"; 
permission jdk.dio.gpio.GPIOPortPermission "*:*"; 
permission jdk.dio.i2cbus.I2CPermission "*:*", "open,powermanage"; 
permission jdk.dio.pwm.PWMPermission "*:*"; 
permission jdk.dio.spibus.SPIPermission "*:*"; 
permission jdk.dio.uart.UARTPermission "*:*"; 
permission jdk.dio.watchdog.WatchdogTimerPermission "*:*"; 
}; 




>>>>>>>>>>> Script to run the sample application (deviceIOSamples.sh): <<<<<<<<<<< 


java -Xmx64m \ 
-classpath /opt/deviceIOSamples:/opt/deviceIOSamples/dio.jar:/opt/deviceIOSamples/DeviceIOSamples-0.0.1.jar:$CLASSPATH \ 
-Djava.library.path=/opt/deviceIOSamples \ 
-Djdk.dio.registry=/opt/deviceIOSamples/dio.properties \ 
-Djava.security.policy=/opt/deviceIOSamples/java.policy \ 
-Duser.country=BR \ 
-Duser.language=pt \ 
-Duser.timezone=America/Sao_Paulo \ 
DeviceIOSamples 


____________________________________________________________________________ 
Aviso de confidencialidade 

Esta mensagem da Empresa Brasileira de Pesquisa Agropecuaria (Embrapa), 
empresa publica federal regida pelo disposto na Lei Federal no. 5.851, de 
7 de dezembro de 1972, e enviada exclusivamente a seu destinatario e pode 
conter informacoes confidenciais, protegidas por sigilo profissional. Sua 
utilizacao desautorizada e ilegal e sujeita o infrator as penas da lei. Se 
voce a recebeu indevidamente, queira, por gentileza, reenvia-la ao emitente, 
esclarecendo o equivoco. 

Confidentiality note 

This message from Empresa Brasileira de Pesquisa Agropecuaria (Embrapa), a 
government company established under Brazilian law (5.851/72), is directed 
exclusively to its addressee and may contain confidential data, protected 
under professional secrecy rules. Its unauthorized use is illegal and may 
subject the transgressor to the law's penalties. If you are not the addressee, 
please send it back, elucidating the failure. 


____________________________________________________________________________
Aviso de confidencialidade 

Esta mensagem da Empresa  Brasileira de Pesquisa  Agropecuaria  (Embrapa),
empresa publica federal  regida pelo disposto  na Lei Federal no. 5.851,  de
7 de dezembro de 1972,  e  enviada exclusivamente  a seu destinatario e pode
conter informacoes  confidenciais, protegidas  por sigilo profissional.  Sua
utilizacao desautorizada  e ilegal e  sujeita o infrator as penas da lei. Se
voce  a recebeu indevidamente, queira, por gentileza, reenvia-la ao emitente,
esclarecendo o equivoco.

Confidentiality note

This message from Empresa  Brasileira de Pesquisa  Agropecuaria  (Embrapa), a
government company  established under  Brazilian law  (5.851/72), is directed
exclusively to  its addressee  and may contain  confidential data,  protected
under  professional secrecy  rules. Its unauthorized  use is illegal and  may
subject the transgressor to the law's penalties. If you are not the addressee,
please send it back, elucidating the failure.


More information about the dio-dev mailing list