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