Skip to content

Commit 5643287

Browse files
committed
Add I/O library for Raspberry Pi and similar Linux-based micro computers
1 parent 68397e8 commit 5643287

16 files changed

Lines changed: 1827 additions & 0 deletions

File tree

java/libraries/io/build.xml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0"?>
2+
<project name="Processing I/O Library" default="build">
3+
4+
<target name="clean" description="Clean the build directories">
5+
<delete dir="bin" />
6+
<delete file="library/io.jar" />
7+
</target>
8+
9+
<target name="compile" description="Compile sources">
10+
<condition property="core-built">
11+
<available file="../../../core/library/core.jar" />
12+
</condition>
13+
<fail unless="core-built" message="Please build the core library first and make sure it sits in ../../../core/library/core.jar" />
14+
15+
<mkdir dir="bin" />
16+
<javac source="1.7"
17+
target="1.7"
18+
srcdir="src" destdir="bin"
19+
encoding="UTF-8"
20+
includeAntRuntime="false"
21+
classpath="../../../core/library/core.jar"
22+
nowarn="true"
23+
compiler="org.eclipse.jdt.core.JDTCompilerAdapter">
24+
<compilerclasspath path="../../mode/org.eclipse.jdt.core.jar;
25+
../../mode/jdtCompilerAdapter.jar" />
26+
</javac>
27+
</target>
28+
29+
<target name="build" depends="compile" description="Build I/O library">
30+
<jar basedir="bin" destfile="library/io.jar" />
31+
</target>
32+
</project>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
name = I/O
2+
version = 1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
name = I/O for Raspberry Pi and other Linux-based computers
29.4 KB
Binary file not shown.
31.4 KB
Binary file not shown.
32.8 KB
Binary file not shown.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
TARGET := libprocessing-io.so
2+
OBJS := impl.o
3+
CC := gcc
4+
5+
CFLAGS := -std=c99 -fPIC -g
6+
CFLAGS += -I$(shell dirname $(shell realpath $(shell which javac)))/../include
7+
CFLAGS += -I$(shell dirname $(shell realpath $(shell which javac)))/../include/linux
8+
LDFLAGS := -shared
9+
10+
$(TARGET): $(OBJS)
11+
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
12+
13+
iface.h:
14+
javah -classpath .. -o iface.h processing.io.NativeInterface
15+
16+
clean:
17+
rm -f $(TARGET) $(OBJS)

java/libraries/io/src/native/iface.h

