Guest User

Sample BBB Java code for GPIO/I2C

a guest
Dec 20th, 2013
354
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 56.46 KB | None | 0 0
  1. # This is a shell archive. Save it in a file, remove anything before
  2. # this line, and then unpack it by entering "sh file". Note, it may
  3. # create directories; files and directories will be owned by you and
  4. # have default permissions.
  5. #
  6. # This archive contains:
  7. #
  8. # BBGPIOFactory.java
  9. # GPIO.java
  10. # GPIOFactory.java
  11. # I2CBus.java
  12. # I2CDevice.java
  13. # POSIX.java
  14. #
  15. echo x - BBGPIOFactory.java
  16. sed 's/^X//' >BBGPIOFactory.java << 'END-of-BBGPIOFactory.java'
  17. Ximport java.util.*;
  18. Ximport java.io.*;
  19. X
  20. X/**
  21. X * GPIOFactory for BeagleBone Black with the GPIO device-tree overlays from
  22. X * https://github.com/nomel/beaglebone/tree/master/gpio-header. It is assumed
  23. X * the overlay for the required GPIO has been loaded if required - this factory
  24. X * won't do that.
  25. X */
  26. Xclass BBGPIOFactory extends GPIOFactory {
  27. X
  28. X private static String CAPEMGRFILE, DTODIR;
  29. X
  30. X private static final String[] gpionames = {
  31. X null, // 0
  32. X "P8.25", // 1
  33. X "P9.22", // 2
  34. X "P9.21", // 3
  35. X "P9.18", // 4
  36. X "P9.17", // 5
  37. X null, // 6
  38. X "P9.42", // 7
  39. X "P8.35", // 8
  40. X "P8.33", // 9
  41. X "P8.31", // 10
  42. X "P8.32", // 11
  43. X "P9.20", // 12
  44. X "P9.19", // 13
  45. X "P9.26", // 14
  46. X "P9.24", // 15
  47. X null, // 16
  48. X null, // 17
  49. X null, // 18
  50. X null, // 19
  51. X "P9.41", // 20
  52. X null, // 21
  53. X "P8.19", // 22
  54. X "P8.13", // 23
  55. X null, // 24
  56. X null, // 25
  57. X "P8.14", // 26
  58. X "P8.17", // 27
  59. X null, // 28
  60. X null, // 29
  61. X "P9.11", // 30
  62. X "P9.13", // 31
  63. X null, // 32
  64. X "P8.24", // 33
  65. X "P8.5", // 34
  66. X "P8.6", // 35
  67. X "P8.23", // 36
  68. X "P8.22", // 37
  69. X "P8.3", // 38
  70. X "P8.4", // 39
  71. X null, // 40
  72. X null, // 41
  73. X null, // 42
  74. X null, // 43
  75. X "P8.12", // 44
  76. X "P8.11", // 45
  77. X "P8.16", // 46
  78. X "P8.15", // 47
  79. X "P9.15", // 48
  80. X "P9.23", // 49
  81. X "P9.14", // 50
  82. X "P9.16", // 51
  83. X null, // 52
  84. X null, // 53
  85. X null, // 54
  86. X null, // 55
  87. X null, // 56
  88. X null, // 57
  89. X null, // 58
  90. X null, // 59
  91. X "P9.12", // 60
  92. X "P8.26", // 61
  93. X "P8.21", // 62
  94. X "P8.20", // 63
  95. X null, // 64
  96. X "P8.18", // 65
  97. X "P8.7", // 66
  98. X "P8.8", // 67
  99. X "P8.10", // 68
  100. X "P8.9", // 69
  101. X "P8.45", // 70
  102. X "P8.46", // 71
  103. X "P8.43", // 72
  104. X "P8.44", // 73
  105. X "P8.41", // 74
  106. X "P8.42", // 75
  107. X "P8.39", // 76
  108. X "P8.40", // 77
  109. X "P8.37", // 78
  110. X "P8.38", // 79
  111. X "P8.36", // 80
  112. X "P8.34", // 81
  113. X null, // 82
  114. X null, // 83
  115. X null, // 84
  116. X null, // 85
  117. X "P8.27", // 86
  118. X "P8.29", // 87
  119. X "P8.28", // 88
  120. X "P8.30", // 89
  121. X null, // 90
  122. X null, // 91
  123. X null, // 92
  124. X null, // 93
  125. X null, // 94
  126. X null, // 95
  127. X null, // 96
  128. X null, // 97
  129. X null, // 98
  130. X null, // 99
  131. X null, // 100
  132. X null, // 101
  133. X null, // 102
  134. X null, // 103
  135. X null, // 104
  136. X null, // 105
  137. X null, // 106
  138. X null, // 107
  139. X null, // 108
  140. X null, // 109
  141. X "P9.31", // 110
  142. X "P9.29", // 111
  143. X "P9.30", // 112
  144. X "P9.28", // 113
  145. X "P9.42b", // 114
  146. X "P9.27", // 115
  147. X "P9.41b", // 116
  148. X "P9.25", // 117
  149. X };
  150. X
  151. X synchronized static boolean canCreate() {
  152. X // Do we need to check more?
  153. X if (CAPEMGRFILE == null) {
  154. X File f = new File("/sys/devices");
  155. X File[] sf = f.listFiles();
  156. X for (int i=0;i<sf.length;i++) {
  157. X if (CAPEMGRFILE == null && sf[i].getName().startsWith("bone_capemgr.") && f.isDirectory()) {
  158. X CAPEMGRFILE = sf[i].getAbsolutePath() + "/slots";
  159. X } else if (sf[i].getName().startsWith("ocp.") && f.isDirectory()) {
  160. X DTODIR = sf[i].getAbsolutePath();
  161. X }
  162. X }
  163. X if (CAPEMGRFILE == null || DTODIR == null) {
  164. X return false;
  165. X }
  166. X }
  167. X return true;
  168. X }
  169. X
  170. X private static void writeToFile(String file, String data) throws IOException {
  171. X Writer out = new OutputStreamWriter(new FileOutputStream(file), "ISO-8859-1");
  172. X out.write(data);
  173. X out.close();
  174. X }
  175. X
  176. X public GPIO open(int gpio, GPIO.Mode mode) throws IOException {
  177. X if (gpio > gpionames.length || gpio < 0 || gpionames[gpio] == null) {
  178. X throw new IllegalArgumentException(Integer.toString(gpio));
  179. X }
  180. X File[] f = new File(DTODIR).listFiles();
  181. X String prefix = "gpio-"+gpionames[gpio]+"_gpio"+gpio;
  182. X boolean found = false;
  183. X for (int i=0;!found && i<f.length;i++) {
  184. X found = f[i].getName().startsWith(prefix);
  185. X }
  186. X if (!found) {
  187. X// String s = gpionames[gpio].replaceAll("\\.0", ".");
  188. X// System.out.println("## Writing \"gpio-"+gpionames[gpio]+"\" to "+CAPEMGRFILE);
  189. X writeToFile(CAPEMGRFILE, "gpio-"+gpionames[gpio]);
  190. X }
  191. X GPIO gpioobj = new GPIO(gpio, "gpio"+gpio+"@"+gpionames[gpio], this);
  192. X gpioobj.setMode(mode);
  193. X return gpioobj;
  194. X }
  195. X
  196. X public int getNumGPIOs() {
  197. X return gpionames.length;
  198. X }
  199. X
  200. X public void setPull(int gpio, boolean input, int pull) throws IOException {
  201. X String s = pull > 0 ? "rxEnable_pullUp" : pull < 0 ? "rxEnable_pullDown" : "rxEnable_pullNone";
  202. X File[] f = new File(DTODIR).listFiles();
  203. X String prefix = "gpio-"+gpionames[gpio]+"_gpio"+gpio;
  204. X for (int i=0;i<f.length;i++) {
  205. X if (f[i].getName().startsWith(prefix)) {
  206. X writeToFile(DTODIR + "/" + f[i].getName() + "/state", s);
  207. X return;
  208. X }
  209. X }
  210. X throw new IOException("No file \""+DTODIR+"/"+prefix+"*\"");
  211. X }
  212. X
  213. X}
  214. END-of-BBGPIOFactory.java
  215. echo x - GPIO.java
  216. sed 's/^X//' >GPIO.java << 'END-of-GPIO.java'
  217. Ximport java.util.*;
  218. Ximport java.io.*;
  219. X
  220. X/**
  221. X * The GPIO class represents a single GPIO pin on the hardware, which may be
  222. X * output or input, possibly with pullup or pulldown resistors.
  223. X * <pre class="example">
  224. X * GPIO gpio = GPIOFactory.getInstance().open(gpionum, GPIO.Mode.INPUT_PULLUP);
  225. X * </pre>
  226. X */
  227. Xpublic class GPIO {
  228. X
  229. X public static enum Mode {
  230. X OUTPUT_LOW, OUTPUT_HIGH, INPUT_NONE, INPUT_PULLUP, INPUT_PULLDOWN
  231. X };
  232. X
  233. X // Everything in this class should be standard to all reasonably modern Linux
  234. X // distributions on any hardware. Variations in the hardware are managed by
  235. X // different GPIOFactory implementations
  236. X
  237. X private static final String GPIODIR = "/sys/class/gpio";
  238. X private static GPIO[] all;
  239. X private static PollThread pollthread;
  240. X private static final List<GPIO> pollfdlist = new ArrayList<GPIO>();
  241. X
  242. X private final int gpio, fd;
  243. X private String name;
  244. X private final GPIOFactory factory;
  245. X private boolean output, value, poll;
  246. X
  247. X static {
  248. X pollthread = new PollThread();
  249. X pollthread.start();
  250. X }
  251. X
  252. X private static void writeToFile(String file, String data) throws IOException {
  253. X Writer out = new OutputStreamWriter(new FileOutputStream(file), "ISO-8859-1");
  254. X out.write(data);
  255. X out.close();
  256. X }
  257. X
  258. X /**
  259. X * Open a new GPIO. The GPIO must not be opened elsewhere. Called by factory
  260. X * @param gpio the GPIO number
  261. X * @param name the user-friendly name
  262. X * @param factory the factory creating the GPIO
  263. X */
  264. X public GPIO(int gpio, String name, GPIOFactory factory) throws IOException {
  265. X synchronized(GPIO.class) {
  266. X if (all == null) {
  267. X all = new GPIO[factory.getNumGPIOs()];
  268. X }
  269. X if (all[gpio] != null) {
  270. X throw new IllegalArgumentException("GPIO "+gpio+" already open");
  271. X }
  272. X all[gpio] = this;
  273. X }
  274. X String valfile = GPIODIR + "/gpio" + gpio + "/value";
  275. X if (!new File(valfile).exists()) {
  276. X writeToFile(GPIODIR+"/export", Integer.toString(gpio));
  277. X }
  278. X this.gpio = gpio;
  279. X this.fd = POSIX.open(valfile, POSIX.O_RDWR | POSIX.O_NONBLOCK);
  280. X if (fd < 0) {
  281. X throw new IOException("Couldn't open \""+valfile+"\": "+POSIX.errmsg());
  282. X }
  283. X this.factory = factory;
  284. X this.name = name;
  285. X }
  286. X
  287. X /**
  288. X * Close the GPIO and release it to be opened elsewhere
  289. X */
  290. X public void close() {
  291. X setPolling(false);
  292. X POSIX.close(fd);
  293. X synchronized(GPIO.class) {
  294. X all[gpio] = null;
  295. X }
  296. X }
  297. X
  298. X public int hashCode() {
  299. X return gpio;
  300. X }
  301. X
  302. X public boolean equals(Object o) {
  303. X return o == this;
  304. X }
  305. X
  306. X void setEdge(boolean rising, boolean falling) throws IOException {
  307. X String s = rising ? falling ? "both" : "rising" : falling ? "falling" : "none";
  308. X writeToFile(GPIODIR + "/gpio" + gpio + "/edge", s);
  309. X }
  310. X
  311. X public boolean isOutput() {
  312. X return output;
  313. X }
  314. X
  315. X /**
  316. X * Set the Mode of the GPIO.
  317. X */
  318. X public void setMode(Mode mode) throws IOException {
  319. X this.output = mode == Mode.OUTPUT_LOW || mode == Mode.OUTPUT_HIGH;
  320. X writeToFile(GPIODIR + "/gpio" + gpio + "/direction", output ? "out": "in");
  321. X if (!output) {
  322. X factory.setPull(gpio, !output, mode == Mode.INPUT_PULLUP ? 1 : mode == Mode.INPUT_PULLDOWN ? -1 : 0);
  323. X if (POSIX.lseek(fd, 0, POSIX.SEEK_SET) < 0) {
  324. X throw new IOException("Can't seek: "+POSIX.errmsg());
  325. X }
  326. X } else {
  327. X set(mode == Mode.OUTPUT_HIGH);
  328. X }
  329. X }
  330. X
  331. X /**
  332. X * For output GPIOs, set the output value to on or off. Illegal for input GPIOs
  333. X */
  334. X public void set(boolean on) {
  335. X if (output) {
  336. X byte[] b = new byte[] { on ? (byte)'1' : (byte)'0' };
  337. X POSIX.write(fd, b, 1);
  338. X if (value != on) {
  339. X value = on;
  340. X // TODO Fire an event here notifiying listeners the GPIO has changed
  341. X// Marshall.pubGPIO(value, this);
  342. X }
  343. X } else {
  344. X throw new IllegalStateException("input");
  345. X }
  346. X }
  347. X
  348. X private boolean doget() throws IOException {
  349. X byte[] b = new byte[1];
  350. X if (POSIX.pread(fd, b, 1, 0) < 0) { // pread so we don't need to lseek between reads!
  351. X throw new IOException("Can't read: "+POSIX.errmsg());
  352. X }
  353. X return value = b[0] == '1' ? true : false;
  354. X }
  355. X
  356. X /**
  357. X * Get the value of the GPIO. For Output GPIOs, this is the last value set.
  358. X * For input GPIOs with no listener attached, this reads the pin immediately.
  359. X * For input GPIos with listners attached, the value is kept updated by the
  360. X * listener
  361. X */
  362. X public boolean get() {
  363. X if (!output && !poll) {
  364. X try {
  365. X doget();
  366. X } catch (IOException e) {
  367. X throw new RuntimeException(e);
  368. X }
  369. X }
  370. X return value;
  371. X }
  372. X
  373. X public synchronized void setPolling(boolean poll) {
  374. X if (poll == this.poll) {
  375. X return;
  376. X }
  377. X if (poll) {
  378. X try {
  379. X setEdge(true, true);
  380. X } catch (IOException e) {
  381. X throw new RuntimeException(e);
  382. X }
  383. X synchronized(pollfdlist) {
  384. X pollfdlist.add(this);
  385. X pollfdlist.notifyAll();
  386. X }
  387. X } else {
  388. X synchronized(pollfdlist) {
  389. X pollfdlist.remove(this);
  390. X pollfdlist.notifyAll();
  391. X }
  392. X try {
  393. X setEdge(false, false);
  394. X } catch (IOException e) {
  395. X throw new RuntimeException(e);
  396. X }
  397. X }
  398. X this.poll = poll;
  399. X }
  400. X
  401. X /**
  402. X * Return the GPIO number of this GPIO
  403. X */
  404. X public int getGPIO() {
  405. X return gpio;
  406. X }
  407. X
  408. X /**
  409. X * Return the user-friendly name of this GPIO
  410. X */
  411. X public String getName() {
  412. X return name;
  413. X }
  414. X
  415. X /**
  416. X * Set the user-friendly name of this GPIO
  417. X */
  418. X public void setName(String name) {
  419. X this.name = name;
  420. X }
  421. X
  422. X private static class PollThread extends Thread {
  423. X
  424. X public PollThread() {
  425. X super("GPIOPoller");
  426. X setDaemon(true);
  427. X }
  428. X
  429. X public void run() {
  430. X final int polltimeout = 1000;
  431. X POSIX.Pollfd[] pollfd = null;
  432. X GPIO[] gpiolist = null;
  433. X int num;
  434. X while (pollthread != null) {
  435. X synchronized(pollfdlist) {
  436. X if (pollfdlist.isEmpty()) {
  437. X try {
  438. X pollfdlist.wait();
  439. X } catch (InterruptedException e) {}
  440. X }
  441. X gpiolist = pollfdlist.toArray(new GPIO[pollfdlist.size()]);
  442. X }
  443. X num = gpiolist.length;
  444. X if (pollfd == null || pollfd.length < num) {
  445. X pollfd = new POSIX.Pollfd[num];
  446. X for (int i=0;i<num;i++) {
  447. X pollfd[i] = new POSIX.Pollfd();
  448. X }
  449. X }
  450. X for (int i=0;i<num;i++) {
  451. X pollfd[i].init(gpiolist[i].fd, POSIX.POLLPRI);
  452. X }
  453. X if (num > 0) {
  454. X int ret = POSIX.poll(pollfd, num, polltimeout);
  455. X// System.out.println("> Poll gave "+ret+"/"+num);
  456. X if (ret > 0) {
  457. X int minpin = -1, maxpin = 0;
  458. X long c1 = 0, c2 = 0;
  459. X for (int i=0;i < num && ret > 0;i++) {
  460. X if (pollfd[i].isPri()) {
  461. X if (minpin < 0) {
  462. X minpin = i;
  463. X }
  464. X maxpin = i;
  465. X GPIO gpio = gpiolist[i];
  466. X boolean old = gpio.value;
  467. X try {
  468. X gpio.doget();
  469. X } catch (IOException e) {
  470. X e.printStackTrace();
  471. X }
  472. X if (old != gpio.value) {
  473. X if (i < 64) {
  474. X c1 |= (1<<i);
  475. X } else {
  476. X c2 |= (1<<(i-64));
  477. X }
  478. X }
  479. X ret--;
  480. X }
  481. X }
  482. X for (int i=minpin;i<=maxpin;i++) {
  483. X if ((i < 64 && (c1&(1<<i)) != 0) || (i >= 64 && (c2&(1<<(i-64))) != 0)) {
  484. X GPIO gpio = gpiolist[i];
  485. X boolean value = gpio.value;
  486. X // TODO Fire an event here notifiying listeners the GPIO has changed
  487. X// Marshall.pubGPIO(value, gpio);
  488. X }
  489. X }
  490. X } else if (ret < 0) {
  491. X// Marshall.pubMessage(new IOException("Poll failed: "+POSIX.errmsg()), this);
  492. X new IOException("Poll failed: "+POSIX.errmsg()).printStackTrace();
  493. X }
  494. X }
  495. X }
  496. X }
  497. X }
  498. X
  499. X public String toString() {
  500. X return name;
  501. X }
  502. X
  503. X}
  504. END-of-GPIO.java
  505. echo x - GPIOFactory.java
  506. sed 's/^X//' >GPIOFactory.java << 'END-of-GPIOFactory.java'
  507. Ximport java.io.*;
  508. X
  509. X/**
  510. X * A GPIOFactory creates GPIO objects which are suitable for the current
  511. X * hardware.
  512. X */
  513. Xpublic abstract class GPIOFactory {
  514. X
  515. X private static GPIOFactory instance;
  516. X
  517. X /**
  518. X * Get a GPIOFactory for the current hardware (best guess)
  519. X */
  520. X public synchronized static GPIOFactory getInstance() {
  521. X if (instance == null) {
  522. X if (BBGPIOFactory.canCreate()) {
  523. X instance = new BBGPIOFactory();
  524. X }
  525. X if (instance == null) {
  526. X throw new IllegalStateException("No usable factory found");
  527. X }
  528. X }
  529. X return instance;
  530. X }
  531. X
  532. X /**
  533. X * Open a new GPIO
  534. X * @param gpio the gpio number, as found in /sys/class/gpio
  535. X * @param mode the {@link GPIO.Mode mode} to open the GPIO in - input or output
  536. X */
  537. X public abstract GPIO open(int gpio, GPIO.Mode mode) throws IOException;
  538. X
  539. X /**
  540. X * Set the pullup or pulldown resistors if available. If the required state
  541. X * is not available an IOException is thrown
  542. X * @param gpio the gpio
  543. X * @param input whether the pin is in input mode or not
  544. X * @param pull A value > 0 for pullup, < 0 for pull down or 0 for no pull
  545. X */
  546. X public abstract void setPull(int gpio, boolean input, int pull) throws IOException;
  547. X
  548. X /**
  549. X * Get the number of GPIOs available from this factory (0 < gpio < num);
  550. X */
  551. X public abstract int getNumGPIOs();
  552. X
  553. X}
  554. END-of-GPIOFactory.java
  555. echo x - I2CBus.java
  556. sed 's/^X//' >I2CBus.java << 'END-of-I2CBus.java'
  557. Ximport java.io.*;
  558. Ximport java.nio.*;
  559. Ximport java.util.*;
  560. X
  561. X/**
  562. X * An I2C bus represents the file "/dev/i2c-nnn", where nnn is the bus number.
  563. X * All I/O to that file goes through this class, and many {@link I2CDevice} devices
  564. X * may be used on the bus. All I/O methods on this class are synchronized, which means
  565. X * for the purposes of the API they are atomic. If a non-atomic exchange of data is required
  566. X * by the I2C device, it should synchronize on this class while doing so.
  567. X * </p><p>
  568. X * Operations may also be queued on the timer returned from {@link #getTime} by calling
  569. X * {@link #queue}.
  570. X * </p>
  571. X *
  572. X * <pre class="example">
  573. X * I2CBus bus = I2CBus.openBus(1);
  574. X * I2CDevice device = new I2CDevice(0x34, bus);
  575. X * int val = device.smReadByte(register)
  576. X * bus.close();
  577. X * </pre>
  578. X */
  579. Xpublic class I2CBus {
  580. X
  581. X private static final int NUMBUSSES = 4;
  582. X private static final I2CBus[] bus = new I2CBus[NUMBUSSES];
  583. X
  584. X private final String name;
  585. X private final int num, fd;
  586. X private Timer timer;
  587. X private int address;
  588. X
  589. X /**
  590. X * Open the specified I2C bus
  591. X * @param num the bus number
  592. X */
  593. X public static synchronized I2CBus openBus(int num) throws IOException {
  594. X if (num < 0 || num >= NUMBUSSES) {
  595. X throw new IllegalArgumentException(Integer.toString(num));
  596. X }
  597. X if (bus[num] == null) {
  598. X bus[num] = new I2CBus(num);
  599. X }
  600. X return bus[num];
  601. X }
  602. X
  603. X private I2CBus(int num) throws IOException {
  604. X this.num = num;
  605. X this.name = "/dev/i2c-"+num;
  606. X if ((this.fd = POSIX.open(name, POSIX.O_RDWR)) < 0) {
  607. X throw new IOException("Can't open "+name+": "+POSIX.errmsg());
  608. X }
  609. X }
  610. X
  611. X /**
  612. X * Close this I2C bus
  613. X */
  614. X public synchronized void close() {
  615. X POSIX.close(fd);
  616. X if (timer != null) {
  617. X timer.cancel();
  618. X }
  619. X synchronized(I2CBus.class) {
  620. X bus[num] = null;
  621. X }
  622. X }
  623. X
  624. X public String toString() {
  625. X return name;
  626. X }
  627. X
  628. X private void set(int address) throws IOException {
  629. X if (this.address != address) {
  630. X if (POSIX.ioctl(fd, POSIX.I2C_SLAVE, address) < 0) {
  631. X throw new IOException("Can't set address 0x"+Integer.toHexString(address)+" on "+this);
  632. X }
  633. X this.address = address;
  634. X }
  635. X }
  636. X
  637. X /**
  638. X * Read data for the specified bus
  639. X * @param address the device address
  640. X * @param buf the array to read into
  641. X * @param len the number of bytes to read
  642. X */
  643. X public synchronized void read(int address, byte[] buf, int off, int len) throws IOException {
  644. X set(address);
  645. X if (off == 0) {
  646. X if (POSIX.read(fd, buf, len) != len) {
  647. X throw new IOException("Read failed for "+this);
  648. X }
  649. X } else {
  650. X ByteBuffer b = ByteBuffer.wrap(buf);
  651. X b.position(off);
  652. X if (POSIX.read(fd, b, len) != len) {
  653. X throw new IOException("Read failed for "+this);
  654. X }
  655. X }
  656. X }
  657. X
  658. X /**
  659. X * Write data to the specified bus
  660. X * @param address the device address
  661. X * @param wbuf the array to write from
  662. X * @param wlen the number of bytes to write
  663. X */
  664. X public synchronized void write(int address, byte[] buf, int off, int len) throws IOException {
  665. X set(address);
  666. X if (off == 0) {
  667. X if (POSIX.write(fd, buf, len) != len) {
  668. X throw new IOException("Write failed for "+this);
  669. X }
  670. X } else {
  671. X ByteBuffer b = ByteBuffer.wrap(buf);
  672. X b.position(off);
  673. X if (POSIX.write(fd, b, len) != len) {
  674. X throw new IOException("Write failed for "+this);
  675. X }
  676. X }
  677. X }
  678. X
  679. X /**
  680. X * Write data to the specified bus, then read some back
  681. X * @param address the device address
  682. X * @param wbuf the array to write from
  683. X * @param woff the offset into the wbuf array
  684. X * @param wlen the number of bytes to write
  685. X * @param rbuf the array to read into
  686. X * @param roff the offset into the rbuf array
  687. X * @param rlen the number of bytes to read
  688. X */
  689. X public synchronized void writeread(int address, byte[] wbuf, int woff, int wlen, byte[] rbuf, int roff, int rlen) throws IOException {
  690. X set(address);
  691. X if (woff == 0) {
  692. X if (POSIX.write(fd, wbuf, wlen) != wlen) {
  693. X throw new IOException("Write failed for "+this);
  694. X }
  695. X } else {
  696. X ByteBuffer b = ByteBuffer.wrap(wbuf);
  697. X b.position(woff);
  698. X if (POSIX.write(fd, b, wlen) != wlen) {
  699. X throw new IOException("Write failed for "+this);
  700. X }
  701. X }
  702. X if (roff == 0) {
  703. X if (POSIX.read(fd, rbuf, rlen) != rlen) {
  704. X throw new IOException("Read failed for "+this);
  705. X }
  706. X } else {
  707. X ByteBuffer b = ByteBuffer.wrap(rbuf);
  708. X b.position(roff);
  709. X if (POSIX.read(fd, b, rlen) != rlen) {
  710. X throw new IOException("Read failed for "+this);
  711. X }
  712. X }
  713. X }
  714. X
  715. X public synchronized void writeread(int address, ByteBuffer wbuf, ByteBuffer rbuf) throws IOException {
  716. X set(address);
  717. X if (POSIX.write(fd, wbuf, wbuf.remaining()) < 0) {
  718. X throw new IOException("Write failed for "+this);
  719. X }
  720. X if (POSIX.read(fd, rbuf, rbuf.remaining()) < 0) {
  721. X throw new IOException("Read failed for "+this);
  722. X }
  723. X }
  724. X
  725. X /**
  726. X * Queue a task (a read or write, normally) in the specified number of ms
  727. X * @param r the task to run
  728. X * @param ms the number of ms to delay before running it
  729. X */
  730. X public void queue(final Runnable r, int ms) {
  731. X Timer timer = getTimer();
  732. X synchronized(timer) {
  733. X timer.schedule(new TimerTask() {
  734. X public void run() {
  735. X r.run();
  736. X }
  737. X }, ms);
  738. X }
  739. X }
  740. X
  741. X /**
  742. X * Get a timer that can be used to queue tasks on this bus
  743. X */
  744. X public synchronized Timer getTimer() {
  745. X if (timer == null) {
  746. X timer = new Timer(true);
  747. X }
  748. X return timer;
  749. X }
  750. X
  751. X}
  752. END-of-I2CBus.java
  753. echo x - I2CDevice.java
  754. sed 's/^X//' >I2CDevice.java << 'END-of-I2CDevice.java'
  755. Ximport java.io.*;
  756. Ximport java.util.*;
  757. X
  758. X/**
  759. X * An I2CDevice is an address on an I2CBus. This class can be used
  760. X * as a base for more complex devices.
  761. X */
  762. Xpublic class I2CDevice {
  763. X
  764. X private I2CBus bus;
  765. X private int address;
  766. X private static byte[] buf = new byte[4];
  767. X private TimerTask polltask;
  768. X
  769. X /**
  770. X * Create a new I2CDevice
  771. X */
  772. X public I2CDevice() {
  773. X }
  774. X
  775. X /**
  776. X * Set the I2C bus and address
  777. X * @param address the 7-bit device address
  778. X * @param bus the bus the device is on.
  779. X */
  780. X public void setAddress(int address, I2CBus bus) {
  781. X if (address < 0 || address > 0x7F || bus == null) {
  782. X throw new IllegalArgumentException("Invalid address or bus");
  783. X }
  784. X this.address = address;
  785. X this.bus = bus;
  786. X }
  787. X
  788. X /**
  789. X * Get the bus this device was created on
  790. X */
  791. X public I2CBus getBus() {
  792. X return bus;
  793. X }
  794. X
  795. X /**
  796. X * Get the bus address
  797. X */
  798. X public int getAddress() {
  799. X return address;
  800. X }
  801. X
  802. X public String toString() {
  803. X return bus+"@0x"+Integer.toHexString(address);
  804. X }
  805. X
  806. X public int read() throws IOException {
  807. X bus.read(address, buf, 0, 1);
  808. X return buf[0] & 0xFF;
  809. X }
  810. X
  811. X public void read(byte[] buf) throws IOException {
  812. X bus.read(address, buf, 0, buf.length);
  813. X }
  814. X
  815. X public void read(byte[] buf, int off, int len) throws IOException {
  816. X bus.read(address, buf, off, len);
  817. X }
  818. X
  819. X public void write(int b) throws IOException {
  820. X buf[0] = (byte)b;
  821. X bus.write(address, buf, 0, 1);
  822. X }
  823. X
  824. X public void write(byte[] b) throws IOException {
  825. X bus.write(address, b, 0, b.length);
  826. X }
  827. X
  828. X public void write(byte[] b, int off, int len) throws IOException {
  829. X bus.write(address, b, off, len);
  830. X }
  831. X
  832. X /**
  833. X * Read a byte from the specified register of a System Management bus device
  834. X */
  835. X public int smReadByte(int register) throws IOException {
  836. X buf[0] = (byte)register;
  837. X bus.writeread(address, buf, 0, 1, buf, 0, 1);
  838. X return buf[0]&0xFF;
  839. X }
  840. X
  841. X /**
  842. X * Read a 16-bit word from the specified register of a System Management bus device
  843. X */
  844. X public int smReadWord(int register) throws IOException {
  845. X buf[0] = (byte)register;
  846. X bus.writeread(address, buf, 0, 1, buf, 0, 2);
  847. X return ((buf[0]&0xFF)<<8) | (buf[1]&0xFF);
  848. X }
  849. X
  850. X /**
  851. X * Write a byte to the specified register of a System Management bus device
  852. X */
  853. X public void smWriteByte(int register, int data) throws IOException {
  854. X buf[0] = (byte)register;
  855. X buf[1] = (byte)data;
  856. X bus.write(address, buf, 0, 2);
  857. X }
  858. X
  859. X /**
  860. X * Write a 16-bit word to the specified register of a System Management bus device
  861. X */
  862. X public void smWriteWord(int register, int data) throws IOException {
  863. X buf[0] = (byte)register;
  864. X buf[1] = (byte)((data>>8)&0xFF);
  865. X buf[2] = (byte)(data&0xFF);
  866. X bus.write(address, buf, 0, 3);
  867. X }
  868. X
  869. X public void poll() throws IOException {
  870. X throw new UnsupportedOperationException();
  871. X }
  872. X
  873. X public void autopoll(int ms) {
  874. X if (ms == 0 && polltask != null) {
  875. X polltask.cancel();
  876. X polltask = null;
  877. X } else if (ms > 0) {
  878. X if (polltask == null) {
  879. X polltask = new TimerTask() {
  880. X public void run() {
  881. X try {
  882. X poll();
  883. X } catch (Exception e) {
  884. X e.printStackTrace();
  885. X autopoll(0);
  886. X }
  887. X }
  888. X };
  889. X }
  890. X getBus().getTimer().schedule(polltask, 0, ms);
  891. X }
  892. X }
  893. X
  894. X
  895. X}
  896. END-of-I2CDevice.java
  897. echo x - POSIX.java
  898. sed 's/^X//' >POSIX.java << 'END-of-POSIX.java'
  899. Ximport com.sun.jna.*;
  900. Ximport java.util.*;
  901. Ximport java.io.*;
  902. Ximport java.nio.*;
  903. X
  904. X/**
  905. X * A JNA-based wrapped around the various C libraries under Linux.
  906. X * Much of this was lifted from the "JTermios" classes of the purejavacomm
  907. X * API at https://github.com/nyholku/purejavacomm
  908. X */
  909. Xpublic class POSIX {
  910. X
  911. X private static final boolean IS64B = NativeLong.SIZE == 8;
  912. X
  913. X // sys/fileio.h stuff
  914. X public static final int FIONREAD = 0x541B;
  915. X // bits/fcntl-linux.h
  916. X public static final int O_RDONLY = 0x00000000;
  917. X public static final int O_WRONLY = 0x00000001;
  918. X public static final int O_RDWR = 0x00000002;
  919. X public static final int O_CREAT = 0x00000040;
  920. X public static final int O_EXCL = 0x00000080;
  921. X public static final int O_NOCTTY = 0x00000100;
  922. X public static final int O_TRUNC = 0x00000200;
  923. X public static final int O_APPEND = 0x00000400;
  924. X public static final int O_NONBLOCK = 0x00000800;
  925. X public static final int O_NDELAY = O_NONBLOCK;
  926. X public static final int O_SYNC = 0x00101000;
  927. X public static final int O_DIRECT = 0x00004000;
  928. X public static final int O_LARGEFILE = 0x00008000;
  929. X public static final int O_DIRECTORY = 0x00010000;
  930. X public static final int O_NOFOLLOW = 0x00020000;
  931. X public static final int O_NOATIME = 0x00040000;
  932. X public static final int O_CLOEXEC = 0x00080000;
  933. X public static final int F_GETFL = 0x00000003;
  934. X public static final int F_SETFL = 0x00000004;
  935. X
  936. X // errno.h stuff
  937. X public static final int EACCES = 11;
  938. X public static final int EAGAIN = 13;
  939. X public static final int EBADF = 9;
  940. X public static final int EBUSY = 16;
  941. X public static final int EEXIST = 17;
  942. X public static final int EINTR = 4;
  943. X public static final int EINVAL = 22;
  944. X public static final int EIO = 5;
  945. X public static final int EISDIR = 21;
  946. X public static final int ELOOP = 40;
  947. X public static final int EMFILE = 24;
  948. X public static final int ENAMETOOLONG = 36;
  949. X public static final int ENFILE = 23;
  950. X public static final int ENOENT = 2;
  951. X public static final int ENOSR = 63;
  952. X public static final int ENOSPC = 28;
  953. X public static final int ENOTDIR = 20;
  954. X public static final int ENXIO = 6;
  955. X public static final int EOVERFLOW = 75;
  956. X public static final int EROFS = 30;
  957. X public static final int ENOTSUP = 95;
  958. X // seek
  959. X public static final int SEEK_SET = 0;
  960. X public static final int SEEK_CUR = 1;
  961. X public static final int SEEK_END = 2;
  962. X // linux/i2c-dev.h
  963. X public static final int I2C_RETRIES = 0x0701;
  964. X public static final int I2C_TIMEOUT = 0x0702;
  965. X public static final int I2C_SLAVE = 0x0703;
  966. X public static final int I2C_SLAVE_FORCE = 0x0706;
  967. X public static final int I2C_FUNCS = 0x0705;
  968. X public static final int I2C_RDWR = 0x0707;
  969. X public static final int I2C_PEC = 0x0708;
  970. X public static final int I2C_SMBUS = 0x0720;
  971. X // termios.h stuff
  972. X public static final int TIOCM_RNG = 0x00000080;
  973. X public static final int TIOCM_CAR = 0x00000040;
  974. X public static final int IGNBRK = 0x00000001;
  975. X public static final int BRKINT = 0x00000002;
  976. X public static final int IGNPAR = 0x00000004;
  977. X public static final int PARMRK = 0x00000008;
  978. X public static final int INLCR = 0x00000040;
  979. X public static final int IGNCR = 0x00000080;
  980. X public static final int ICRNL = 0x00000100;
  981. X public static final int ECHONL = 0x00000040;
  982. X public static final int IEXTEN = 0x00008000;
  983. X public static final int CLOCAL = 0x00000800;
  984. X public static final int OPOST = 0x00000001;
  985. X public static final int VSTART = 0x00000008;
  986. X public static final int TCSANOW = 0x00000000;
  987. X public static final int VSTOP = 0x00000009;
  988. X public static final int VMIN = 0x00000006;
  989. X public static final int VTIME = 0x00000005;
  990. X public static final int VEOF = 0x00000004;
  991. X public static final int TIOCMGET = 0x00005415;
  992. X public static final int TIOCM_CTS = 0x00000020;
  993. X public static final int TIOCM_DSR = 0x00000100;
  994. X public static final int TIOCM_RI = 0x00000080;
  995. X public static final int TIOCM_CD = 0x00000040;
  996. X public static final int TIOCM_DTR = 0x00000002;
  997. X public static final int TIOCM_RTS = 0x00000004;
  998. X public static final int ICANON = 0x00000002;
  999. X public static final int ECHO = 0x00000008;
  1000. X public static final int ECHOE = 0x00000010;
  1001. X public static final int ISIG = 0x00000001;
  1002. X public static final int TIOCMSET = 0x00005418;
  1003. X public static final int IXON = 0x00000400;
  1004. X public static final int IXOFF = 0x00001000;
  1005. X public static final int IXANY = 0x00000800;
  1006. X public static final int CRTSCTS = 0x80000000;
  1007. X public static final int TCSADRAIN = 0x00000001;
  1008. X public static final int INPCK = 0x00000010;
  1009. X public static final int ISTRIP = 0x00000020;
  1010. X public static final int CSIZE = 0x00000030;
  1011. X public static final int TCIFLUSH = 0x00000000;
  1012. X public static final int TCOFLUSH = 0x00000001;
  1013. X public static final int TCIOFLUSH = 0x00000002;
  1014. X public static final int CS5 = 0x00000000;
  1015. X public static final int CS6 = 0x00000010;
  1016. X public static final int CS7 = 0x00000020;
  1017. X public static final int CS8 = 0x00000030;
  1018. X public static final int CSTOPB = 0x00000040;
  1019. X public static final int CREAD = 0x00000080;
  1020. X public static final int PARENB = 0x00000100;
  1021. X public static final int PARODD = 0x00000200;
  1022. X public static final int CMSPAR = 0x40000000;
  1023. X public static final int B0 = 0;
  1024. X public static final int B50 = 1;
  1025. X public static final int B75 = 2;
  1026. X public static final int B110 = 3;
  1027. X public static final int B134 = 4;
  1028. X public static final int B150 = 5;
  1029. X public static final int B200 = 6;
  1030. X public static final int B300 = 7;
  1031. X public static final int B600 = 8;
  1032. X public static final int B1200 = 9;
  1033. X public static final int B1800 = 10;
  1034. X public static final int B2400 = 11;
  1035. X public static final int B4800 = 12;
  1036. X public static final int B9600 = 13;
  1037. X public static final int B19200 = 14;
  1038. X public static final int B38400 = 15;
  1039. X public static final int B57600 = 4097;
  1040. X public static final int B115200 = 4098;
  1041. X public static final int B230400 = 4099;
  1042. X // bits/poll.h. See also Pollfd class
  1043. X public static final short POLLIN = 0x01;
  1044. X public static final short POLLPRI = 0x02;
  1045. X public static final short POLLOUT = 0x04;
  1046. X // spi.h stuff
  1047. X private static final int SPI_IOC_MAGIC = 'k';
  1048. X public static final int SPI_IOC_RD_MODE = ioc(true, SPI_IOC_MAGIC, 1, 1);
  1049. X public static final int SPI_IOC_WR_MODE = ioc(false, SPI_IOC_MAGIC, 1, 1);
  1050. X public static final int SPI_IOC_RD_LSB_FIRST = ioc(true, SPI_IOC_MAGIC, 2, 1);
  1051. X public static final int SPI_IOC_WR_LSB_FIRST = ioc(false, SPI_IOC_MAGIC, 2, 1);
  1052. X public static final int SPI_IOC_RD_BITS_PER_WORD = ioc(true, SPI_IOC_MAGIC, 3, 1);
  1053. X public static final int SPI_IOC_WR_BITS_PER_WORD = ioc(false, SPI_IOC_MAGIC, 3, 1);
  1054. X public static final int SPI_IOC_RD_MAX_SPEED_HZ = ioc(true, SPI_IOC_MAGIC, 4, 4);
  1055. X public static final int SPI_IOC_WR_MAX_SPEED_HZ = ioc(false, SPI_IOC_MAGIC, 4, 4);
  1056. X // misc stuff
  1057. X public static final int DC1 = 0x11; // Ctrl-Q;
  1058. X public static final int DC3 = 0x13; // Ctrl-S;
  1059. X
  1060. X private static final FastLibrary libcfast = new FastLibrary();
  1061. X private static final SlowLibrary libcslow = (SlowLibrary)Native.loadLibrary("c", SlowLibrary.class);
  1062. X
  1063. X //----------------------------------------------------------------------------
  1064. X
  1065. X private static int ioc(boolean read, int type, int nr, int size) {
  1066. X final int dirbits = 2;
  1067. X final int sizebits = 14;
  1068. X final int nrbits = 8;
  1069. X final int typebits = 8;
  1070. X if (size >= 1<<sizebits) {
  1071. X throw new IllegalArgumentException("SPI message too long");
  1072. X }
  1073. X return ((read ? 2 : 1)<<(sizebits + nrbits + typebits)) | (size<<(typebits + nrbits)) | (type<<nrbits) | nr;
  1074. X }
  1075. X
  1076. X public static void printf(String format, Object... args) {
  1077. X libcslow.printf(format, args);
  1078. X }
  1079. X
  1080. X public static void puts(ByteBuffer buf) {
  1081. X libcfast.puts(buf);
  1082. X }
  1083. X
  1084. X public static int errno() {
  1085. X return Native.getLastError();
  1086. X }
  1087. X
  1088. X public static String errmsg() {
  1089. X return strerror(errno());
  1090. X }
  1091. X
  1092. X public static String strerror(int num) {
  1093. X return libcfast.strerror(num);
  1094. X }
  1095. X
  1096. X public static void cfmakeraw(Termios termios) {
  1097. X termios_struct t = new termios_struct(termios);
  1098. X libcfast.cfmakeraw(t);
  1099. X t.update(termios);
  1100. X }
  1101. X
  1102. X public static int fcntl(int fd, int cmd, int arg) {
  1103. X return libcfast.fcntl(fd, cmd, arg);
  1104. X }
  1105. X
  1106. X public static int tcdrain(int fd) {
  1107. X return libcfast.tcdrain(fd);
  1108. X }
  1109. X
  1110. X public static int speedToBaud(int speed) {
  1111. X switch(speed) {
  1112. X case B0: return 0;
  1113. X case B50: return 50;
  1114. X case B75: return 75;
  1115. X case B110: return 110;
  1116. X case B134: return 134;
  1117. X case B150: return 150;
  1118. X case B200: return 200;
  1119. X case B300: return 300;
  1120. X case B600: return 600;
  1121. X case B1200: return 1200;
  1122. X case B1800: return 1800;
  1123. X case B2400: return 2400;
  1124. X case B4800: return 4800;
  1125. X case B9600: return 9600;
  1126. X case B19200: return 19200;
  1127. X case B38400: return 38400;
  1128. X case B57600: return 57600;
  1129. X case B115200: return 115200;
  1130. X case B230400: return 230400;
  1131. X default: return -1;
  1132. X }
  1133. X }
  1134. X
  1135. X public static int baudToSpeed(int baud) {
  1136. X switch(baud) {
  1137. X case 0: return B0;
  1138. X case 50: return B50;
  1139. X case 75: return B75;
  1140. X case 110: return B110;
  1141. X case 134: return B134;
  1142. X case 150: return B150;
  1143. X case 200: return B200;
  1144. X case 300: return B300;
  1145. X case 600: return B600;
  1146. X case 1200: return B1200;
  1147. X case 1800: return B1800;
  1148. X case 2400: return B2400;
  1149. X case 4800: return B4800;
  1150. X case 9600: return B9600;
  1151. X case 19200: return B19200;
  1152. X case 38400: return B38400;
  1153. X case 57600: return B57600;
  1154. X case 115200: return B115200;
  1155. X case 230400: return B230400;
  1156. X default: return -1;
  1157. X }
  1158. X }
  1159. X
  1160. X
  1161. X public static int cfgetispeed(Termios termios) {
  1162. X return libcfast.cfgetispeed(new termios_struct(termios)).intValue();
  1163. X }
  1164. X
  1165. X public static int cfgetospeed(Termios termios) {
  1166. X return libcfast.cfgetospeed(new termios_struct(termios)).intValue();
  1167. X }
  1168. X
  1169. X public static int cfsetispeed(Termios termios, int speed) {
  1170. X termios_struct t = new termios_struct(termios);
  1171. X int ret = libcfast.cfsetispeed(t, new NativeLong(speed));
  1172. X t.update(termios);
  1173. X return ret;
  1174. X }
  1175. X
  1176. X public static int cfsetospeed(Termios termios, int speed) {
  1177. X termios_struct t = new termios_struct(termios);
  1178. X int ret = libcfast.cfsetospeed(t, new NativeLong(speed));
  1179. X t.update(termios);
  1180. X return ret;
  1181. X }
  1182. X
  1183. X public static int open(String s, int t) {
  1184. X return libcfast.open(s, t);
  1185. X }
  1186. X
  1187. X public static int read(int fd, ByteBuffer buffer, int len) {
  1188. X return IS64B ? (int)libcfast.read(fd, buffer, (long)len) : libcfast.read(fd, buffer, len);
  1189. X }
  1190. X
  1191. X public static int read(int fd, byte[] buffer, int len) {
  1192. X return IS64B ? (int)libcfast.read(fd, buffer, (long)len) : libcfast.read(fd, buffer, len);
  1193. X }
  1194. X
  1195. X public static int pread(int fd, byte[] buffer, int len, long offset) {
  1196. X return IS64B ? (int)libcfast.pread(fd, buffer, (long)len, new NativeLong(offset)) : libcfast.pread(fd, buffer, len, new NativeLong(offset));
  1197. X }
  1198. X
  1199. X public static int write(int fd, ByteBuffer buffer, int len) {
  1200. X return IS64B ? (int)libcfast.write(fd, buffer, (long)len) : libcfast.write(fd, buffer, len);
  1201. X }
  1202. X
  1203. X public static int write(int fd, byte[] buffer, int len) {
  1204. X return IS64B ? (int)libcfast.write(fd, buffer, (long)len) : libcfast.write(fd, buffer, len);
  1205. X }
  1206. X
  1207. X public static long lseek(int fd, long off, int whence) {
  1208. X return libcfast.lseek(new NativeLong(fd), new NativeLong(off), new NativeLong(whence)).longValue();
  1209. X }
  1210. X
  1211. X public static int close(int fd) {
  1212. X return libcfast.close(fd);
  1213. X }
  1214. X
  1215. X public static int tcflush(int fd, int b) {
  1216. X return libcfast.tcflush(fd, b);
  1217. X }
  1218. X
  1219. X public static int tcgetattr(int fd, Termios termios) {
  1220. X termios_struct t = new termios_struct();
  1221. X int ret = libcfast.tcgetattr(fd, t);
  1222. X t.update(termios);
  1223. X return ret;
  1224. X }
  1225. X
  1226. X public static void perror(String msg) {
  1227. X libcfast.perror(msg);
  1228. X }
  1229. X
  1230. X public static int tcsendbreak(int fd, int duration) {
  1231. X // If duration is not zero, it sends zero-valued bits for duration*N seconds,
  1232. X // where N is at least 0.25, and not more than 0.5.
  1233. X return libcfast.tcsendbreak(fd, duration / 250);
  1234. X }
  1235. X
  1236. X public static int tcsetattr(int fd, int cmd, Termios termios) {
  1237. X return libcfast.tcsetattr(fd, cmd, new termios_struct(termios));
  1238. X }
  1239. X
  1240. X public static void FD_CLR(int fd, FDSet set) {
  1241. X if (set == null) {
  1242. X return;
  1243. X }
  1244. X set.bits[fd / FDSet.NFBBITS] &= ~(1 << (fd % FDSet.NFBBITS));
  1245. X }
  1246. X
  1247. X public static boolean FD_ISSET(int fd, FDSet set) {
  1248. X if (set == null) {
  1249. X return false;
  1250. X }
  1251. X return (set.bits[fd / FDSet.NFBBITS] & (1 << (fd % FDSet.NFBBITS))) != 0;
  1252. X }
  1253. X
  1254. X public static void FD_SET(int fd, FDSet set) {
  1255. X if (set == null) {
  1256. X return;
  1257. X }
  1258. X set.bits[fd / FDSet.NFBBITS] |= 1 << (fd % FDSet.NFBBITS);
  1259. X }
  1260. X
  1261. X public static void FD_ZERO(FDSet set) {
  1262. X if (set == null) {
  1263. X return;
  1264. X }
  1265. X Arrays.fill(set.bits, 0);
  1266. X }
  1267. X
  1268. X public static int select(int nfds, FDSet rfds, FDSet wfds, FDSet efds, TimeVal timeout) {
  1269. X timeval_struct tout = null;
  1270. X if (timeout != null) {
  1271. X tout = new timeval_struct(timeout);
  1272. X }
  1273. X
  1274. X int[] r = rfds != null ? rfds.bits : null;
  1275. X int[] w = wfds != null ? wfds.bits : null;
  1276. X int[] e = efds != null ? efds.bits : null;
  1277. X return libcfast.select(nfds, r, w, e, tout);
  1278. X }
  1279. X
  1280. X public static int poll(Pollfd fds[], int nfds, int timeout) {
  1281. X int[] v = new int[nfds * 2];
  1282. X for (int i=0,j=0;i<nfds;i++) {
  1283. X v[j++] = fds[i].fd;
  1284. X v[j++] = fds[i].events;
  1285. X }
  1286. X int ret = libcfast.poll(v, nfds, timeout);
  1287. X for (int i=0;i<nfds;i++) {
  1288. X fds[i].events = v[i*2+1];
  1289. X }
  1290. X return ret;
  1291. X }
  1292. X
  1293. X public static int ioctl(int fd, int cmd, int data) {
  1294. X return libcfast.ioctl(fd, cmd, data);
  1295. X }
  1296. X
  1297. X public static int ioctl(int fd, int cmd, byte[] data) {
  1298. X return libcfast.ioctl(fd, cmd, data);
  1299. X }
  1300. X
  1301. X public static int ioctl(int fd, int cmd, int[] data) {
  1302. X return libcfast.ioctl(fd, cmd, data);
  1303. X }
  1304. X
  1305. X private static final spi_ioc_transfer_struct spi_ioc_transfer_instance = new spi_ioc_transfer_struct();
  1306. X
  1307. X public static void ioctl_spimessage(int fd, ByteBuffer tx, ByteBuffer rx, int len) throws IOException {
  1308. X synchronized(spi_ioc_transfer_instance) {
  1309. X spi_ioc_transfer_instance.tx_buf = rx == null ? 0 : Pointer.nativeValue(Native.getDirectBufferPointer(tx));
  1310. X spi_ioc_transfer_instance.rx_buf = rx == null ? 0 : Pointer.nativeValue(Native.getDirectBufferPointer(rx));
  1311. X spi_ioc_transfer_instance.len = len;
  1312. X int cmd = ioc(false, SPI_IOC_MAGIC, 0, spi_ioc_transfer_instance.size());
  1313. X int v = libcfast.ioctl(fd, cmd, spi_ioc_transfer_instance);
  1314. X if (v < 0) {
  1315. X throw new IOException("ioctl(SPI_IOC_MESSAGE): "+POSIX.errmsg());
  1316. X }
  1317. X }
  1318. X }
  1319. X
  1320. X //----------------------------------------------------------------------
  1321. X
  1322. X private static class FastLibrary {
  1323. X native public int puts(ByteBuffer buf);
  1324. X native public long memcpy(int[] dst, short[] src, long n);
  1325. X native public int memcpy(int[] dst, short[] src, int n);
  1326. X native public int pipe(int[] fds);
  1327. X native public int tcdrain(int fd);
  1328. X native public void cfmakeraw(termios_struct termios);
  1329. X native public int fcntl(int fd, int cmd, int arg);
  1330. X native public int ioctl(int fd, int cmd, int arg);
  1331. X native public int ioctl(int fd, int cmd, int[] arg);
  1332. X native public int ioctl(int fd, int cmd, byte[] arg);
  1333. X native public int ioctl(int fd, int cmd, spi_ioc_transfer_struct arg);
  1334. X native public int open(String path, int flags);
  1335. X native public int close(int fd);
  1336. X native public String strerror(int errno);
  1337. X native public int tcgetattr(int fd, termios_struct termios);
  1338. X native public int tcsetattr(int fd, int cmd, termios_struct termios);
  1339. X native public int cfsetispeed(termios_struct termios, NativeLong i);
  1340. X native public int cfsetospeed(termios_struct termios, NativeLong i);
  1341. X native public NativeLong cfgetispeed(termios_struct termios);
  1342. X native public NativeLong cfgetospeed(termios_struct termios);
  1343. X native public int write(int fd, ByteBuffer buffer, int count);
  1344. X native public int read(int fd, ByteBuffer buffer, int count);
  1345. X native public int pread(int fd, byte[] buffer, int count, NativeLong offset);
  1346. X native public long write(int fd, ByteBuffer buffer, long count);
  1347. X native public long read(int fd, ByteBuffer buffer, long count);
  1348. X native public long pread(int fd, byte[] buffer, long count, NativeLong offset);
  1349. X native public int write(int fd, byte[] buffer, int count);
  1350. X native public int read(int fd, byte[] buffer, int count);
  1351. X native public long write(int fd, byte[] buffer, long count);
  1352. X native public long read(int fd, byte[] buffer, long count);
  1353. X native public NativeLong lseek(NativeLong fd, NativeLong off, NativeLong whence);
  1354. X native public int select(int n, int[] read, int[] write, int[] error, timeval_struct timeout);
  1355. X native public int poll(int[] fds, int nfds, int timeout);
  1356. X native public int tcflush(int fd, int qs);
  1357. X native public void perror(String msg);
  1358. X native public int tcsendbreak(int fd, int duration);
  1359. X static {
  1360. X try {
  1361. X Native.register("c");
  1362. X } catch (Exception e) {
  1363. X e.printStackTrace();
  1364. X }
  1365. X }
  1366. X }
  1367. X
  1368. X private interface SlowLibrary extends Library {
  1369. X void printf(String format, Object... args);
  1370. X public long memcpy(int[] dst, short[] src, long n);
  1371. X public int memcpy(int[] dst, short[] src, int n);
  1372. X public int pipe(int[] fds);
  1373. X public int tcdrain(int fd);
  1374. X public void cfmakeraw(termios_struct termios);
  1375. X public int fcntl(int fd, int cmd, int arg);
  1376. X public int ioctl(int fd, int cmd, int[] arg);
  1377. X public int ioctl(int fd, int cmd, Pointer arg);
  1378. X// public int ioctl(int fd, int cmd, serial arg);
  1379. X public int open(String path, int flags);
  1380. X public int close(int fd);
  1381. X public int tcgetattr(int fd, termios_struct termios);
  1382. X public int tcsetattr(int fd, int cmd, termios_struct termios);
  1383. X public int cfsetispeed(termios_struct termios, NativeLong i);
  1384. X public int cfsetospeed(termios_struct termios, NativeLong i);
  1385. X public NativeLong cfgetispeed(termios_struct termios);
  1386. X public NativeLong cfgetospeed(termios_struct termios);
  1387. X public int write(int fd, byte[] buffer, int count);
  1388. X public int read(int fd, byte[] buffer, int count);
  1389. X public long write(int fd, byte[] buffer, long count);
  1390. X public long read(int fd, byte[] buffer, long count);
  1391. X public NativeLong lseek(NativeLong fd, NativeLong off, NativeLong whence);
  1392. X public int select(int n, int[] read, int[] write, int[] error, timeval_struct timeout);
  1393. X public int tcflush(int fd, int qs);
  1394. X public void perror(String msg);
  1395. X public int tcsendbreak(int fd, int duration);
  1396. X }
  1397. X
  1398. X public static class timeval_struct extends Structure {
  1399. X public NativeLong tv_sec;
  1400. X public NativeLong tv_usec;
  1401. X
  1402. X public timeval_struct(TimeVal timeout) {
  1403. X tv_sec = new NativeLong(timeout.tv_sec);
  1404. X tv_usec = new NativeLong(timeout.tv_usec);
  1405. X }
  1406. X
  1407. X @Override protected List getFieldOrder() {
  1408. X return Arrays.asList("tv_sec", "tv_usec");
  1409. X }
  1410. X }
  1411. X
  1412. X /*
  1413. X public static class serial extends Structure {
  1414. X public int type;
  1415. X public int line;
  1416. X public int port;
  1417. X public int irq;
  1418. X public int flags;
  1419. X public int xmit_fifo_size;
  1420. X public int custom_divisor;
  1421. X public int baud_base;
  1422. X public short close_delay;
  1423. X public short io_type;
  1424. X public int hub6;
  1425. X public short closing_wait;
  1426. X public short closing_wait2;
  1427. X public Pointer iomem_base;
  1428. X public short iomem_reg_shift;
  1429. X public int port_high;
  1430. X public NativeLong iomap_base;
  1431. X
  1432. X @Override protected List getFieldOrder() {
  1433. X return Arrays.asList("type", "line", "port", "irq", "flags", "xmit_fifo_size", "custom_divisor", "baud_base", "close_delay", "io_type", "hub6", "closing_wait", "closing_wait2", "iomem_base", "iomem_reg_shift", "port_high", "iomap_base");
  1434. X }
  1435. X };
  1436. X */
  1437. X
  1438. X public static class termios_struct extends Structure {
  1439. X public int c_iflag;
  1440. X public int c_oflag;
  1441. X public int c_cflag;
  1442. X public int c_lflag;
  1443. X public byte c_line;
  1444. X public byte[] c_cc = new byte[32];
  1445. X public int c_ispeed;
  1446. X public int c_ospeed;
  1447. X
  1448. X public termios_struct() {
  1449. X }
  1450. X
  1451. X public termios_struct(Termios t) {
  1452. X c_iflag = t.c_iflag;
  1453. X c_oflag = t.c_oflag;
  1454. X c_cflag = t.c_cflag;
  1455. X c_lflag = t.c_lflag;
  1456. X System.arraycopy(t.c_cc, 0, c_cc, 0, t.c_cc.length);
  1457. X c_ispeed = t.c_ispeed;
  1458. X c_ospeed = t.c_ospeed;
  1459. X }
  1460. X
  1461. X public void update(Termios t) {
  1462. X t.c_iflag = c_iflag;
  1463. X t.c_oflag = c_oflag;
  1464. X t.c_cflag = c_cflag;
  1465. X t.c_lflag = c_lflag;
  1466. X System.arraycopy(c_cc, 0, t.c_cc, 0, t.c_cc.length);
  1467. X t.c_ispeed = c_ispeed;
  1468. X t.c_ospeed = c_ospeed;
  1469. X }
  1470. X
  1471. X @Override protected List getFieldOrder() {
  1472. X return Arrays.asList("c_iflag", "c_oflag", "c_cflag", "c_lflag", "c_line", "c_cc", "c_ispeed", "c_ospeed");
  1473. X }
  1474. X }
  1475. X
  1476. X public static final class FDSet {
  1477. X static final int FD_SET_SIZE = 1024;
  1478. X static final int NFBBITS = 32;
  1479. X int[] bits = new int[(FD_SET_SIZE + NFBBITS - 1) / NFBBITS];
  1480. X
  1481. X public String toString() {
  1482. X return String.format("%08X%08X", bits[0], bits[1]);
  1483. X }
  1484. X }
  1485. X
  1486. X public static final class Pollfd {
  1487. X int fd;
  1488. X int events;
  1489. X
  1490. X public Pollfd() {
  1491. X }
  1492. X
  1493. X public Pollfd(int fd, short events) {
  1494. X this.fd = fd;
  1495. X this.events = eventmask[events&7];
  1496. X }
  1497. X
  1498. X public void init(int fd, short events) {
  1499. X this.fd = fd;
  1500. X this.events = eventmask[events&7];
  1501. X }
  1502. X
  1503. X boolean isIn() {
  1504. X return (events & POLLIN_OUT) != 0;
  1505. X }
  1506. X boolean isOut() {
  1507. X return (events & POLLOUT_OUT) != 0;
  1508. X }
  1509. X boolean isPri() {
  1510. X return (events & POLLPRI_OUT) != 0;
  1511. X }
  1512. X boolean isErr() {
  1513. X return (events & POLLERR_OUT) != 0;
  1514. X }
  1515. X boolean isHup() {
  1516. X return (events & POLLHUP_OUT) != 0;
  1517. X }
  1518. X boolean isNval() {
  1519. X return (events & POLLNVAL_OUT) != 0;
  1520. X }
  1521. X
  1522. X private static final int POLLIN_OUT = pollMask(1, POLLIN);
  1523. X private static final int POLLPRI_OUT = pollMask(1, POLLPRI);
  1524. X private static final int POLLOUT_OUT = pollMask(1, POLLOUT);
  1525. X private static final int POLLERR_OUT = pollMask(1, (short)0x08);
  1526. X private static final int POLLHUP_OUT = pollMask(1, (short)0x10);
  1527. X private static final int POLLNVAL_OUT = pollMask(1, (short)0x20);
  1528. X private static int pollMask(int out, short n) {
  1529. X short[] s = new short[2];
  1530. X int[] d = new int[1];
  1531. X s[out] = n;
  1532. X if (IS64B) {
  1533. X libcfast.memcpy(d, s, (long) 4);
  1534. X } else {
  1535. X libcfast.memcpy(d, s, (int) 4);
  1536. X }
  1537. X return d[0];
  1538. X }
  1539. X private static final int[] eventmask = new int[8];
  1540. X static {
  1541. X for (short i=0;i<8;i++) {
  1542. X eventmask[i] = pollMask(0, i);
  1543. X }
  1544. X }
  1545. X }
  1546. X
  1547. X public static final class TimeVal {
  1548. X public long tv_sec;
  1549. X public long tv_usec;
  1550. X public TimeVal(long sec, long usec) {
  1551. X this.tv_sec = sec;
  1552. X this.tv_usec = usec;
  1553. X }
  1554. X public String toString() {
  1555. X return String.format("%d.%06d", tv_sec, tv_usec);
  1556. X }
  1557. X }
  1558. X
  1559. X public static final class Termios {
  1560. X public int c_iflag;
  1561. X public int c_oflag;
  1562. X public int c_cflag;
  1563. X public int c_lflag;
  1564. X public byte[] c_cc = new byte[20];
  1565. X public int c_ispeed;
  1566. X public int c_ospeed;
  1567. X public void set(Termios s) {
  1568. X c_iflag = s.c_iflag;
  1569. X c_oflag = s.c_oflag;
  1570. X c_cflag = s.c_cflag;
  1571. X c_lflag = s.c_lflag;
  1572. X System.arraycopy(s.c_cc, 0, c_cc, 0, c_cc.length);
  1573. X c_ispeed = s.c_ispeed;
  1574. X c_ospeed = s.c_ospeed;
  1575. X }
  1576. X }
  1577. X
  1578. X public static class spi_ioc_transfer_struct extends Structure {
  1579. X public long tx_buf;
  1580. X public long rx_buf;
  1581. X public int len;
  1582. X public int speed_hz;
  1583. X public short delay_usecs;
  1584. X public byte bits_per_word;
  1585. X public byte cs_change;
  1586. X public int pad;
  1587. X
  1588. X @Override protected List getFieldOrder() {
  1589. X return Arrays.asList("tx_buf", "rx_buf", "len", "speed_hz", "delay_usecs", "bits_per_word", "cs_change", "pad");
  1590. X }
  1591. X }
  1592. X
  1593. X}
  1594. END-of-POSIX.java
  1595. exit
Add Comment
Please, Sign In to add comment