I am using JNA library to call native C on a BeagleBone for communication to the I2C bus. Communication to I2C bus requires low level file actions such as open, ioctl, close, read, and write. I am able to open the bus file no problem but I cannot get ioctl to work. If I could get this working I believe I would have I2C function working on either BeagleBone Black or Raspberry Pi. Here is my code
`
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import com.sun.jna.*;
public class Main {
static Linux_C_lib_DirectMapping libC = new Linux_C_lib_DirectMapping();
public static int O_RDWR = 0x00000002;
public static void main(String[] args) {
new Main();
}
public Main(){
System.setProperty(“jna.library.path”,"/usr/lib/cgi-bin/jna");
//Open I2C Bus 1 file
String fileName = “/dev/i2c-1”;
int file = libC.open(fileName, O_RDWR);
if(file<0){
System.out.println(“Error opening file”);
return;
}else{
System.out.println(“File open for reading and writing”);
}
//Print out returned value from file open
System.out.println(file);
//initiate connection to chip. I2C chip I am using mounts on 0x21
int[] addr = {0x21};
int i2c_slave = 0x0703;
//This is what fails. I always get -1 back.
int iocntl = libC.ioctl(file, i2c_slave, addr);
//Print returned value after ioctl action
System.out.println("fcntl = "+iocntl);
if(iocntl<0){
System.out.println(“error on libC.ioctl”);
libC.close(file);
return;
}else{
System.out.println(“ioctl complete”);
}
//Initialize communication to chip
byte[] buf = {0,0};
if(libC.write(file, buf, 2) != 2){
System.out.println(“error writing”);
libC.close(file);
return;
}else{
System.out.println(“I2C chip initialized”);
}
while(true){
if(turnOnAllRelays(file)){
try {
Thread.sleep(1000);
turnOffAllRelays(file);
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public boolean turnOnAllRelays(int file){
byte[] buffer = {0xA,0xF};
if(libC.write(file, buffer, 2) != 2){
System.out.println(“all relays on”);
return true;
}else{
System.out.println(“failed to turn all relays on”);
libC.close(file);
return false;
}
}
public boolean turnOffAllRelays(int file){
byte[] buffer = {0xA, 0x0};
if(libC.write(file, buffer, 2) != 2){
System.out.println(“all relays off”);
return true;
}else{
System.out.println(“failed to turn all relays off”);
libC.close(file);
return false;
}
}
public interface Linux_C_lib extends com.sun.jna.Library {
public long memcpy(int[] dst, short[] src, long n);
public int memcpy(int[] dst, short[] src, int n);
public int pipe(int[] fds);
public int tcdrain(int fd);
public int fcntl(int fd, int cmd, int arg);
public int ioctl(int fd, int cmd, int[] arg);
public int open(String path, int flags);
public int close(int fd);
public int write(int fd, byte[] buffer, int count);
public int read(int fd, byte[] buffer, int count);
public long write(int fd, byte[] buffer, long count);
public long read(int fd, byte[] buffer, long count);
public int select(int n, int[] read, int[] write, int[] error, timeval timeout);
public int poll(int[] fds, int nfds, int timeout);
public int tcflush(int fd, int qs);
public void perror(String msg);
public int tcsendbreak(int fd, int duration);
static public class timeval extends Structure {
public NativeLong tv_sec;
public NativeLong tv_usec;
@Override
protected List getFieldOrder() {
return Arrays.asList(//
“tv_sec”,//
“tv_usec”//
);
}
public timeval(jtermios.TimeVal timeout) {
tv_sec = new NativeLong(timeout.tv_sec);
tv_usec = new NativeLong(timeout.tv_usec);
}
}
}
public static class Linux_C_lib_DirectMapping implements Linux_C_lib {
native public long memcpy(int[] dst, short[] src, long n);
native public int memcpy(int[] dst, short[] src, int n);
native public int pipe(int[] fds);
native public int tcdrain(int fd);
native public int fcntl(int fd, int cmd, int arg);
native public int ioctl(int fd, int cmd, int[] arg);
native public int open(String path, int flags);
native public int close(int fd);
native public int write(int fd, byte[] buffer, int count);
native public int read(int fd, byte[] buffer, int count);
native public long write(int fd, byte[] buffer, long count);
native public long read(int fd, byte[] buffer, long count);
native public int select(int n, int[] read, int[] write, int[] error, timeval timeout);
native public int poll(int[] fds, int nfds, int timeout);
native public int tcflush(int fd, int qs);
native public void perror(String msg);
native public int tcsendbreak(int fd, int duration);
static {
try {
Native.register(“c”);
System.out.println(“registered to c library”);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
`
While the open call does work through JNA calling ioctl always returns -1. I am not familiar with this function since I have not done much C programming but accordingly to the example code from Linux here it means the function failed:http://elinux.org/Interfacing_with_I2C_Devices
I should note that I got the idea to use JNA for these functions from the developer of purjavacomm who seemed to use it successfully.
Anyone have any ideas where I am going wrong here?