Lines changed: 85 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
/*
2+
Copyright (c) The Processing Foundation 2015
3+
I/O library developed by Gottfried Haider as part of GSOC 2015
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General
16+
Public License along with this library; if not, write to the
17+
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18+
Boston, MA 02111-1307 USA
19+
*/
20+
21+
#include <errno.h>
22+
#include <fcntl.h>
23+
#include <jni.h>
24+
#include <linux/i2c.h>
25+
#include <linux/i2c-dev.h>
26+
#include <linux/spi/spidev.h>
27+
#include <poll.h>
28+
#include <stdint.h>
29+
#include <stdlib.h>
30+
#include <string.h>
31+
#include <sys/ioctl.h>
32+
#include <sys/param.h>
33+
#include <unistd.h>
34+
#include "iface.h"
35+
36+
37+
JNIEXPORT jint JNICALL Java_processing_io_NativeInterface_openDevice
38+
(JNIEnv *env, jclass cls, jstring _fn)
39+
{
40+
const char *fn = (*env)->GetStringUTFChars(env, _fn, JNI_FALSE);
41+
int file = open(fn, O_RDWR);
42+
(*env)->ReleaseStringUTFChars(env, _fn, fn);
43+
if (file < 0) {
44+
return -errno;
45+
} else {
46+
return file;
47+
}
48+
}
49+
50+
51+
JNIEXPORT jstring JNICALL Java_processing_io_NativeInterface_getError
52+
(JNIEnv *env, jclass cls, jint _errno)
53+
{
54+
char *msg = strerror(abs(_errno));
55+
if (msg) {
56+
return (*env)->NewStringUTF(env, msg);
57+
} else {
58+
return NULL;
59+
}
60+
}
61+
62+
63+
JNIEXPORT jint JNICALL Java_processing_io_NativeInterface_closeDevice
64+
(JNIEnv *env, jclass cls, jint handle)
65+
{
66+
if (close(handle) < 0) {
67+
return -errno;
68+
} else {
69+
return 0;
70+
}
71+
}
72+
73+
74+
JNIEXPORT jint JNICALL Java_processing_io_NativeInterface_readFile
75+
(JNIEnv *env, jclass cls, jstring _fn, jbyteArray _in)
76+
{
77+
const char *fn = (*env)->GetStringUTFChars(env, _fn, JNI_FALSE);
78+
int file = open(fn, O_RDONLY);
79+
(*env)->ReleaseStringUTFChars(env, _fn, fn);
80+
if (file < 0) {
81+
return -errno;
82+
}
83+
84+
jbyte *in = (*env)->GetByteArrayElements(env, _in, NULL);
85+
int len = read(file, in, (*env)->GetArrayLength(env, _in));
86+
if (len < 0) {
87+
len = -errno;
88+
}
89+
(*env)->ReleaseByteArrayElements(env, _in, in, 0);
90+
91+
close(file);
92+
return len;
93+
}
94+
95+
96+
JNIEXPORT jint JNICALL Java_processing_io_NativeInterface_writeFile
97+
(JNIEnv *env, jclass cls, jstring _fn, jbyteArray _out)
98+
{
99+
const char *fn = (*env)->GetStringUTFChars(env, _fn, JNI_FALSE);
100+
int file = open(fn, O_WRONLY);
101+
(*env)->ReleaseStringUTFChars(env, _fn, fn);
102+
if (file < 0) {
103+
return -errno;
104+
}
105+
106+
jbyte *out = (*env)->GetByteArrayElements(env, _out, JNI_FALSE);
107+
int len = write(file, out, (*env)->GetArrayLength(env, _out));
108+
if (len < 0) {
109+
len = -errno;
110+
}
111+
(*env)->ReleaseByteArrayElements(env, _out, out, JNI_ABORT);
112+
113+
close(file);
114+
return len;
115+
}
116+
117+
118+
JNIEXPORT jint JNICALL Java_processing_io_NativeInterface_pollDevice
119+
(JNIEnv *env, jclass cls, jstring _fn, jint timeout)
120+
{
121+
const char *fn = (*env)->GetStringUTFChars(env, _fn, JNI_FALSE);
122+
int file = open(fn, O_RDONLY|O_NONBLOCK);
123+
(*env)->ReleaseStringUTFChars(env, _fn, fn);
124+
if (file < 0) {
125+
return -errno;
126+
}
127+
128+
// dummy read
129+
char tmp;
130+
while (0 < read(file, &tmp, 1));
131+
132+
struct pollfd fds[1];
133+
memset(fds, 0, sizeof(fds));
134+
fds[0].fd = file;
135+
fds[0].events = POLLPRI|POLLERR;
136+
137+
// and wait
138+
int ret = poll(fds, 1, timeout);
139+
close(file);
140+
141+
if (ret < 0) {
142+
return -errno;
143+
} else if (ret == 0) {
144+
// timeout
145+
return 0;
146+
} else if (fds[0].revents & POLLPRI) {
147+
// interrupt
148+
return 1;
149+
} else {
150+
// POLLERR?
151+
return -ENOMSG;
152+
}
153+
}
154+
155+
156+
JNIEXPORT jint JNICALL Java_processing_io_NativeInterface_transferI2c
157+
(JNIEnv *env, jclass cls, jint handle, jint slave, jbyteArray _out, jbyteArray _in)
158+
{
159+
struct i2c_rdwr_ioctl_data packets;
160+
struct i2c_msg msgs[2];
161+
jbyte *out, *in;
162+
163+
packets.msgs = msgs;
164+
165+
msgs[0].addr = slave;
166+
msgs[0].flags = 0;
167+
msgs[0].len = (*env)->GetArrayLength(env, _out);
168+
out = (*env)->GetByteArrayElements(env, _out, NULL);
169+
msgs[0].buf = out;
170+
if (_in != NULL) {
171+
in = (*env)->GetByteArrayElements(env, _in, NULL);
172+
msgs[1].addr = slave;
173+
msgs[1].flags = I2C_M_RD; // I2C_M_RECV_LEN is not supported
174+
msgs[1].len = (*env)->GetArrayLength(env, _in);
175+
msgs[1].buf = in;
176+
packets.nmsgs = 2;
177+
} else {
178+
packets.nmsgs = 1;
179+
}
180+
181+
int ret = ioctl(handle, I2C_RDWR, &packets);
182+
if (ret < 0) {
183+
ret = -errno;
184+
}
185+
186+
(*env)->ReleaseByteArrayElements(env, _out, out, JNI_ABORT);
187+
if (_in != NULL) {
188+
(*env)->ReleaseByteArrayElements(env, _in, in, 0);
189+
}
190+
191+
return ret;
192+
}
193+
194+
195+
JNIEXPORT jint JNICALL Java_processing_io_NativeInterface_setSpiSettings
196+
(JNIEnv *env, jclass cls, jint handle, jint _maxSpeed, jint dataOrder, jint mode)
197+
{
198+
uint8_t tmp;
199+
uint32_t maxSpeed;
200+
201+
tmp = (uint8_t)mode;
202+
int ret = ioctl(handle, SPI_IOC_WR_MODE, &tmp);
203+
if (ret < 0) {
204+
return ret;
205+
}
206+
207+
tmp = (uint8_t)dataOrder;
208+
ret = ioctl(handle, SPI_IOC_WR_LSB_FIRST, &tmp);
209+
if (ret < 0) {
210+
return ret;
211+
}
212+
213+
maxSpeed = (uint32_t)_maxSpeed;
214+
ret = ioctl(handle, SPI_IOC_WR_MAX_SPEED_HZ, &maxSpeed);
215+
if (ret < 0) {
216+
return ret;
217+
}
218+
219+
return 0;
220+
}
221+
222+
223+
JNIEXPORT jint JNICALL Java_processing_io_NativeInterface_transferSpi
224+
(JNIEnv *env, jclass cls, jint handle, jbyteArray _out, jbyteArray _in)
225+
{
226+
jbyte* out = (*env)->GetByteArrayElements(env, _out, NULL);
227+
jbyte* in = (*env)->GetByteArrayElements(env, _in, NULL);
228+
229+
struct spi_ioc_transfer xfer = {
230+
.tx_buf = (unsigned long)out,
231+
.rx_buf = (unsigned long)in,
232+
.len = MIN((*env)->GetArrayLength(env, _out), (*env)->GetArrayLength(env, _in)),
233+
};
234+
235+
int ret = ioctl(handle, SPI_IOC_MESSAGE(1), &xfer);
236+
237+
(*env)->ReleaseByteArrayElements(env, _out, out, JNI_ABORT);
238+
(*env)->ReleaseByteArrayElements(env, _in, in, 0);
239+
240+
return ret;
241+
}

0 commit comments

Comments
 (0)