package com.knutejohnson.pi.jpigpio; import java.io.*; import java.net.*; import java.nio.*; import java.util.*; import static java.util.stream.Collectors.*; import static com.knutejohnson.pi.jpigpio.JPigpioConstants.*; /** * JPigpio * * A Java wrapper written in all Java to access the pigpio library through its * socket interface. See http://abyz.me.uk/rpi/pigpio/ for details of the * pigpio libary. See http://knutejohnson.com/pi/jpigpio for details of this * library. * * @version 0.21.0 - 2021-02-11 * @author Knute Johnson */ public class JPigpio implements AutoCloseable { /** JPigpio version */ public static final String VERSION = "0.21.0"; /** Socket to connect to pigpio */ private final Socket socket; /** OutputStream for socket */ private final OutputStream os; /** InputStream for socket */ private final InputStream is; /** List of commands that return 32 bit unsigned results */ private final List<Integer> listOf32BitResults = Arrays.asList(10,11,16,17,26); /** Debug flag */ private volatile boolean debugMode; /** * Create a new JPigpio object and connect it to the specified pigpio on * the specified port. * * @param ip hostname or ip address where pigpio is running * @param port port pigpio is listening on * @throws UnknownHostException if the IP address of the host could not be * determined * @throws IOException if an I/O error occurs creating the socket or when * creating the input or output streams */ public JPigpio(String ip, int port) throws UnknownHostException,IOException { socket = new Socket(ip,port); os = socket.getOutputStream(); is = socket.getInputStream(); } /** * Create a new JPigpio object and connects it to the local machine on the * default port. * * @throws UnknownHostException if the IP address of the host could not be * determined * @throws IOException if an I/O error occurs creating the socket or when * creating the input or output streams */ public JPigpio() throws UnknownHostException, IOException { this("::1",8888); } /** * Set the mode for the GPIO pin. * * @param gpio GPIO pin number * @param mode GPIO pin modes (PI_INPUT, PI_OUTPUT, PI_ALT0 - 7) * @return 0 for success, otherwise PI_BAD_GPIO, PI_BAD_MODE, or * PI_NOT_PERMITTED * @throws IOException if an I/O error occurs */ public int modeSet(int gpio, int mode) throws IOException { sendCmd(PI_CMD_MODES,gpio,mode,0); return readEcho(); } /** * Get the mode for the GPIO pin. * * @param gpio GPIO pin number * @return the GPIO mode or PI_BAD_GPIO * @throws IOException if an I/O error occurs */ public int modeGet(int gpio) throws IOException { sendCmd(PI_CMD_MODEG,gpio,0,0); return readEcho(); } /** * Set the pull up/down for the specified GPIO pin. * * @param gpio GPIO pin number * @param pud one of PI_PUD_OFF, PI_PUD_DOWN, or PI_PUD_UP * @return 0 for success or PI_BAD_GPIO, PI_BAD_PUD, or PI_NOT_PERMITTED * @throws IOException if an I/O error occurs */ public int pullUpDown(int gpio, int pud) throws IOException { sendCmd(PI_CMD_PUD,gpio,pud,0); return readEcho(); } /** * Read the level on the specified GPIO pin. * * @param gpio GPIO pin number * @return gpio level or PI_BAD_GPIO * @throws IOException if an I/O error occurs */ public int read(int gpio) throws IOException { sendCmd(PI_CMD_READ,gpio,0,0); return readEcho(); } /** * Write the level to the GPIO pin. * * @param gpio GPIO pin number * @param level 0 or 1 * @return 0 on success or PI_BAD_GPIO, PI_BAD_LEVEL, or PI_NOT_PERMITTED * @throws IOException if an I/O error occurs */ public int write(int gpio, int level) throws IOException { sendCmd(PI_CMD_WRITE,gpio,level,0); return readEcho(); } /** * Start PWM (non-zero dutycycle) or stop (0) on the specified GPIO. * * @param gpio GPIO pin number * @param dutycycle pwm dutycycle * @return 0 on success or PI_BAD_USER_GPIO, PI_BAD_DUTYCYCLE, or * PI_NOT_PERMITTED * @throws IOException if an I/O error occurs * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#set_PWM_dutycycle">pigpiod documentation for setPWM_range</a> */ public int setPWMValue(int gpio, int dutycycle) throws IOException { sendCmd(PI_CMD_PWM,gpio,dutycycle,0); return readEcho(); } /** * Set PWM range. If PWM is currently active on the GPIO its dutycycle * will be scaled to reflect the new range. * * @param gpio GPIO pin number * @param range pwm range (25-40000) * @return 0 on success or PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO * @throws IOException if an I/O occurs * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#set_PWM_range">pigpiod documentation for set_PWM_range</a> */ public int setPWMRange(int gpio, int range) throws IOException { sendCmd(PI_CMD_PRS,gpio,range,0); return readEcho(); } /** * Set PWM frequency. Overrides servo commands on this GPIO. * * @param gpio GPIO pin number * @param freq pwm frequency * @return Numerically closest frequency on success or PI_BAD_USER_GPIO, * if PWM is currently active on the GPIO it will be switched off * and then back on at the new frequency. Each GPIO can be set * to one of 18 different PWM frequencies. The selectable * frequencies depend on the sample rate which is set when the * pigpio daemon is started. * @throws IOException if an I/O error occurs * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#set_PWM_frequency">pigpiod documentation for set_PWM_frequency</a> */ public int setPWMFreq(int gpio, int freq) throws IOException { sendCmd(PI_CMD_PFS,gpio,freq,0); return readEcho(); } /** * Get PWM range. * * @param gpio GPIO pin number * @return pwm range or PI_BAD_USER_GPIO * @throws IOException if an I/O error occurs * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#get_PWM_dutycycle">pigpiod documentation for get_PWM_range</a> */ public int getPWMRange(int gpio) throws IOException { sendCmd(PI_CMD_PRG,gpio,0,0); return readEcho(); } /** * Get PWM frequency. * * @param gpio GPIO pin number * @return pwm frequency or PI_BAD_USER_GPIO * @throws IOException if an I/O error occurs * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#get_PWM_frequency">see pigpiod documenation</a> */ public int getPWMFreq(int gpio) throws IOException { sendCmd(PI_CMD_PFG,gpio,0,0); return readEcho(); } /** * Get PWM real range. * * @param gpio GPIO pin number * @return pwm real range or PI_BAD_USER_GPIO * @throws IOException if an I/O error occurs * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#get_PWM_real_range">see pigpiod documentation</a> */ public int getPWMRealRange(int gpio) throws IOException { sendCmd(PI_CMD_PRRG,gpio,0,0); return readEcho(); } /** * Get PWM value (dutycycle). * * @param gpio GPIO pin number * @return dutycycle or PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#get_PWM_dutycycle">see pigpiod documentation</a> * @throws IOException if an I/O error occurs */ public int getPWMValue(int gpio) throws IOException { sendCmd(PI_CMD_GDC,gpio,0,0); return readEcho(); } /** * Starts servo pulses on the specified GPIO in pulsewidth milliseconds. * Overrides PWM commands on this GPIO. * * @param gpio GPIO pin number * @param pulsewidth pulse width in milliseconds, values from 500 to * 2500 start the pulses with 0 stopping the pulses * @return 0 on success or PI_BAD_USER_GPIO, PI_BAD_PULSEWIDTH, or * PI_NOT_PERMITTED * @throws IOException if an I/O error occurs */ public int setServoPulsewidth(int gpio, int pulsewidth) throws IOException { sendCmd(PI_CMD_SERVO,gpio,pulsewidth,0); return readEcho(); } /** * Read the levels of bank 1 GPIO (0-31). * * @return bitmask in int * @throws IOException if an I/O error occurs */ public int readBank1() throws IOException { sendCmd(PI_CMD_BR1,0,0,0); return readEcho(); } /** * Read the levels of bank 2 GPIO (32-53). * * @return bitmask in lower order 21 bits corresponding to GPIO 32-53 * @throws IOException if an I/O error occurs */ public int readBank2() throws IOException { sendCmd(PI_CMD_BR2,0,0,0); return readEcho(); } /** * Clear bank 1 GPIO (0-31) if the corresponding bit is set. * * @param bits bitmask * @return 0 if success or PI_SOME_PERMITTED. A status of * PI_SOME_PERMITTED indicates the user is not allowed t write * to one or more of the GPIO * @throws IOException if an I/O error occurs */ public int clearBank1(int bits) throws IOException { sendCmd(PI_CMD_BC1,bits,0,0); return readEcho(); } /** * Clear bank 2 GPIO (32-53) if the corresponding bit is set. * Bit 0 corresponds to pin 32 and bit 21 to pin 53. * * @param bits bitmask in lower order 21 bits * @return 0 if success or PI_SOME_PERMITTED. A status of * PI_SOME_PERMITTED indicates the user is not allowed t write * to one or more of the GPIO * @throws IOException if an I/O error occurs */ public int clearBank2(int bits) throws IOException { sendCmd(PI_CMD_BC2,bits,0,0); return readEcho(); } /** * Set bank 1 GPIO pins (0-31) corresponding to bitmask. * * @param bits bitmask * @return 0 if success or PI_SOME_PERMITTED. A status of * PI_SOME_PERMITTED indicates the user is not allowed t write * to one or more of the GPIO * @throws IOException if an I/O error occurs */ public int setBank1(int bits) throws IOException { sendCmd(PI_CMD_BS1,bits,0,0); return readEcho(); } /** * Set bank 2 GPIO pins (32-53) corresponding to bitmask. * Bit 0 corresponds to pin 32 and bit 21 to pin 53. * * @param bits bitmask in lower order 21 bits * @return 0 if success or PI_SOME_PERMITTED. A status of * PI_SOME_PERMITTED indicates the user is not allowed t write * to one or more of the GPIO * @throws IOException if an I/O error occurs */ public int setBank2(int bits) throws IOException { sendCmd(PI_CMD_BS2,bits,0,0); return readEcho(); } /** * Gets the servo pulse width on the specified GPIO pin. * * @param gpio GPIO pin number * @return pulse width in milliseconds or PI_BAD_USER o rPI_NOT_SERVO_GPIO * @throws IOException if an I/O error occurs */ public int getServoPulseWidth(int gpio) throws IOException { sendCmd(PI_CMD_GPW,gpio,0,0); return readEcho(); } /** * Sets a glitch filter on a GPIO. Level changes are not reported unless * the level has been stable for at least 'steady' microseconds. * * @param gpio GPIO to filter (0 - 31) * @param steady time in microseconds level change must be steady * @return 0 on success or PI_BAD_USER_GPIO or PI_BAD_FILTER * @throws IOException if an I/O error occurs * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#set_glitch_filter">pigpiod documentation for set_glitch_filter</a> */ public int setGlitchFilter(int gpio,int steady) throws IOException { sendCmd(PI_CMD_FG,gpio,steady,0); return readEcho(); } /** * Sets a noise filter on a GPIO. Level changes are ignored until a level * which has been stable for 'steady' microseconds is detected. Level * changes are reported for 'active' microseconds after which the process * repeats. * * @param gpio GPIO to filter (0 - 31) * @param steady time in microseconds level change must be steady * @param active period during which level changes are rported * @return 0 on success or PI_BAD_USER_GPIO or PI_BAD_FILTER * @throws IOException if an I/O error occurs * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#set_noise_filter">pigpiod documentation for set_noise_filter</a> */ public int setNoiseFilter(int gpio,int steady,int active) throws IOException { sendCmd(PI_CMD_FN,gpio,steady,4); sendExt(active); return readEcho(); } /** * Returns the current tick count from the pigpio library. The tick count * is stored in the pigpio library as an unsigned 32 bit number that will * roll over about 72 minutes after boot. * * @return tick count * @throws IOException if an I/O error occurs */ public long tick() throws IOException { sendCmd(PI_CMD_TICK,0,0,0); return Integer.toUnsignedLong(readEcho()); } /** * Measure an elapsed time period in ticks between two tick counts dealing * with the 32 bit rollover. * * @param first the tick count at the beginning of the period * @param second the tick count at the end of the period * @return the elapsed time in ticks */ public long tickDiff(long first, long second) { long diff = second - first; diff &= 0xffffffffL; return diff; } /** * Returns the hardware version. * * @return the hardware version (display in hex for readability) * @throws IOException if an I/O error occurs */ public long hardwareVersion() throws IOException { sendCmd(PI_CMD_HWVER,0,0,0); return Integer.toUnsignedLong(readEcho()); } /** * Returns the pigpio version. * * @return the pigpio version * @throws IOException if an I/O error occurs */ public long pigpioVersion() throws IOException { sendCmd(PI_CMD_PIGPV,0,0,0); return Integer.toUnsignedLong(readEcho()); } /** * Requests a free notification handle. * * @return notification handle or PI_NO_HANDLE * @throws IOException if an I/O error occurs */ public int notifyOpen() throws IOException { sendCmd(PI_CMD_NO,0,0,0); return readEcho(); } /** * Starts notifications on a previously opened handle. * * @param handle notification handle from notifyOpen * @param bits bit mask specifying which GPIO state change will be * sent notifications * @return 0 on success or PI_BAD_HANDLE * @throws IOException if an I/O error occurs */ public int notifyBegin(int handle, int bits) throws IOException { sendCmd(PI_CMD_NB,handle,bits,0); return readEcho(); } /** * Pauses notifcations on a previously opened handle. * * @param handle notification handle * @return 0 on success or PI_BAD_HANDLE * @throws IOException if an I/O error occurs */ public int notifyPause(int handle) throws IOException { sendCmd(PI_CMD_NP,handle,0,0); return readEcho(); } /** * Stops notifications on a previously opend handle and releases the handle. * * @param handle notification handle * @return 0 on success or PI_BAD_HANDLE * @throws IOException if an I/O error occurs */ public int notifyClose(int handle) throws IOException { sendCmd(PI_CMD_NC,handle,0,0); return readEcho(); } /** * Sends a trigger pulse to specified GPIO of specified pulse length in * microseconds and level. * * @param gpio GPIO pin number * @param pulselen pulse length in microseconds * @param level level of the pulse * @return 0 on success or error code * @throws IOException if an I/O error occurs */ public int gpioTrigger(int gpio, int pulselen, int level) throws IOException { sendCmd(PI_CMD_TRIG,gpio,pulselen,4); sendExt(level); return readEcho(); } /** * Starts a hardware clock at the specified frequency on the specified GPIO * pin. Frequency of 0 stops the clock. * * @param gpio GPIO pin * @param clkfreq clock frequency * @return 0 on success or PI_NOT_PERMITTED, PI_BAD_GPIO, PI_NOT_CHLK_GPIO, * PI_BAD_HCLK_FREQ, or PI_BAD_HCLK_PASS * @throws IOException if an I/O error occurs * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#hardware_clock">pipgiod documentation for hardware_clock</a> */ public int hardwareClock(int gpio, int clkfreq) throws IOException { sendCmd(PI_CMD_HC,gpio,clkfreq,0); return readEcho(); } /** * Starts hardware PWM on a GPIO at the specified frequency and dutycycle. * * @param gpio GPIO pin number * @param freq PWM frequency * @param dutycycle PWM dutycycle * @return 0 if success or PI_NOT_PERMITTED, PI_BAD_GPIO,PI_NOT_HPWM_GPIO, * PI_BAD_HPWM_DUTY, PI_BAD_HPWM_FREQ, or PI_HPWM_ILLEGAL * @throws IOException if an I/O error occurs * @see <a href="http://abyz.me.uk/rpi/pigpio/pdif2.html#hardware_PWM">pigpiod documentation for hardware PWM</a> */ public int hardwarePWM(int gpio,int freq, int dutycycle) throws IOException { sendCmd(PI_CMD_HP,gpio,freq,4); sendExt(dutycycle); return readEcho(); } //------------------------------------------------------------------------- /** * Sends the specified command and parameters to the running pigpio library. * * @param cmd pigpio command * @param p1 first parameter * @param p2 second parameter * @param p3 third parameter * @throws IOException if an I/O error occurs */ protected void sendCmd(int cmd, int p1, int p2, int p3) throws IOException { ByteBuffer outBuf = ByteBuffer.allocate(16); outBuf.order(ByteOrder.LITTLE_ENDIAN); outBuf.putInt(cmd); outBuf.putInt(p1); outBuf.putInt(p2); outBuf.putInt(p3); os.write(outBuf.array()); os.flush(); } /** * Read the echo of a command and return the result field. If the debug * mode is enabled on an error this method will pring the calling method * and the error message. * * @return result field * @throws IOException if an I/O error occurs */ protected int readEcho() throws IOException { int n = 0; byte[] resBuf = new byte[16]; while ((n += is.read(resBuf,n,16-n)) < 16) ; ByteBuffer inBuf = ByteBuffer.wrap(resBuf); inBuf.order(ByteOrder.LITTLE_ENDIAN); int cmd = inBuf.getInt(0); int res = inBuf.getInt(12); if (debugMode && res < 0 && !listOf32BitResults.contains(cmd)) { // get the calling method name StackWalker walker = StackWalker.getInstance(); Optional<String> methodName = walker.walk(frames -> frames. limit(2). reduce((first,second) -> second). map(StackWalker.StackFrame::getMethodName)); String funcName = methodName.isPresent() ? methodName.get() : ""; System.out.printf("Error in %s: %s\n",funcName, JPigpio.errorToString(res)); } return res; } /** * Send an integer (32 bit) extension to the running pigpio library. * * @param ext integer extension * @throws IOException if an I/O error occurs */ public void sendExt(int ext) throws IOException { ByteBuffer outBuf = ByteBuffer.allocate(4); outBuf.order(ByteOrder.LITTLE_ENDIAN); outBuf.putInt(ext); os.write(outBuf.array()); os.flush(); } /** * Send a command extension to the running pigpio library. * * @param buf byte array to send * @throws IOException if an I/O error occurs */ public void sendExt(byte[] buf) throws IOException { os.write(buf); os.flush(); } /** * Send a command extension to the running pigpio library. * * @param buf byte array to send * @param offset into the byte array * @param length number of bytes to send * @throws IOException if an I/O error occurs */ public void sendExt(byte[] buf, int offset, int length) throws IOException { os.write(buf,offset,length); os.flush(); } /** * readReport reads the 12 byte packet from the specified input stream when * a notify has been sent. * * @param is InputStream to read report from * @return a GPIOReport object with the report data * @throws IOException if an I/O error occurs */ public GPIOReport readReport(InputStream is) throws IOException { int n = 0; byte[] resBuf = new byte[12]; while ((n += is.read(resBuf,n,12-n)) < 12) ; ByteBuffer inBuf = ByteBuffer.wrap(resBuf); inBuf.order(ByteOrder.LITTLE_ENDIAN); return new GPIOReport( Short.toUnsignedInt(inBuf.getShort()), Short.toUnsignedInt(inBuf.getShort()), Integer.toUnsignedLong(inBuf.getInt()), Integer.toUnsignedLong(inBuf.getInt())); } /** * Sets the debug mode. * * @param state true enables debug mode */ public void setDebugMode(boolean state) { debugMode = state; } /** * Get debug mode. * * @return true if debug mode is enabled otherwise false */ public boolean getDebugMode() { return debugMode; } /** * Disconnects the socket from the running pigpio libaray. * * @throws IOException if an I/O error occurs */ public void disconnect() throws IOException { socket.close(); } /** * Specified by AutoCloseable, disconnects from the running pigpio library. * * @throws IOException if an I/O error occurs */ @Override public void close() throws IOException { disconnect(); } /** * Get the JPigpio version. * * @return JPigpio version string */ public static String getVersion() { return VERSION; } /** * Returns a string error message from an error number. * * @param errno pigpio error number * @return error message string */ public static String errorToString(int errno) { switch(errno) { case PI_NO_ERROR: return "no error"; case PI_INIT_FAILED: return "gpioInitialise failed"; case PI_BAD_USER_GPIO: return "GPIO not 0-31"; case PI_BAD_GPIO: return "GPIO not 0-53"; case PI_BAD_MODE: return "mode not 0-7"; case PI_BAD_LEVEL: return "level not 0-1"; case PI_BAD_PUD: return "pud not 0-2"; case PI_BAD_PULSEWIDTH: return "pulsewidth not 0 or 500-2500"; case PI_BAD_DUTYCYCLE: return "dutycycle outside set range"; case PI_BAD_TIMER: return "timer not 0-9"; case PI_BAD_MS: return "ms not 10-60000"; case PI_BAD_TIMETYPE: return "timetype not 0-1"; case PI_BAD_SECONDS: return "seconds < 0"; case PI_BAD_MICROS: return "micros not 0-999999"; case PI_TIMER_FAILED: return "gpioSetTimerFunc failed"; case PI_BAD_WDOG_TIMEOUT: return "timeout not 0-60000"; case PI_NO_ALERT_FUNC: return "DEPRECATED"; case PI_BAD_CLK_PERIPH: return "clock peripheral not 0-1"; case PI_BAD_CLK_SOURCE: return "DEPRECATED"; case PI_BAD_CLK_MICROS: return "clock micros not 1, 2, 4, 5, 8, or 10"; case PI_BAD_BUF_MILLIS: return "buf millis not 100-10000"; case PI_BAD_DUTYRANGE: return "dutycycle range not 25-40000"; case PI_BAD_SIGNUM: return "signum not 0-63"; case PI_BAD_PATHNAME: return "can't open pathname"; case PI_NO_HANDLE: return "no handle available"; case PI_BAD_HANDLE: return "unknown handle"; case PI_BAD_IF_FLAGS: return "ifFlags > 4"; case PI_BAD_CHANNEL: return "DMA channel not 0-15"; // case PI_BAD_PRIM_CHANNEL: return "DMA primary channel not 0-15"; case PI_BAD_SOCKET_PORT: return "socket port not 1024-32000"; case PI_BAD_FIFO_COMMAND: return "unrecognized fifo command"; case PI_BAD_SECO_CHANNEL: return "DMA secondary channel not 0-15"; case PI_NOT_INITIALISED: return "function called before gpioInitialise"; case PI_INITIALISED: return "function called after gpioInitialise"; case PI_BAD_WAVE_MODE: return "waveform mode not 0-3"; case PI_BAD_CFG_INTERNAL: return "bad parameter in gpioCfgInternals call"; case PI_BAD_WAVE_BAUD: return "baud rate not 50-250K(RX)/50-1M(TX)"; case PI_TOO_MANY_PULSES: return "waveform has too many pulses"; case PI_TOO_MANY_CHARS: return "waveform has too many chars"; case PI_NOT_SERIAL_GPIO: return "no bit bang serial read on GPIO"; case PI_BAD_SERIAL_STRUC: return "bad (null) serial structure parameter"; case PI_BAD_SERIAL_BUF: return "bad (null) serial buf parameter"; case PI_NOT_PERMITTED: return "GPIO operation not permitted"; case PI_SOME_PERMITTED: return "one or more GPIO not permitted"; case PI_BAD_WVSC_COMMND: return "bad WVSC subcommand"; case PI_BAD_WVSM_COMMND: return "bad WVSM subcommand"; case PI_BAD_WVSP_COMMND: return "bad WVSP subcommand"; case PI_BAD_PULSELEN: return "trigger pulse length not 1-100"; case PI_BAD_SCRIPT: return "invalid script"; case PI_BAD_SCRIPT_ID: return "unknown script id"; case PI_BAD_SER_OFFSET: return "add serial data offset > 30 minutes"; case PI_GPIO_IN_USE: return "GPIO already in use"; case PI_BAD_SERIAL_COUNT: return "must read at least a byte at a time"; case PI_BAD_PARAM_NUM: return "script parameter id not 0-9"; case PI_DUP_TAG: return "script has duplicate tag"; case PI_TOO_MANY_TAGS: return "script has too many tags"; case PI_BAD_SCRIPT_CMD: return "illegal script command"; case PI_BAD_VAR_NUM: return "script variable id not 0-149"; case PI_NO_SCRIPT_ROOM: return "no more room for scripts"; case PI_NO_MEMORY: return "can't allocate temporary memory"; case PI_SOCK_READ_FAILED: return "socket read failed"; case PI_SOCK_WRIT_FAILED: return "socket write failed"; case PI_TOO_MANY_PARAM: return "too many script parameters (> 10)"; // case PI_NOT_HALTED: return "DEPRECATED"; case PI_SCRIPT_NOT_READY: return "script initialising"; case PI_BAD_TAG: return "script has unresolved tag"; case PI_BAD_MICS_DELAY: return "bad MICS delay (too large)"; case PI_BAD_MILS_DELAY: return "bad MILS delay (too large)"; case PI_BAD_WAVE_ID: return "non existent wave id"; case PI_TOO_MANY_CBS: return "No more CBs for waveform"; case PI_TOO_MANY_OOL: return "No more OOL for waveform"; case PI_EMPTY_WAVEFORM: return "attempt to create an empty waveform"; case PI_NO_WAVEFORM_ID: return "no more waveforms"; case PI_I2C_OPEN_FAILED: return "can't open I2C device"; case PI_SER_OPEN_FAILED: return "can't open serial device"; case PI_SPI_OPEN_FAILED: return "can't open SPI device"; case PI_BAD_I2C_BUS: return "bad I2C bus"; case PI_BAD_I2C_ADDR: return "bad I2C address"; case PI_BAD_SPI_CHANNEL: return "bad SPI channel"; case PI_BAD_FLAGS: return "bad i2c/spi/ser open flags"; case PI_BAD_SPI_SPEED: return "bad SPI speed"; case PI_BAD_SER_DEVICE: return "bad serial device name"; case PI_BAD_SER_SPEED: return "bad serial baud rate"; case PI_BAD_PARAM: return "bad i2c/spi/ser parameter"; case PI_I2C_WRITE_FAILED: return "i2c write failed"; case PI_I2C_READ_FAILED: return "i2c read failed"; case PI_BAD_SPI_COUNT: return "bad SPI count"; case PI_SER_WRITE_FAILED: return "ser write failed"; case PI_SER_READ_FAILED: return "ser read failed"; case PI_SER_READ_NO_DATA: return "ser read no data available"; case PI_UNKNOWN_COMMAND: return "unknown command"; case PI_SPI_XFER_FAILED: return "spi xfer/read/write failed"; case PI_BAD_POINTER: return "bad (NULL) pointer"; case PI_NO_AUX_SPI: return "no auxiliary SPI on Pi A or B"; case PI_NOT_PWM_GPIO: return "GPIO is not in use for PWM"; case PI_NOT_SERVO_GPIO: return "GPIO is not in use for servo pulses"; case PI_NOT_HCLK_GPIO: return "GPIO has no hardware clock"; case PI_NOT_HPWM_GPIO: return "GPIO has no hardware PWM"; case PI_BAD_HPWM_FREQ: return "invalid hardware PWM frequency"; case PI_BAD_HPWM_DUTY: return "hardware PWM dutycycle not 0-1M"; case PI_BAD_HCLK_FREQ: return "invalid hardware clock frequency"; case PI_BAD_HCLK_PASS: return "need password to use hardware clock 1"; case PI_HPWM_ILLEGAL: return "illegal, PWM in use for main clock"; case PI_BAD_DATABITS: return "serial data bits not 1-32"; case PI_BAD_STOPBITS: return "serial (half) stop bits not 2-8"; case PI_MSG_TOOBIG: return "socket/pipe message too big"; case PI_BAD_MALLOC_MODE: return "bad memory allocation mode"; case PI_TOO_MANY_SEGS: return "too many I2C transaction segments"; case PI_BAD_I2C_SEG: return "an I2C transaction segment failed"; case PI_BAD_SMBUS_CMD: return "SMBus command not supported by driver"; case PI_NOT_I2C_GPIO: return "no bit bang I2C in progress on GPIO"; case PI_BAD_I2C_WLEN: return "bad I2C write length"; case PI_BAD_I2C_RLEN: return "bad I2C read length"; case PI_BAD_I2C_CMD: return "bad I2C command"; case PI_BAD_I2C_BAUD: return "bad I2C baud rate, not 50-500k"; case PI_CHAIN_LOOP_CNT: return "bad chain loop count"; case PI_BAD_CHAIN_LOOP: return "empty chain loop"; case PI_CHAIN_COUNTER: return "too many chain counters"; case PI_BAD_CHAIN_CMD: return "bad chain command"; case PI_BAD_CHAIN_DELAY: return "bad chain delay micros"; case PI_CHAIN_NESTING: return "chain counters nested too deeply"; case PI_CHAIN_TOO_BIG: return "chain is too long"; case PI_DEPRECATED: return "deprecated function removed"; case PI_BAD_SER_INVERT: return "bit bang serial invert not 0 or 1"; case PI_BAD_EDGE: return "bad ISR edge value, not 0-2"; case PI_BAD_ISR_INIT: return "bad ISR initialisation"; case PI_BAD_FOREVER: return "loop forever must be last command"; case PI_BAD_FILTER: return "bad filter parameter"; case PI_BAD_PAD: return "bad pad number"; case PI_BAD_STRENGTH: return "bad pad drive strength"; case PI_FIL_OPEN_FAILED: return "file open failed"; case PI_BAD_FILE_MODE: return "bad file mode"; case PI_BAD_FILE_FLAG: return "bad file flag"; case PI_BAD_FILE_READ: return "bad file read"; case PI_BAD_FILE_WRITE: return "bad file write"; case PI_FILE_NOT_ROPEN: return "file not open for read"; case PI_FILE_NOT_WOPEN: return "file not open for write"; case PI_BAD_FILE_SEEK: return "bad file seek"; case PI_NO_FILE_MATCH: return "no files match pattern"; case PI_NO_FILE_ACCESS: return "no permission to access file"; case PI_FILE_IS_A_DIR: return "file is a directory"; case PI_BAD_SHELL_STATUS: return "bad shell return status"; case PI_BAD_SCRIPT_NAME: return "bad script name"; case PI_BAD_SPI_BAUD: return "bad SPI baud rate, not 50-500k"; case PI_NOT_SPI_GPIO: return "no bit bang SPI in progress on GPIO"; case PI_BAD_EVENT_ID: return "bad event id"; case PI_CMD_INTERRUPTED: return "Used by Python"; case PI_NOT_ON_BCM2711: return "not available on BCM2711"; case PI_ONLY_ON_BCM2711: return "only available on BCM2711"; case pigif_bad_send: return "bad send"; case pigif_bad_recv: return "bad receive"; case pigif_bad_getaddrinfo: return "bad getaddrinfo"; case pigif_bad_connect: return "bad connect"; case pigif_bad_socket: return "bad socket"; case pigif_bad_noib: return "noib"; case pigif_duplicate_callback: return "duplicate callback"; case pigif_bad_malloc: return "bad malloc"; case pigif_bad_callback: return "bad callback"; case pigif_notify_failed: return "notify failed"; case pigif_callback_not_found: return "callback not found"; case pigif_unconnected_pi: return "unconnect to pi"; case pigif_too_many_pis: return "too many pis"; default: return "unknown error"; } } /** * Get the JPigpio license. * * @return license string */ public String getLicense() { String license = ""; try (InputStream is = getClass().getResourceAsStream("jpigpio_license.txt")) { if (is != null) { try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) { license = br.lines().collect(joining("\n")); } } else { license = "License not found"; } } catch (IOException ioe) { license = String.format("Error reading license: %s\n",ioe.toString()); } return license; } }
package com.knutejohnson.pi.jpigpio; /** * Class to hold all the constants used by JPigpio. This class should be * imported statically to any program using JPigpio to use them without their * full class name. * * @version 2020-12-26 * @author Knute Johnson */ public class JPigpioConstants { public static final int GPIO1 = 1; public static final int GPIO2 = 2; public static final int GPIO3 = 3; public static final int GPIO4 = 4; public static final int GPIO5 = 5; public static final int GPIO6 = 6; public static final int GPIO7 = 7; public static final int GPIO8 = 8; public static final int GPIO9 = 9; public static final int GPIO10 = 10; public static final int GPIO11 = 11; public static final int GPIO12 = 12; public static final int GPIO13 = 13; public static final int GPIO14 = 14; public static final int GPIO15 = 15; public static final int GPIO16 = 16; public static final int GPIO17 = 17; public static final int GPIO18 = 18; public static final int GPIO19 = 19; public static final int GPIO20 = 20; public static final int GPIO21 = 21; public static final int GPIO22 = 22; public static final int GPIO23 = 23; public static final int GPIO24 = 24; public static final int GPIO25 = 25; public static final int GPIO26 = 26; public static final int GPIO27 = 27; // gpio pin states public static final int PI_ON = 1; public static final int PI_OFF = 0; public static final int PI_SET = 1; public static final int PI_CLEAR = 0; public static final int PI_HIGH = 1; public static final int PI_LOW = 0; // pi commands public static final int PI_CMD_MODES = 0; public static final int PI_CMD_MODEG = 1; public static final int PI_CMD_PUD = 2; public static final int PI_CMD_READ = 3; public static final int PI_CMD_WRITE = 4; public static final int PI_CMD_PWM = 5; public static final int PI_CMD_PRS = 6; public static final int PI_CMD_PFS = 7; public static final int PI_CMD_SERVO = 8; public static final int PI_CMD_WDOG = 9; public static final int PI_CMD_BR1 = 10; public static final int PI_CMD_BR2 = 11; public static final int PI_CMD_BC1 = 12; public static final int PI_CMD_BC2 = 13; public static final int PI_CMD_BS1 = 14; public static final int PI_CMD_BS2 = 15; public static final int PI_CMD_TICK = 16; public static final int PI_CMD_HWVER = 17; public static final int PI_CMD_NO = 18; public static final int PI_CMD_NB = 19; public static final int PI_CMD_NP = 20; public static final int PI_CMD_NC = 21; public static final int PI_CMD_PRG = 22; public static final int PI_CMD_PFG = 23; public static final int PI_CMD_PRRG = 24; public static final int PI_CMD_HELP = 25; public static final int PI_CMD_PIGPV = 26; public static final int PI_CMD_WVCLR = 27; public static final int PI_CMD_WVAG = 28; public static final int PI_CMD_WVAS = 29; public static final int PI_CMD_WVGO = 30; public static final int PI_CMD_WVGOR = 31; public static final int PI_CMD_WVBSY = 32; public static final int PI_CMD_WVHLT = 33; public static final int PI_CMD_WVSM = 34; public static final int PI_CMD_WVSP = 35; public static final int PI_CMD_WVSC = 36; public static final int PI_CMD_TRIG = 37; public static final int PI_CMD_PROC = 38; public static final int PI_CMD_PROCD = 39; public static final int PI_CMD_PROCR = 40; public static final int PI_CMD_PROCS = 41; public static final int PI_CMD_SLRO = 42; public static final int PI_CMD_SLR = 43; public static final int PI_CMD_SLRC = 44; public static final int PI_CMD_PROCP = 45; public static final int PI_CMD_MICS = 46; public static final int PI_CMD_MILS = 47; public static final int PI_CMD_PARSE = 48; public static final int PI_CMD_WVCRE = 49; public static final int PI_CMD_WVDEL = 50; public static final int PI_CMD_WVTX = 51; public static final int PI_CMD_WVTXR = 52; public static final int PI_CMD_WVNEW = 53; public static final int PI_CMD_I2CO = 54; public static final int PI_CMD_I2CC = 55; public static final int PI_CMD_I2CRD = 56; public static final int PI_CMD_I2CWD = 57; public static final int PI_CMD_I2CWQ = 58; public static final int PI_CMD_I2CRS = 59; public static final int PI_CMD_I2CWS = 60; public static final int PI_CMD_I2CRB = 61; public static final int PI_CMD_I2CWB = 62; public static final int PI_CMD_I2CRW = 63; public static final int PI_CMD_I2CWW = 64; public static final int PI_CMD_I2CRK = 65; public static final int PI_CMD_I2CWK = 66; public static final int PI_CMD_I2CRI = 67; public static final int PI_CMD_I2CWI = 68; public static final int PI_CMD_I2CPC = 69; public static final int PI_CMD_I2CPK = 70; public static final int PI_CMD_SPIO = 71; public static final int PI_CMD_SPIC = 72; public static final int PI_CMD_SPIR = 73; public static final int PI_CMD_SPIW = 74; public static final int PI_CMD_SPIX = 75; public static final int PI_CMD_SERO = 76; public static final int PI_CMD_SERC = 77; public static final int PI_CMD_SERRB = 78; public static final int PI_CMD_SERWB = 79; public static final int PI_CMD_SERR = 80; public static final int PI_CMD_SERW = 81; public static final int PI_CMD_SERDA = 82; public static final int PI_CMD_GDC = 83; public static final int PI_CMD_GPW = 84; public static final int PI_CMD_HC = 85; public static final int PI_CMD_HP = 86; public static final int PI_CMD_CF1 = 87; public static final int PI_CMD_CF2 = 88; public static final int PI_CMD_BI2CC = 89; public static final int PI_CMD_BI2CO = 90; public static final int PI_CMD_BI2CZ = 91; public static final int PI_CMD_I2CZ = 92; public static final int PI_CMD_WVCHA = 93; public static final int PI_CMD_SLRI = 94; public static final int PI_CMD_CGI = 95; public static final int PI_CMD_CSI = 96; public static final int PI_CMD_FG = 97; public static final int PI_CMD_FN = 98; public static final int PI_CMD_NOIB = 99; public static final int PI_CMD_WVTXM = 100; public static final int PI_CMD_WVTAT = 101; public static final int PI_CMD_PADS = 102; public static final int PI_CMD_PADG = 103; public static final int PI_CMD_FO = 104; public static final int PI_CMD_FC = 105; public static final int PI_CMD_FR = 106; public static final int PI_CMD_FW = 107; public static final int PI_CMD_FS = 108; public static final int PI_CMD_FL = 109; public static final int PI_CMD_SHELL = 110; public static final int PI_CMD_BSPIC = 111; public static final int PI_CMD_BSPIO = 112; public static final int PI_CMD_BSPIX = 113; public static final int PI_CMD_BSCX = 114; public static final int PI_CMD_EVM = 115; public static final int PI_CMD_EVT = 116; public static final int PI_CMD_PROCU = 117; // GPIO modes public static final int PI_INPUT = 0; public static final int PI_OUTPUT = 1; public static final int PI_ALT0 = 4; public static final int PI_ALT1 = 5; public static final int PI_ALT2 = 6; public static final int PI_ALT3 = 7; public static final int PI_ALT4 = 3; public static final int PI_ALT5 = 2; // GPIO pull up/down public static final int PI_PUD_OFF = 0; public static final int PI_PUD_DOWN = 1; public static final int PI_PUD_UP = 2; // error codes public static final int PI_NO_ERROR = 0; public static final int PI_INIT_FAILED = -1; public static final int PI_BAD_USER_GPIO = -2; public static final int PI_BAD_GPIO = -3; public static final int PI_BAD_MODE = -4; public static final int PI_BAD_LEVEL = -5; public static final int PI_BAD_PUD = -6; public static final int PI_BAD_PULSEWIDTH = -7; public static final int PI_BAD_DUTYCYCLE = -8; public static final int PI_BAD_TIMER = -9; public static final int PI_BAD_MS = -10; public static final int PI_BAD_TIMETYPE = -11; public static final int PI_BAD_SECONDS = -12; public static final int PI_BAD_MICROS = -13; public static final int PI_TIMER_FAILED = -14; public static final int PI_BAD_WDOG_TIMEOUT = -15; public static final int PI_NO_ALERT_FUNC = -16; public static final int PI_BAD_CLK_PERIPH = -17; public static final int PI_BAD_CLK_SOURCE = -18; public static final int PI_BAD_CLK_MICROS = -19; public static final int PI_BAD_BUF_MILLIS = -20; public static final int PI_BAD_DUTYRANGE = -21; public static final int PI_BAD_SIGNUM = -22; public static final int PI_BAD_PATHNAME = -23; public static final int PI_NO_HANDLE = -24; public static final int PI_BAD_HANDLE = -25; public static final int PI_BAD_IF_FLAGS = -26; public static final int PI_BAD_CHANNEL = -27; // public static final int PI_BAD_PRIM_CHANNEL = -27; public static final int PI_BAD_SOCKET_PORT = -28; public static final int PI_BAD_FIFO_COMMAND = -29; public static final int PI_BAD_SECO_CHANNEL = -30; public static final int PI_NOT_INITIALISED = -31; public static final int PI_INITIALISED = -32; public static final int PI_BAD_WAVE_MODE = -33; public static final int PI_BAD_CFG_INTERNAL = -34; public static final int PI_BAD_WAVE_BAUD = -35; public static final int PI_TOO_MANY_PULSES = -36; public static final int PI_TOO_MANY_CHARS = -37; public static final int PI_NOT_SERIAL_GPIO = -38; public static final int PI_BAD_SERIAL_STRUC = -39; public static final int PI_BAD_SERIAL_BUF = -40; public static final int PI_NOT_PERMITTED = -41; public static final int PI_SOME_PERMITTED = -42; public static final int PI_BAD_WVSC_COMMND = -43; public static final int PI_BAD_WVSM_COMMND = -44; public static final int PI_BAD_WVSP_COMMND = -45; public static final int PI_BAD_PULSELEN = -46; public static final int PI_BAD_SCRIPT = -47; public static final int PI_BAD_SCRIPT_ID = -48; public static final int PI_BAD_SER_OFFSET = -49; public static final int PI_GPIO_IN_USE = -50; public static final int PI_BAD_SERIAL_COUNT = -51; public static final int PI_BAD_PARAM_NUM = -52; public static final int PI_DUP_TAG = -53; public static final int PI_TOO_MANY_TAGS = -54; public static final int PI_BAD_SCRIPT_CMD = -55; public static final int PI_BAD_VAR_NUM = -56; public static final int PI_NO_SCRIPT_ROOM = -57; public static final int PI_NO_MEMORY = -58; public static final int PI_SOCK_READ_FAILED = -59; public static final int PI_SOCK_WRIT_FAILED = -60; public static final int PI_TOO_MANY_PARAM = -61; // public static final int PI_NOT_HALTED = -62; public static final int PI_SCRIPT_NOT_READY = -62; public static final int PI_BAD_TAG = -63; public static final int PI_BAD_MICS_DELAY = -64; public static final int PI_BAD_MILS_DELAY = -65; public static final int PI_BAD_WAVE_ID = -66; public static final int PI_TOO_MANY_CBS = -67; public static final int PI_TOO_MANY_OOL = -68; public static final int PI_EMPTY_WAVEFORM = -69; public static final int PI_NO_WAVEFORM_ID = -70; public static final int PI_I2C_OPEN_FAILED = -71; public static final int PI_SER_OPEN_FAILED = -72; public static final int PI_SPI_OPEN_FAILED = -73; public static final int PI_BAD_I2C_BUS = -74; public static final int PI_BAD_I2C_ADDR = -75; public static final int PI_BAD_SPI_CHANNEL = -76; public static final int PI_BAD_FLAGS = -77; public static final int PI_BAD_SPI_SPEED = -78; public static final int PI_BAD_SER_DEVICE = -79; public static final int PI_BAD_SER_SPEED = -80; public static final int PI_BAD_PARAM = -81; public static final int PI_I2C_WRITE_FAILED = -82; public static final int PI_I2C_READ_FAILED = -83; public static final int PI_BAD_SPI_COUNT = -84; public static final int PI_SER_WRITE_FAILED = -85; public static final int PI_SER_READ_FAILED = -86; public static final int PI_SER_READ_NO_DATA = -87; public static final int PI_UNKNOWN_COMMAND = -88; public static final int PI_SPI_XFER_FAILED = -89; public static final int PI_BAD_POINTER = -90; public static final int PI_NO_AUX_SPI = -91; public static final int PI_NOT_PWM_GPIO = -92; public static final int PI_NOT_SERVO_GPIO = -93; public static final int PI_NOT_HCLK_GPIO = -94; public static final int PI_NOT_HPWM_GPIO = -95; public static final int PI_BAD_HPWM_FREQ = -96; public static final int PI_BAD_HPWM_DUTY = -97; public static final int PI_BAD_HCLK_FREQ = -98; public static final int PI_BAD_HCLK_PASS = -99; public static final int PI_HPWM_ILLEGAL = -100; public static final int PI_BAD_DATABITS = -101; public static final int PI_BAD_STOPBITS = -102; public static final int PI_MSG_TOOBIG = -103; public static final int PI_BAD_MALLOC_MODE = -104; public static final int PI_TOO_MANY_SEGS = -105; public static final int PI_BAD_I2C_SEG = -106; public static final int PI_BAD_SMBUS_CMD = -107; public static final int PI_NOT_I2C_GPIO = -108; public static final int PI_BAD_I2C_WLEN = -109; public static final int PI_BAD_I2C_RLEN = -110; public static final int PI_BAD_I2C_CMD = -111; public static final int PI_BAD_I2C_BAUD = -112; public static final int PI_CHAIN_LOOP_CNT = -113; public static final int PI_BAD_CHAIN_LOOP = -114; public static final int PI_CHAIN_COUNTER = -115; public static final int PI_BAD_CHAIN_CMD = -116; public static final int PI_BAD_CHAIN_DELAY = -117; public static final int PI_CHAIN_NESTING = -118; public static final int PI_CHAIN_TOO_BIG = -119; public static final int PI_DEPRECATED = -120; public static final int PI_BAD_SER_INVERT = -121; public static final int PI_BAD_EDGE = -122; public static final int PI_BAD_ISR_INIT = -123; public static final int PI_BAD_FOREVER = -124; public static final int PI_BAD_FILTER = -125; public static final int PI_BAD_PAD = -126; public static final int PI_BAD_STRENGTH = -127; public static final int PI_FIL_OPEN_FAILED = -128; public static final int PI_BAD_FILE_MODE = -129; public static final int PI_BAD_FILE_FLAG = -130; public static final int PI_BAD_FILE_READ = -131; public static final int PI_BAD_FILE_WRITE = -132; public static final int PI_FILE_NOT_ROPEN = -133; public static final int PI_FILE_NOT_WOPEN = -134; public static final int PI_BAD_FILE_SEEK = -135; public static final int PI_NO_FILE_MATCH = -136; public static final int PI_NO_FILE_ACCESS = -137; public static final int PI_FILE_IS_A_DIR = -138; public static final int PI_BAD_SHELL_STATUS = -139; public static final int PI_BAD_SCRIPT_NAME = -140; public static final int PI_BAD_SPI_BAUD = -141; public static final int PI_NOT_SPI_GPIO = -142; public static final int PI_BAD_EVENT_ID = -143; public static final int PI_CMD_INTERRUPTED = -144; public static final int PI_NOT_ON_BCM2711 = -145; public static final int PI_ONLY_ON_BCM2711 = -146; public static final int pigif_bad_send = -2000; public static final int pigif_bad_recv = -2001; public static final int pigif_bad_getaddrinfo = -2002; public static final int pigif_bad_connect = -2003; public static final int pigif_bad_socket = -2004; public static final int pigif_bad_noib = -2005; public static final int pigif_duplicate_callback = -2006; public static final int pigif_bad_malloc = -2007; public static final int pigif_bad_callback = -2008; public static final int pigif_notify_failed = -2009; public static final int pigif_callback_not_found = -2010; public static final int pigif_unconnected_pi = -2011; public static final int pigif_too_many_pis = -2012; }
package com.knutejohnson.pi.jpigpio; /** * Class to hold data returned from a notify action. * * @version 2021-01-22 * @author Knute Johnson */ public class GPIOReport { /** Sequence number */ public int seqno; /** Flags */ public int flags; /** Time of the event in ticks/microseconds of boot */ public long tick; /** Level of the GPIO pin that triggered the notification */ public long level; /** * Create a new GPIOReport object. * * @param seqno sequence number * @param flags flags * @param tick tick count * @param level GPIO pin level */ public GPIOReport(int seqno, int flags, long tick, long level) { this.seqno = seqno; this.flags = flags; this.tick = tick; this.level = level; } /** * Create a String representation of the GPIOReport * * @return String containing fields of report */ public String toString() { return String.format("seqno: %d - flags: %s - tick: %d - level: %s", seqno,Integer.toUnsignedString(flags,2),tick, Long.toUnsignedString(level,2)); } }