This repository was archived by the owner on Jan 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSpi.java
More file actions
421 lines (387 loc) · 15 KB
/
Copy pathSpi.java
File metadata and controls
421 lines (387 loc) · 15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
/*
* Copyright (c) Steven P. Goldsmith. All rights reserved.
*/
package com.codeferm.periphery;
import static com.codeferm.periphery.Common.MAX_CHAR_ARRAY_LEN;
import static com.codeferm.periphery.Common.jString;
import static com.codeferm.periphery.Common.memMove;
import static org.fusesource.hawtjni.runtime.FieldFlag.CONSTANT;
import org.fusesource.hawtjni.runtime.JniClass;
import org.fusesource.hawtjni.runtime.JniField;
import org.fusesource.hawtjni.runtime.JniMethod;
import org.fusesource.hawtjni.runtime.Library;
import static org.fusesource.hawtjni.runtime.MethodFlag.CONSTANT_INITIALIZER;
/**
* c-periphery SPI wrapper functions for Linux userspace spidev devices.
*
* @author Steven P. Goldsmith
* @version 1.0.0
* @since 1.0.0
*/
@JniClass
public class Spi implements AutoCloseable {
/**
* Function was successful.
*/
public static final int SPI_SUCCESS = 0;
/**
* java-periphery library.
*/
private static final Library LIBRARY = new Library("java-periphery", Spi.class);
/**
* SPI handle.
*/
final private long handle;
/**
* Load library.
*/
static {
LIBRARY.load();
init();
}
/**
* Load constants.
*/
@JniMethod(flags = {CONSTANT_INITIALIZER})
private static native void init();
/**
* Error constants.
*/
@JniField(flags = {CONSTANT})
public static int SPI_ERROR_ARG;
@JniField(flags = {CONSTANT})
public static int SPI_ERROR_OPEN;
@JniField(flags = {CONSTANT})
public static int SPI_ERROR_QUERY;
@JniField(flags = {CONSTANT})
public static int SPI_ERROR_CONFIGURE;
@JniField(flags = {CONSTANT})
public static int SPI_ERROR_TRANSFER;
@JniField(flags = {CONSTANT})
public static int SPI_ERROR_CLOSE;
/**
* Bit order constants.
*/
@JniField(flags = {CONSTANT})
public static int MSB_FIRST;
@JniField(flags = {CONSTANT})
public static int LSB_FIRST;
/**
* Open the spidev device at the specified path (e.g. "/dev/spidev1.0"), with the specified SPI mode, specified max speed in
* hertz, and the defaults of MSB_FIRST bit order, and 8 bits per word.
*
* @param path spidev path.
* @param mode Mode can be 0, 1, 2, or 3.
* @param maxSpeed Max speed in hertz.
*/
public Spi(final String path, final int mode, final int maxSpeed) {
// Allocate handle
handle = spiNew();
if (handle == 0) {
throw new RuntimeException("Handle cannot be NULL");
}
// Open device
if (spiOpen(handle, path, mode, maxSpeed) != SPI_SUCCESS) {
// Free handle before throwing exception
spiFree(handle);
throw new RuntimeException(spiErrMessage(handle));
}
}
/**
* Open the spidev device at the specified path, with the specified SPI mode, max speed in hertz, bit order, bits per word, and
* extra flags.
*
* SPI mode can be 0, 1, 2, or 3. Bit order can be MSB_FIRST or LSB_FIRST, as defined above. Bits per word specifies the
* transfer word size. Extra flags specified additional flags bitwise-ORed with the SPI mode.
*
* @param path spidev path.
* @param mode Mode can be 0, 1, 2, or 3.
* @param maxSpeed Max speed in hertz.
* @param bitOrder Bit order can be MSB_FIRST or LSB_FIRST.
* @param bitsPerWord Transfer word size.
* @param extraFlags Additional flags bitwise-ORed with the SPI mode.
*/
public Spi(final String path, final int mode, final int maxSpeed, final int bitOrder, final byte bitsPerWord,
final byte extraFlags) {
// Allocate handle
handle = spiNew();
if (handle == 0) {
throw new RuntimeException("Handle cannot be NULL");
}
// Open device
if (spiOpenAdvanced(handle, path, mode, maxSpeed, bitOrder, bitsPerWord, extraFlags) != SPI_SUCCESS) {
// Free handle before throwing exception
spiFree(handle);
throw new RuntimeException(spiErrMessage(handle));
}
}
/**
* Close and free handle.
*/
@Override
public void close() {
spiClose(handle);
spiFree(handle);
}
/**
* Handle accessor.
*
* @return Handle.
*/
public long getHandle() {
return handle;
}
/**
* Allocate an SPI handle.
*
* @return A valid handle on success, or NULL on failure.
*/
@JniMethod(accessor = "spi_new")
public static final native long spiNew();
/**
* Open the spidev device at the specified path (e.g. "/dev/spidev1.0"), with the specified SPI mode, specified max speed in
* hertz, and the defaults of MSB_FIRST bit order, and 8 bits per word.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param path spidev path.
* @param mode Mode can be 0, 1, 2, or 3.
* @param maxSpeed Max speed in hertz.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_open")
public static native int spiOpen(long spi, String path, int mode, int maxSpeed);
/**
* Open the spidev device at the specified path, with the specified SPI mode, max speed in hertz, bit order, bits per word, and
* extra flags.
*
* spi should be a valid pointer to an allocated SPI handle structure. SPI mode can be 0, 1, 2, or 3. Bit order can be MSB_FIRST
* or LSB_FIRST, as defined above. Bits per word specifies the transfer word size. Extra flags specified additional flags
* bitwise-ORed with the SPI mode.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param path spidev path.
* @param mode Mode can be 0, 1, 2, or 3.
* @param maxSpeed Max speed in hertz.
* @param bitOrder Bit order can be MSB_FIRST or LSB_FIRST.
* @param bitsPerWord Transfer word size.
* @param extraFlags Additional flags bitwise-ORed with the SPI mode.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_open_advanced")
public static native int spiOpenAdvanced(long spi, String path, int mode, int maxSpeed, int bitOrder, byte bitsPerWord,
byte extraFlags);
/**
* Open the spidev device at the specified path, with the specified SPI mode, max speed in hertz, bit order, bits per word, and
* extra flags. This open function is the same as spi_open_advanced(), except that extra_flags can be 32-bits.
*
* spi should be a valid pointer to an allocated SPI handle structure. SPI mode can be 0, 1, 2, or 3. Bit order can be MSB_FIRST
* or LSB_FIRST, as defined above. Bits per word specifies the transfer word size. Extra flags specified additional flags
* bitwise-ORed with the SPI mode.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param path spidev path.
* @param mode Mode can be 0, 1, 2, or 3.
* @param maxSpeed Max speed in hertz.
* @param bitOrder Bit order can be MSB_FIRST or LSB_FIRST.
* @param bitsPerWord Transfer word size.
* @param extraFlags Additional flags bitwise-ORed with the SPI mode.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_open_advanced2")
public static native int spiOpenAdvanced2(long spi, String path, int mode, int maxSpeed, int bitOrder, byte bitsPerWord,
int extraFlags);
/**
* Shift out len word counts of the txbuf buffer, while shifting in len word counts to the rxbuf buffer.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param txBuf Transmit buffer.
* @param rxBuf Receive buffer.
* @param len Word count.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_transfer")
public static native int spiTransfer(long spi, byte[] txBuf, byte[] rxBuf, long len);
/**
* Close the spidev device.
*
* @param spi Valid pointer to an allocated SPI handle structure.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_close")
public static native int spiClose(long spi);
/**
* Free an SPI handle.
*
* @param spi Valid pointer to an allocated SPI handle structure.
*/
@JniMethod(accessor = "spi_free")
public static native void spiFree(long spi);
/**
* Get the mode.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param mode Mode can be 0, 1, 2, or 3.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_get_mode")
public static native int spiGetMode(long spi, int[] mode);
/**
* Get the max speed.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param maxSpeed Max speed in hertz.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_get_max_speed")
public static native int spiGetMaxSpeed(long spi, int[] maxSpeed);
/**
* Get the bit order.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param bit_order Bit order can be MSB_FIRST or LSB_FIRST.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_get_bit_order")
public static native int spiGetBitOrder(long spi, int[] bit_order);
/**
* Get the bits per word.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param bitsPerWord Transfer word size.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_get_bits_per_word")
public static native int spiGetBitsPerWord(long spi, byte[] bitsPerWord);
/**
* Get extra flags.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param extraFlags Additional flags bitwise-ORed with the SPI mode.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_get_extra_flags")
public static native int spiGetExtraFlags(long spi, byte[] extraFlags);
/**
* Get extra flags.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param extraFlags Additional flags bitwise-ORed with the SPI mode.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_get_extra_flags32")
public static native int spiGetExtraFlags32(long spi, int[] extraFlags);
/**
* Set the mode.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param mode Mode can be 0, 1, 2, or 3.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_set_mode")
public static native int spiSetMode(long spi, int mode);
/**
* Set the max speed.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param maxSpeed Max speed in hertz.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_set_max_speed")
public static native int spiSetMaxSpeed(long spi, int maxSpeed);
/**
* Set the bit order.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param bit_order Bit order can be MSB_FIRST or LSB_FIRST.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_set_bit_order")
public static native int spiSetBitOrder(long spi, int bit_order);
/**
* Set the bits per word.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param bitsPerWord Transfer word size.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_set_bits_per_word")
public static native int spiSetBitsPerWord(long spi, byte bitsPerWord);
/**
* Set extra flags.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param extraFlags Additional flags bitwise-ORed with the SPI mode.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_set_extra_flags")
public static native int spiSetExtraFlags(long spi, byte extraFlags);
/**
* Set extra flags.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @param extraFlags Additional flags bitwise-ORed with the SPI mode.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_set_extra_flags32")
public static native int spiSetExtraFlags32(long spi, int extraFlags);
/**
* Return the file descriptor (for the underlying spidev device) of the SPI handle.
*
* @param spi A valid pointer to an allocated SPI handle structure.
* @return File descriptor (for the underlying spidev device) of the SPI handle.
*/
@JniMethod(accessor = "spi_fd")
public static native int spiFd(long spi);
/**
* Return a string representation of the SPI handle.
*
* @param spi Valid pointer to an allocated SPI handle structure.
* @param str String representation of the SPI handle.
* @param len Length of char array.
* @return 0 on success, or a negative SPI error code on failure.
*/
@JniMethod(accessor = "spi_tostring")
public static native int spiToString(long spi, byte[] str, long len);
/**
* Return a string representation of the SPI handle. Wraps native method and simplifies.
*
* @param spi Valid pointer to an allocated SPI handle structure.
* @return SPI handle as String.
*/
public static String spiToString(long spi) {
var str = new byte[MAX_CHAR_ARRAY_LEN];
if (spiToString(spi, str, str.length) < 0) {
throw new RuntimeException(spiErrMessage(spi));
}
return jString(str);
}
/**
* Return the libc errno of the last failure that occurred.
*
* @param spi Valid pointer to an allocated SPI handle structure.
* @return libc errno.
*/
@JniMethod(accessor = "spi_errno")
public static native int spiErrNo(long spi);
/**
* Return a human readable error message pointer of the last failure that occurred.
*
* @param spi Valid pointer to an allocated SPI handle structure.
* @return Error message pointer.
*/
@JniMethod(accessor = "spi_errmsg")
public static native long spiErrMsg(long spi);
/**
* Return a human readable error message of the last failure that occurred. Converts const char * returned by spi_errmsg to a
* Java String.
*
* @param spi Valid pointer to an allocated SPI handle structure.
* @return Error message.
*/
public static String spiErrMessage(long spi) {
var ptr = spiErrMsg(spi);
var str = new byte[MAX_CHAR_ARRAY_LEN];
memMove(str, ptr, str.length);
return jString(str);
}
}