Tue, 26 Aug 2008 12:45:33 +0100
initial commit
Makefile | file | annotate | diff | revisions | |
include/liblpfk.h | file | annotate | diff | revisions | |
src/liblpfk.c | file | annotate | diff | revisions | |
test/lpfktest.c | file | annotate | diff | revisions |
1.1 diff -r 000000000000 -r 745037d69d81 Makefile 1.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 +++ b/Makefile Tue Aug 26 12:45:33 2008 +0100 1.4 @@ -0,0 +1,19 @@ 1.5 +CFLAGS=-fPIC -g -I./include 1.6 +SONAME=liblpfk.so.1 1.7 + 1.8 +.PHONY: all clean 1.9 + 1.10 +all: liblpfk.so lpfktest 1.11 + ldconfig -n . 1.12 + 1.13 +clean: 1.14 + -rm -f lpfktest 1.15 + -rm -f liblpfk.so* 1.16 + -rm -f src/*.o 1.17 + -rm -f test/*.o 1.18 + 1.19 +liblpfk.so: src/liblpfk.o 1.20 + $(CC) -shared -Wl,-soname,$(SONAME) -o $@ $< 1.21 + 1.22 +lpfktest: test/lpfktest.o 1.23 + $(CC) -o $@ $< -L. -llpfk
2.1 diff -r 000000000000 -r 745037d69d81 include/liblpfk.h 2.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 +++ b/include/liblpfk.h Tue Aug 26 12:45:33 2008 +0100 2.4 @@ -0,0 +1,135 @@ 2.5 +/**************************************************************************** 2.6 + * Project: liblpfk 2.7 + * Purpose: Driver library for the IBM 6094-020 Lighted Program Function 2.8 + * Keyboard. 2.9 + * Version: 1.0 2.10 + * Author: Philip Pemberton <philpem@philpem.me.uk> 2.11 + * 2.12 + * The latest version of this library is available from 2.13 + * <http://www.philpem.me.uk/code/liblpfk/>. 2.14 + * 2.15 + * Copyright (c) 2008, Philip Pemberton 2.16 + * All rights reserved. 2.17 + * 2.18 + * Redistribution and use in source and binary forms, with or without 2.19 + * modification, are permitted provided that the following conditions 2.20 + * are met: 2.21 + * 2.22 + * * Redistributions of source code must retain the above copyright 2.23 + * notice, this list of conditions and the following disclaimer. 2.24 + * * Redistributions in binary form must reproduce the above copyright 2.25 + * notice, this list of conditions and the following disclaimer in 2.26 + * the documentation and/or other materials provided with the 2.27 + * distribution. 2.28 + * * Neither the name of the project nor the names of its 2.29 + * contributors may be used to endorse or promote products derived 2.30 + * from this software without specific prior written permission. 2.31 + * 2.32 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2.33 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2.34 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 2.35 + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 2.36 + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2.37 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2.38 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 2.39 + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 2.40 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 2.41 + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 2.42 + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2.43 + ****************************************************************************/ 2.44 + 2.45 +/** 2.46 + * @file liblpfk.h 2.47 + * @brief liblpfk library header 2.48 + */ 2.49 + 2.50 +#ifndef _liblpfk_h_included 2.51 +#define _liblpfk_h_included 2.52 + 2.53 +#include <termios.h> 2.54 + 2.55 +/** 2.56 + * @brief LPFK context 2.57 + * 2.58 + * Do not change any variables inside this struct, they are for liblpfk's 2.59 + * internal use only. 2.60 + */ 2.61 +typedef struct { 2.62 + int fd; ///< serial port file descriptor 2.63 + struct termios oldtio; ///< old termios setup 2.64 + int enabled; ///< LPFK enabled 2.65 + unsigned long led_mask; ///< lit LEDs mask 2.66 +} LPFK_CTX; 2.67 + 2.68 +/** 2.69 + * @brief liblpfk error codes 2.70 + */ 2.71 +enum { 2.72 + LPFK_E_OK = 0, ///< No error, success. 2.73 + LPFK_E_PORT_OPEN, ///< Could not open comm port. 2.74 + LPFK_E_NOT_PRESENT, ///< LPFK not present on specified port. 2.75 + LPFK_E_COMMS, ///< Communication error. 2.76 + LPFK_E_PARAM ///< Invalid function parameter. 2.77 +}; 2.78 + 2.79 +/** 2.80 + * @brief Open a serial port and attempt to connecct to an LPFK on that 2.81 + * port. 2.82 + * @param port Serial port path (e.g. /dev/ttyS0). 2.83 + * @param ctx Pointer to an LPFK_CTX struct where LPFK context will be 2.84 + * stored. 2.85 + * @return LPFK_E_OK on success, LPFK_E_PORT_OPEN if port could not be 2.86 + * opened, LPFK_E_NOT_PRESENT if no LPFK present on specified port. 2.87 + */ 2.88 +int lpfk_open(const char *port, LPFK_CTX *ctx); 2.89 + 2.90 +/** 2.91 + * @brief Close the LPFK. 2.92 + * @param ctx Pointer to an LPFK_CTX struct initialised by lpfk_open(). 2.93 + * @return LPFK_E_OK 2.94 + */ 2.95 +int lpfk_close(LPFK_CTX *ctx); 2.96 + 2.97 +/** 2.98 + * @brief Enable or disable LPFK input 2.99 + * @param ctx Pointer to an LPFK_CTX struct initialised by lpfk_open(). 2.100 + * @param val true to enable the LPFK's keys, false to disable. 2.101 + * @return LPFK_E_OK on success, LPFK_E_COMMS on comms error. 2.102 + */ 2.103 +int lpfk_enable(LPFK_CTX *ctx, int val); 2.104 + 2.105 +/** 2.106 + * @brief Set or clear an LED on the LPFK. 2.107 + * @param ctx Pointer to an LPFK_CTX struct initialised by lpfk_open(). 2.108 + * @param num LED/key number, from 0 to 31. 2.109 + * @param state State, true for on, false for off. 2.110 + * @return LPFK_E_OK on success, LPFK_E_PARAM on bad parameter, LPFK_E_COMMS 2.111 + * on comms error. 2.112 + */ 2.113 +int lpfk_set_led(LPFK_CTX *ctx, const int num, const int state); 2.114 + 2.115 +/** 2.116 + * @brief Set or clear all the LEDs on the LPFK. 2.117 + * @param ctx Pointer to an LPFK_CTX struct initialised by lpfk_open(). 2.118 + * @param state State, true for on, false for off. 2.119 + * @return LPFK_E_OK on success, LPFK_E_PARAM on bad parameter, LPFK_E_COMMS 2.120 + * on comms error. 2.121 + */ 2.122 +int lpfk_set_leds(LPFK_CTX *ctx, const int state); 2.123 + 2.124 +/** 2.125 + * @brief Get the status of an LED on the LPFK. 2.126 + * @param ctx Pointer to an LPFK_CTX struct initialised by lpfk_open(). 2.127 + * @param num LED/key number, from 0 to 31. 2.128 + * @return true if LED is on, false otherwise. 2.129 + */ 2.130 +int lpfk_get_led(LPFK_CTX *ctx, const int num); 2.131 + 2.132 +/** 2.133 + * @brief Read a key from the LPFK 2.134 + * @param ctx Pointer to an LPFK_CTX struct initialised by lpfk_open(). 2.135 + * @return -1 if no keys in buffer, 0-31 for key 1-32 down. 2.136 + */ 2.137 +int lpfk_read(LPFK_CTX *ctx); 2.138 + 2.139 +#endif // _liblpfk_h_included
3.1 diff -r 000000000000 -r 745037d69d81 src/liblpfk.c 3.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 +++ b/src/liblpfk.c Tue Aug 26 12:45:33 2008 +0100 3.4 @@ -0,0 +1,399 @@ 3.5 +/**************************************************************************** 3.6 + * Project: liblpfk 3.7 + * Purpose: Driver library for the IBM 6094-020 Lighted Program Function 3.8 + * Keyboard. 3.9 + * Version: 1.0 3.10 + * Author: Philip Pemberton <philpem@philpem.me.uk> 3.11 + * 3.12 + * The latest version of this library is available from 3.13 + * <http://www.philpem.me.uk/code/liblpfk/>. 3.14 + * 3.15 + * Copyright (c) 2008, Philip Pemberton 3.16 + * All rights reserved. 3.17 + * 3.18 + * Redistribution and use in source and binary forms, with or without 3.19 + * modification, are permitted provided that the following conditions 3.20 + * are met: 3.21 + * 3.22 + * * Redistributions of source code must retain the above copyright 3.23 + * notice, this list of conditions and the following disclaimer. 3.24 + * * Redistributions in binary form must reproduce the above copyright 3.25 + * notice, this list of conditions and the following disclaimer in 3.26 + * the documentation and/or other materials provided with the 3.27 + * distribution. 3.28 + * * Neither the name of the project nor the names of its 3.29 + * contributors may be used to endorse or promote products derived 3.30 + * from this software without specific prior written permission. 3.31 + * 3.32 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3.33 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3.34 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 3.35 + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 3.36 + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 3.37 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 3.38 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 3.39 + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 3.40 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 3.41 + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 3.42 + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3.43 + ****************************************************************************/ 3.44 + 3.45 +/** 3.46 + * @file liblpfk.c 3.47 + * @brief liblpfk library, main source 3.48 + */ 3.49 + 3.50 +#include <sys/types.h> 3.51 +#include <sys/stat.h> 3.52 +#include <fcntl.h> 3.53 +#include <unistd.h> 3.54 +#include <termios.h> 3.55 +#include <sys/ioctl.h> 3.56 +#include <time.h> 3.57 +#include <string.h> 3.58 +#include <stdbool.h> 3.59 +#include <stdio.h> 3.60 + 3.61 +#include "liblpfk.h" 3.62 + 3.63 +int lpfk_open(const char *port, LPFK_CTX *ctx) 3.64 +{ 3.65 + struct termios newtio; 3.66 + int status; 3.67 + int fd; 3.68 + int i; 3.69 + 3.70 + // open the serial port 3.71 + fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY); 3.72 + if (fd < 0) return LPFK_E_PORT_OPEN; 3.73 + 3.74 + // save current port settings 3.75 + tcgetattr(fd, &ctx->oldtio); 3.76 + 3.77 + // set up new parameters 3.78 + memset(&newtio, 0, sizeof(newtio)); 3.79 + // 9600 baud, 8 bits, parity enabled, odd parity 3.80 + newtio.c_cflag = B9600 | CS8 | PARENB | PARODD | CLOCAL | CREAD; 3.81 + newtio.c_iflag = 0; 3.82 + newtio.c_oflag = 0; 3.83 + 3.84 + // set input mode -- non canonical, no echo 3.85 + newtio.c_lflag = 0; 3.86 + 3.87 + // inter-character timer unused 3.88 + newtio.c_cc[VTIME] = 0; 3.89 + // read does not block waiting for characters if there are none in the buffer 3.90 + newtio.c_cc[VMIN] = 0; 3.91 + 3.92 + // flush input buffer 3.93 + tcflush(fd, TCIFLUSH); 3.94 + 3.95 + // set new port config 3.96 + tcsetattr(fd, TCSANOW, &newtio); 3.97 + 3.98 + // set RTS true to pull the LPFK out of reset 3.99 + ioctl(fd, TIOCMGET, &status); 3.100 + status |= TIOCM_RTS; 3.101 + ioctl(fd, TIOCMSET, &status); 3.102 + 3.103 + // wait a few seconds for the LPFK to become ready 3.104 + sleep(2); 3.105 + 3.106 + // 0x06: READ CONFIGURATION. LPFK sends 0x03 in response. 3.107 + // Try five times to wake it up. 3.108 + status = false; 3.109 + for (i=0; i<5; i++) { 3.110 + unsigned char buf; 3.111 + time_t tm; 3.112 + 3.113 + // Send 0x06: READ CONFIGURATION, loop on failure 3.114 + if (write(fd, "\x06", 1) < 1) { 3.115 + continue; 3.116 + } 3.117 + 3.118 + // save current time (in seconds) 3.119 + tm = time(NULL); 3.120 + 3.121 + // loop until 2 seconds have passed, or LPFK responds 3.122 + status = false; 3.123 + do { 3.124 + // read data, loop if not successful 3.125 + if (read(fd, &buf, 1) < 1) { 3.126 + continue; 3.127 + } 3.128 + 3.129 + // we got some data, what is it? 3.130 + if (buf == 0x03) { 3.131 + // 0x03 -- correct response. we're done. 3.132 + status = true; 3.133 + } 3.134 + } while (((time(NULL) - tm) < 2) && (!status)); 3.135 + 3.136 + // exit loop if we got the LPFK to talk 3.137 + if (status) { 3.138 + break; 3.139 + } 3.140 + } 3.141 + 3.142 + // Did the LPFK respond? 3.143 + if (!status) { 3.144 + // LPFK isn't talking. Restore serial port state and exit. 3.145 + tcsetattr(fd, TCSANOW, &ctx->oldtio); 3.146 + close(fd); 3.147 + 3.148 + return LPFK_E_NOT_PRESENT; 3.149 + } else { 3.150 + // Initialise LPFK context 3.151 + ctx->led_mask = 0; 3.152 + ctx->fd = fd; 3.153 + 3.154 + // Enable the LPFK 3.155 + write(fd, "\x08", 1); 3.156 + ctx->enabled = true; 3.157 + 3.158 + // Return OK status 3.159 + return LPFK_E_OK; 3.160 + } 3.161 +} 3.162 + 3.163 +int lpfk_close(LPFK_CTX *ctx) 3.164 +{ 3.165 + int status; 3.166 + 3.167 + // 0x09: DISABLE. Stop the LPFK responding to keystrokes. 3.168 + write(ctx->fd, "\x09", 1); 3.169 + 3.170 + // turn all the LEDs off 3.171 + lpfk_set_leds(ctx, false); 3.172 + 3.173 + // set RTS false to put the LPFK into reset 3.174 + ioctl(ctx->fd, TIOCMGET, &status); 3.175 + status &= ~TIOCM_RTS; 3.176 + ioctl(ctx->fd, TIOCMSET, &status); 3.177 + 3.178 + // Restore the port state and close the serial port. 3.179 + tcsetattr(ctx->fd, TCSANOW, &ctx->oldtio); 3.180 + close(ctx->fd); 3.181 + 3.182 + // Done! 3.183 + return LPFK_E_OK; 3.184 +} 3.185 + 3.186 +int lpfk_enable(LPFK_CTX *ctx, int val) 3.187 +{ 3.188 + if (val) { 3.189 + // val == true, enable the LPFK 3.190 + if (write(ctx->fd, "\x08", 1) != 1) { 3.191 + ctx->enabled = true; 3.192 + return LPFK_E_COMMS; 3.193 + } 3.194 + } else { 3.195 + // val == false, disable the LPFK 3.196 + if (write(ctx->fd, "\x09", 1) != 1) { 3.197 + return LPFK_E_COMMS; 3.198 + } 3.199 + } 3.200 + 3.201 + // update the context, return success 3.202 + ctx->enabled = val; 3.203 + return LPFK_E_OK; 3.204 +} 3.205 + 3.206 +/** 3.207 + * @brief Set or clear an LED on the LPFK. 3.208 + * @param ctx Pointer to an LPFK_CTX struct initialised by lpfk_open(). 3.209 + * @param num LED/key number, from 0 to 31. 3.210 + * @param state State, true for on, false for off. 3.211 + * @return LPFK_E_OK on success, LPFK_E_PARAM on bad parameter, LPFK_E_COMMS 3.212 + * on comms error. 3.213 + */ 3.214 +int lpfk_set_led(LPFK_CTX *ctx, const int num, const int state) 3.215 +{ 3.216 + int i; 3.217 + time_t tm; 3.218 + unsigned long mask, leds; 3.219 + unsigned char buf[5]; 3.220 + unsigned char status; 3.221 + 3.222 + // check parameters 3.223 + if ((num < 0) || (num > 31)) { 3.224 + return LPFK_E_PARAM; 3.225 + } 3.226 + 3.227 + // parameters OK, now build the LED mask 3.228 + mask = (0x80 >> (num % 8)) << ((num / 8) * 8); 3.229 + 3.230 + leds = ctx->led_mask; 3.231 + 3.232 + // mask the specified bit 3.233 + if (state) { 3.234 + leds |= mask; 3.235 + } else { 3.236 + leds &= ~mask; 3.237 + } 3.238 + 3.239 + // send new LED mask to the LPFK 3.240 + buf[0] = 0x94; 3.241 + buf[1] = leds & 0xff; 3.242 + buf[2] = leds >> 8; 3.243 + buf[3] = leds >> 16; 3.244 + buf[4] = leds >> 24; 3.245 + 3.246 + // make 5 attempts to set the LEDs 3.247 + for (i=0; i<5; i++) { 3.248 + if (write(ctx->fd, &buf, 5) < 5) { 3.249 + continue; 3.250 + } 3.251 + 3.252 + // check for response -- 0x81 = OK, 0x80 = retransmit 3.253 + // save current time (in seconds) 3.254 + tm = time(NULL); 3.255 + 3.256 + // loop until 2 seconds have passed, or LPFK responds 3.257 + status = 0x00; 3.258 + do { 3.259 + // read data, loop if not successful 3.260 + if (read(ctx->fd, &status, 1) < 1) { 3.261 + continue; 3.262 + } 3.263 + 3.264 + // we got some data, what is it? 3.265 + if (status == 0x81) { 3.266 + // 0x81 -- received successfully 3.267 + break; 3.268 + } 3.269 + } while ((time(NULL) - tm) < 2); 3.270 + 3.271 + // status OK? 3.272 + if (status == 0x81) { 3.273 + // 0x81: OK 3.274 + break; 3.275 + } else if (status == 0x80) { 3.276 + // 0x80: Retransmit request 3.277 + continue; 3.278 + } 3.279 + } 3.280 + 3.281 + // update the context 3.282 + ctx->led_mask = leds; 3.283 + 3.284 + return LPFK_E_OK; 3.285 +} 3.286 + 3.287 +/** 3.288 + * @brief Set or clear all the LEDs on the LPFK. 3.289 + * @param ctx Pointer to an LPFK_CTX struct initialised by lpfk_open(). 3.290 + * @param state State, true for on, false for off. 3.291 + * @return LPFK_E_OK on success, LPFK_E_PARAM on bad parameter, LPFK_E_COMMS 3.292 + * on comms error. 3.293 + */ 3.294 +int lpfk_set_leds(LPFK_CTX *ctx, const int state) 3.295 +{ 3.296 + int i; 3.297 + time_t tm; 3.298 + unsigned long leds; 3.299 + unsigned char buf[5]; 3.300 + unsigned char status; 3.301 + 3.302 + if (state) { 3.303 + // all LEDs on 3.304 + leds = 0xFFFFFFFF; 3.305 + } else { 3.306 + // all LEDs off 3.307 + leds = 0x00000000; 3.308 + } 3.309 + 3.310 + // send new LED mask to the LPFK 3.311 + buf[0] = 0x94; 3.312 + buf[1] = leds & 0xff; 3.313 + buf[2] = leds >> 8; 3.314 + buf[3] = leds >> 16; 3.315 + buf[4] = leds >> 24; 3.316 + 3.317 + // make 5 attempts to set the LEDs 3.318 + for (i=0; i<5; i++) { 3.319 + if (write(ctx->fd, &buf, 5) < 5) { 3.320 + continue; 3.321 + } 3.322 + 3.323 + // check for response -- 0x81 = OK, 0x80 = retransmit 3.324 + // save current time (in seconds) 3.325 + tm = time(NULL); 3.326 + 3.327 + // loop until 2 seconds have passed, or LPFK responds 3.328 + status = 0x00; 3.329 + do { 3.330 + // read data, loop if not successful 3.331 + if (read(ctx->fd, &status, 1) < 1) { 3.332 + continue; 3.333 + } 3.334 + 3.335 + // we got some data, what is it? 3.336 + if (status == 0x81) { 3.337 + // 0x81 -- received successfully 3.338 + break; 3.339 + } 3.340 + } while ((time(NULL) - tm) < 2); 3.341 + 3.342 + // status OK? 3.343 + if (status == 0x81) { 3.344 + // 0x81: OK 3.345 + break; 3.346 + } else if (status == 0x80) { 3.347 + // 0x80: Retransmit request 3.348 + continue; 3.349 + } 3.350 + } 3.351 + 3.352 + // update the context 3.353 + ctx->led_mask = leds; 3.354 + 3.355 + return LPFK_E_OK; 3.356 +} 3.357 + 3.358 +/** 3.359 + * @brief Get the status of an LED on the LPFK. 3.360 + * @param ctx Pointer to an LPFK_CTX struct initialised by lpfk_open(). 3.361 + * @param num LED/key number, from 0 to 31. 3.362 + * @return true if LED is on, false otherwise. 3.363 + */ 3.364 +int lpfk_get_led(LPFK_CTX *ctx, const int num) 3.365 +{ 3.366 + unsigned long mask; 3.367 + 3.368 + // check parameters 3.369 + if ((num < 0) || (num > 31)) { 3.370 + return false; 3.371 + } 3.372 + 3.373 + // parameters OK, now build the LED mask 3.374 + mask = (0x80 >> (num % 8)) << ((num / 8) * 8); 3.375 + if (ctx->led_mask & mask) { 3.376 + return true; 3.377 + } else { 3.378 + return false; 3.379 + } 3.380 +} 3.381 + 3.382 +/** 3.383 + * @brief Read a key from the LPFK 3.384 + * @param ctx Pointer to an LPFK_CTX struct initialised by lpfk_open(). 3.385 + * @return -1 if no keys in buffer, 0-31 for key 1-32 down. 3.386 + */ 3.387 +int lpfk_read(LPFK_CTX *ctx) 3.388 +{ 3.389 + int nbytes; 3.390 + unsigned char key; 3.391 + 3.392 + // try and read a byte (keycode) from the LPFK 3.393 + nbytes = read(ctx->fd, &key, 1); 3.394 + 3.395 + if ((nbytes < 1) || (key > 31)) { 3.396 + // no keys buffered, or keycode invalid. 3.397 + return -1; 3.398 + } else { 3.399 + // key buffered, pass it along. 3.400 + return key; 3.401 + } 3.402 +} 3.403 +
4.1 diff -r 000000000000 -r 745037d69d81 test/lpfktest.c 4.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 +++ b/test/lpfktest.c Tue Aug 26 12:45:33 2008 +0100 4.4 @@ -0,0 +1,63 @@ 4.5 +#include <stdio.h> 4.6 +#include <stdbool.h> 4.7 +#include <time.h> 4.8 +#include "liblpfk.h" 4.9 + 4.10 +int main(int argc, char **argv) 4.11 +{ 4.12 + LPFK_CTX ctx; 4.13 + int i; 4.14 + time_t tm; 4.15 + 4.16 + if (argc < 2) { 4.17 + printf("Syntax: %s commport\n", argv[0]); 4.18 + return -1; 4.19 + } 4.20 + 4.21 + if ((i = lpfk_open(argv[1], &ctx)) != LPFK_E_OK) { 4.22 + switch(i) { 4.23 + case LPFK_E_PORT_OPEN: 4.24 + printf("Error opening comm port.\n"); 4.25 + break; 4.26 + case LPFK_E_NOT_PRESENT: 4.27 + printf("LPFK not connected to specified port.\n"); 4.28 + break; 4.29 + case LPFK_E_COMMS: 4.30 + printf("LPFK communications error.\n"); 4.31 + break; 4.32 + } 4.33 + return -2; 4.34 + } 4.35 + 4.36 +// printf("disable: %d\n", lpfk_enable(&ctx, false)); 4.37 +// printf("enable : %d\n", lpfk_enable(&ctx, true)); 4.38 + 4.39 + printf("Scanning LEDs, 1-32...\n"); 4.40 + 4.41 + for (i=0; i<32; i++) { 4.42 + if (i>0) { 4.43 + lpfk_set_led(&ctx, i-1, false); 4.44 + } 4.45 + lpfk_set_led(&ctx, i, true); 4.46 + usleep(100000); 4.47 + } 4.48 + 4.49 + // Turn LEDs off 4.50 + lpfk_set_leds(&ctx, false); 4.51 + 4.52 + printf("Now press the keys on the LPFK...\n"); 4.53 + 4.54 + // scan keys for 5 seconds 4.55 + tm = time(NULL); 4.56 + do { 4.57 + // read keys 4.58 + if ((i = lpfk_read(&ctx)) >= 0) { 4.59 + // key buffered, toggle the LED 4.60 + printf("Key down: #%d\n", i); 4.61 + lpfk_set_led(&ctx, i, !lpfk_get_led(&ctx, i)); 4.62 + } 4.63 + } while ((time(NULL) - tm) < 30); 4.64 + 4.65 + lpfk_close(&ctx); 4.66 +} 4.67 +