13 Dec 15:35
machctl: r15 - sys
Author: vedge
Date: 2008-12-13 10:35:20 -0400 (Sat, 13 Dec 2008)
New Revision: 15
Modified:
sys/patch-OpenBSD_4.0
Log:
remove new files from patch
Modified: sys/patch-OpenBSD_4.0
===================================================================
--- sys/patch-OpenBSD_4.0 2008-03-25 09:55:16 UTC (rev 14)
+++ sys/patch-OpenBSD_4.0 2008-12-13 14:35:20 UTC (rev 15)
<at> <at> -60,2439 +60,6 <at> <at>
# clonable devices
pseudo-device bpfilter # packet filter
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc.c sys/dev/cnc/cnc.c
---- sys.ORIG/dev/cnc/cnc.c Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc.c Fri Jun 8 07:00:53 2007
- <at> <at> -0,0 +1,597 <at> <at>
-+/* $OpenBSD$ */
-+
-+/*
-+ * Copyright (c) 2007 Hypertriton, Inc. <http://www.hypertriton.com/>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * Real-time control interface for CNC machinery and robots.
-+ */
-+
-+#include <sys/param.h>
-+#include <sys/queue.h>
-+#include <sys/ioctl.h>
-+#include <sys/fcntl.h>
-+#include <sys/vnode.h>
-+#include <sys/systm.h>
-+#include <sys/kernel.h>
-+#include <sys/device.h>
-+#include <sys/pool.h>
-+#include <sys/conf.h>
-+#include <sys/lock.h>
-+
-+#include <sys/gpio.h>
-+#include <sys/cnc.h>
-+
-+#include <dev/gpio/gpiovar.h>
-+
-+#include "cnc_devicevar.h"
-+#include "cnc_servovar.h"
-+#include "cnc_estopvar.h"
-+#include "cnc_spindlevar.h"
-+#include "cncvar.h"
-+
-+#define STEPMAX (INT64_MAX-1)
-+#define STEPLEN 20336 /* 20336 units = 1 step */
-+#define MAXSTEPS (STEPMAX/STEPLEN)
-+
-+cnc_real_t cnc_Vmax = 2000.0; /* maximum velocity (steps/sec) */
-+u_long cnc_timebase = 0; /* delay loop calibration */
-+
-+const char *cnc_insn_names[] = {
-+ "MOVE",
-+ "SET_INTERP",
-+ "SPINDLE_DIR",
-+ "SPINDLE_SPEED",
-+ "SPINDLE_START",
-+ "SPINDLE_STOP",
-+ "ATC_PREPARE",
-+ "ATC_CHANGE",
-+ "LASER_ON",
-+ "LASER_OFF",
-+ "LASER_CURRENT",
-+ "PICKPLACE_REEL",
-+ "PICKPLACE_SUCTION",
-+ "PICKPLACE_RELEASE",
-+ "PREEMPT",
-+ "DWELL",
-+ "COOL_MIST",
-+ "COOL_FLOOD",
-+ "COOL_VORTEX"
-+};
-+
-+struct pool cnc_insnpl;
-+int cnc_opened;
-+TAILQ_HEAD(,cnc_insn) cnc_prog;
-+struct cnc_vector cnc_pos;
-+struct cnc_device *cnc_servos[CNC_NAXES];
-+struct cnc_device *cnc_spindles[CNC_MAX_SPINDLES];
-+struct cnc_device *cnc_estops[CNC_MAX_ESTOPS];
-+struct cnc_device *cnc_estop;
-+int cnc_nservos = 0;
-+int cnc_nspindles = 0;
-+int cnc_nestops = 0;
-+
-+void
-+cncattach(int num)
-+{
-+ int i;
-+
-+ if (num > 1)
-+ return;
-+
-+ printf("cnc: STEPLEN=%u, Vmax = %d steps/s\n",
-+ (u_int)STEPLEN, (int)cnc_Vmax);
-+ cnc_opened = 0;
-+ pool_init(&cnc_insnpl, sizeof(struct cnc_insn), 0, 0, 0, "cncinsnpl",
-+ NULL);
-+ pool_setlowat(&cnc_insnpl, 1024);
-+ TAILQ_INIT(&cnc_prog);
-+
-+ for (i = 0; i < CNC_NAXES; i++)
-+ cnc_pos.v[i] = 0;
-+}
-+
-+int
-+cncdetach(struct device *self, int flags)
-+{
-+ cnc_prog_reset();
-+ return (0);
-+}
-+
-+int
-+cncactivate(struct device *self, enum devact a)
-+{
-+ return (0);
-+}
-+
-+int
-+cncopen(dev_t dev, int flag, int mode, struct proc *p)
-+{
-+ if (cnc_opened) {
-+ return (EBUSY);
-+ }
-+ cnc_opened = 1;
-+ return (0);
-+}
-+
-+int
-+cncclose(dev_t dev, int flag, int mode, struct proc *p)
-+{
-+ cnc_prog_reset();
-+ cnc_opened = 0;
-+ return (0);
-+}
-+
-+struct cnc_device *
-+cnc_get_spindle(int id)
-+{
-+ if (id < 0 || id >= cnc_nspindles) {
-+ return (NULL);
-+ }
-+ return (cnc_spindles[id]);
-+}
-+
-+int
-+cncwrite(dev_t dev, struct uio *uio, int ioflag)
-+{
-+ const char *cause;
-+ struct cnc_insn insn, *iNew;
-+ u_int ip = 0;
-+ void *p;
-+
-+ while (uio->uio_resid > 0) {
-+ int rv;
-+
-+ rv = uiomove(&insn, sizeof(struct cnc_insn), uio);
-+ if (rv != 0) {
-+ printf("cncwrite: uiomove: %d\n", rv);
-+ return (EIO);
-+ }
-+ if (insn.i_type < 0 || insn.i_type >= CNC_LAST_INSN) {
-+ printf("cncwrite: bad insn %d\n", insn.i_type);
-+ return (ENODEV);
-+ }
-+ /*
-+ * We do the best we can to validate the program
-+ * before it is executed.
-+ */
-+ switch (insn.i_type) {
-+ case CNC_MOVE:
-+ if (cnc_vec_distance(&cnc_pos, &insn.i_pos) == 0) {
-+ cause = "L=0";
-+ goto fail;
-+ }
-+ if (insn.i_Amax == 0) { cause = "Amax=0"; goto fail; }
-+ if (insn.i_Jmax == 0) { cause = "Jmax=0"; goto fail; }
-+ break;
-+ case CNC_SET_INTERP:
-+ if (insn.i_interp_mode < 0 ||
-+ insn.i_interp_mode >= CNC_INTERP_LAST) {
-+ cause = "bad interpolation mode";
-+ goto fail;
-+ }
-+ break;
-+ case CNC_SPINDLE_DIR:
-+ if (cnc_get_spindle(insn.i_spindle_id) == NULL) {
-+ cause = "no such spindle";
-+ goto fail;
-+ }
-+ if (insn.i_spindle_dir != -1 &&
-+ insn.i_spindle_dir != 1) {
-+ cause = "bad direction";
-+ goto fail;
-+ }
-+ break;
-+ case CNC_SPINDLE_SPEED:
-+ if ((p = cnc_get_spindle(insn.i_spindle_id)) == NULL) {
-+ cause = "no such spindle";
-+ goto fail;
-+ } else {
-+ struct spindle_softc *sc = p;
-+
-+ if (insn.i_spindle_speed > sc->sc_speed_max) {
-+ cause = "speed exceeds spindle limit";
-+ goto fail;
-+ }
-+ }
-+ break;
-+ case CNC_SPINDLE_START:
-+ case CNC_SPINDLE_STOP:
-+ if ((p = cnc_get_spindle(insn.i_spindle_id)) == NULL) {
-+ cause = "no such spindle";
-+ goto fail;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+ if ((iNew = pool_get(&cnc_insnpl, 0)) == NULL) {
-+ cause = "out of memory for instruction";
-+ goto fail;
-+ }
-+ memcpy(iNew, &insn, sizeof(struct cnc_insn));
-+ TAILQ_INSERT_TAIL(&cnc_prog, iNew, prog);
-+ ip++;
-+ }
-+ printf("cnc: added %u insns to queue\n", ip);
-+ return (0);
-+fail:
-+ printf("%s[%d]: %s\n", cnc_insn_names[insn.i_type], ip, cause);
-+ return (EINVAL);
-+}
-+
-+void
-+cnc_prog_reset(void)
-+{
-+ struct cnc_insn *in;
-+ u_int ninsns = 0;
-+
-+ while ((in = TAILQ_FIRST(&cnc_prog)) != NULL) {
-+ TAILQ_REMOVE(&cnc_prog, in, prog);
-+ pool_put(&cnc_insnpl, in);
-+ ninsns++;
-+ }
-+/* printf("cnc: deleted %u insns\n", ninsns); */
-+}
-+
-+int
-+cnc_prog_exec(void)
-+{
-+ struct cnc_insn *insn;
-+ u_int ninsns = 0;
-+ int s;
-+
-+ if (cnc_nservos != CNC_NAXES) {
-+ printf("cnc: nservos=%d, but CNC_NAXES=%d\n", cnc_nservos,
-+ CNC_NAXES);
-+ return (EIO);
-+ }
-+
-+ printf("cnc: executing program\n");
-+
-+ s = splclock();
-+ TAILQ_FOREACH(insn, &cnc_prog, prog) {
-+ switch (insn->i_type) {
-+ case CNC_MOVE:
-+ if (cnc_move(insn) == -1) {
-+ goto fail;
-+ }
-+ break;
-+#if NSPINDLE > 0
-+ case CNC_SPINDLE_START:
-+ spindle_start(cnc_spindles[insn->i_spindle_id], insn);
-+ break;
-+ case CNC_SPINDLE_STOP:
-+ spindle_stop(cnc_spindles[insn->i_spindle_id], insn);
-+ break;
-+ case CNC_SPINDLE_SPEED:
-+ spindle_speed(cnc_spindles[insn->i_spindle_id], insn);
-+ break;
-+#endif
-+ default:
-+ break;
-+ }
-+ printf("insn %u: type=%d\n", ninsns, insn->i_type);
-+ ninsns++;
-+ }
-+ splx(s);
-+ return (0);
-+fail:
-+ splx(s);
-+ return (EIO);
-+}
-+
-+/*
-+ * Try to calibrate cnc_timebase to a value that will give us as
-+ * close as possible to 1 second. There is no portable way to do
-+ * this so we repeatedly benchmark results of a real delay loop
-+ * until the error is reduced to a minimum.
-+ *
-+ * This can take a while, but only needs to be run once on any
-+ * given machine.
-+ *
-+ * XXX the algorithm should be optimized based on the rate of change
-+ * in the results.
-+ */
-+u_long
-+cnc_calibrate_timebase(void)
-+{
-+ struct timeval tv1, tv2;
-+ long ds, du, d;
-+ u_long timebase = 10000000, i;
-+ int s, j;
-+
-+ s = splhigh();
-+ printf("cnc: calibrating timebase...");
-+ for (j = 0; j < 500; j++) {
-+ microtime(&tv1);
-+ for (i = 0; i < timebase; i++)
-+ ;;
-+ microtime(&tv2);
-+ ds = tv2.tv_sec - tv1.tv_sec;
-+ du = tv2.tv_usec - tv1.tv_usec;
-+
-+ printf(" %ld", 1000000-du);
-+ if (ds < 0) {
-+ timebase += 1000000;
-+ } else if (ds > 0) {
-+ timebase -= 1000000;
-+ } else if (ds == 0 && du < 1000000) {
-+ d = 1000000 - du;
-+ timebase += d*4;
-+ if (d < 10) { break; }
-+ } else if (ds == 0 && du > 1000000) {
-+ d = du - 1000000;
-+ timebase -= d*4;
-+ if (d < 10) { break; }
-+ } else {
-+ break;
-+ }
-+ }
-+ splx(s);
-+ printf("\n");
-+ return (timebase);
-+}
-+
-+int
-+cncioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
-+{
-+ struct cnc_kinematics *kin;
-+ cnc_vec_t *pos;
-+ int i;
-+
-+ switch (cmd) {
-+ case CNC_EXECPROG:
-+ return (cnc_prog_exec());
-+ case CNC_RESETPROG:
-+ return (cnc_prog_exec());
-+ case CNC_GETPOS:
-+ pos = (cnc_vec_t *)data;
-+ for (i = 0; i < CNC_NAXES; i++) {
-+ pos->v[i] = cnc_pos.v[i];
-+ }
-+ return (0);
-+ case CNC_SETPOS:
-+ pos = (cnc_vec_t *)data;
-+ for (i = 0; i < CNC_NAXES; i++) {
-+ printf("cnc: axis %d: %lu -> %lu", i, cnc_pos.v[i],
-+ pos->v[i]);
-+ cnc_pos.v[i] = pos->v[i];
-+ }
-+ return (0);
-+ case CNC_GETNSERVOS:
-+ *(int *)data = cnc_nservos;
-+ return (0);
-+ case CNC_GETNSPINDLES:
-+ *(int *)data = cnc_nspindles;
-+ return (0);
-+ case CNC_GETNESTOPS:
-+ *(int *)data = cnc_nestops;
-+ return (0);
-+ case CNC_GETKINLIMITS:
-+ kin = (struct cnc_kinematics *)data;
-+// kin->k_Ts = (int)cnc_Ts;
-+ kin->k_Vmax = (int)cnc_Vmax;
-+ return (0);
-+ case CNC_SETKINLIMITS:
-+ kin = (struct cnc_kinematics *)data;
-+ if (kin->k_Ts < 0 || kin->k_Vmax < 0) {
-+ return (EINVAL);
-+ }
-+// cnc_Ts = (cnc_real_t)kin->k_Ts;
-+ cnc_Vmax = (cnc_real_t)kin->k_Vmax;
-+ return (0);
-+ case CNC_GETTIMEBASE:
-+ *(u_long *)data = cnc_timebase;
-+ return (0);
-+ case CNC_SETTIMEBASE:
-+ cnc_timebase = *(u_long *)data;
-+ return (0);
-+ case CNC_CALTIMEBASE:
-+ *(u_long *)data = cnc_calibrate_timebase();
-+ return (0);
-+ default:
-+ break;
-+ }
-+ return (ENODEV);
-+}
-+
-+void
-+cnc_move_axis(enum cnc_axis axis, int dir)
-+{
-+ servo_step(cnc_servos[axis], dir);
-+ cnc_pos.v[axis] += dir;
-+}
-+
-+/* Check whether an e-stop device is active. */
-+int
-+cnc_estop_raised(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < cnc_nestops; i++) {
-+ if (estop_get_state(cnc_estops[i])) {
-+ printf("%s: emergency stop\n",
-+ cnc_estops[i]->cd_dev.dv_xname);
-+ return (1);
-+ }
-+ }
-+ return (0);
-+}
-+
-+/*
-+ * Coordinated movement of the n axes to a target position in n-dimensional
-+ * space at the specified feed rate.
-+ *
-+ * TODO Specialized applications could use another algorithm to provide a
-+ * more constant velocity through simultaneous deceleration and acceleration
-+ * of the axes, at the cost of contour errors proportional to Ts.
-+ */
-+int
-+cnc_move(struct cnc_insn *insn)
-+{
-+ struct cnc_quintic_profile qprof;
-+ cnc_real_t t;
-+#if CNC_NAXES == 3
-+ cnc_pos_t x1 = cnc_pos.v[CNC_X];
-+ cnc_pos_t y1 = cnc_pos.v[CNC_Y];
-+ cnc_pos_t z1 = cnc_pos.v[CNC_Z];
-+ cnc_pos_t x2 = insn->i_pos.v[CNC_X];
-+ cnc_pos_t y2 = insn->i_pos.v[CNC_Y];
-+ cnc_pos_t z2 = insn->i_pos.v[CNC_Z];
-+ cnc_pos_t dx, dy, dz;
-+ cnc_pos_t x, y, z;
-+ int xdir, ydir, zdir;
-+#endif
-+
-+#if CNC_NAXES == 3
-+ dx = abs(x2 - x1);
-+ dy = abs(y2 - y1);
-+ dz = abs(z2 - z1);
-+
-+ if (dx == 0 && dy == 0 && dz == 0)
-+ return (0);
-+
-+ xdir = (x2 > x1) ? 1 : -1;
-+ ydir = (y2 > y1) ? 1 : -1;
-+ zdir = (z2 > z1) ? 1 : -1;
-+
-+ printf("MOVE: Delta=%ld,%ld,%ld\n", dx, dy, dz);
-+ printf("MOVE: Dir=%d,%d,%d\n", xdir, ydir, zdir);
-+ printf("MOVE: F = %d st/s, Amax = %d st/s^2, Jmax = %d st/s^3\n",
-+ insn->i_F, insn->i_Amax, insn->i_Jmax);
-+
-+ if (dx >= dy && dx >= dz) {
-+ dy = dy*STEPLEN/dx;
-+ dz = dz*STEPLEN/dx;
-+ if (cnc_quintic_init(&qprof, insn, (cnc_real_t)dx) == -1) {
-+ goto fail;
-+ }
-+ for (x = 0, t = 0.0;
-+ x < dx && t < MAXSTEPS;
-+ x++, t+=1.0) {
-+ y = (dy*ydir*t)/STEPLEN;
-+ z = (dz*zdir*t)/STEPLEN;
-+ if (cnc_estop_raised()) {
-+ goto fail;
-+ }
-+ cnc_move_axis(CNC_X, xdir);
-+ if (y1+y != cnc_pos.v[CNC_Y]) {
-+ cnc_move_axis(CNC_Y, y);
-+ cnc_pos.v[CNC_Y] = y1+y;
-+ }
-+ if (z1+z != cnc_pos.v[CNC_Z]) {
-+ cnc_move_axis(CNC_Z, z);
-+ cnc_pos.v[CNC_Z] = z1+z;
-+ }
-+ cnc_move_delay(&qprof, t, (cnc_real_t)dx);
-+ }
-+ } else if (dy >= dx && dy >= dz) {
-+ dx = dx*STEPLEN/dy;
-+ dz = dz*STEPLEN/dy;
-+ if (cnc_quintic_init(&qprof, insn, (cnc_real_t)dy) == -1) {
-+ goto fail;
-+ }
-+ for (y = 0, t = 0.0;
-+ y < dy && t < MAXSTEPS;
-+ y++, t+=1.0) {
-+ x = (dx*xdir*t)/STEPLEN;
-+ z = (dz*zdir*t)/STEPLEN;
-+ if (cnc_estop_raised()) {
-+ goto fail;
-+ }
-+ cnc_move_axis(CNC_Y, ydir);
-+ if (x1+x != cnc_pos.v[CNC_X]) {
-+ cnc_move_axis(CNC_X, x);
-+ cnc_pos.v[CNC_X] = x1+x;
-+ }
-+ if (z1+z != cnc_pos.v[CNC_Z]) {
-+ cnc_move_axis(CNC_Z, z);
-+ cnc_pos.v[CNC_Z] = z1+z;
-+ }
-+ cnc_move_delay(&qprof, t, (cnc_real_t)dy);
-+ }
-+ } else if (dz >= dx && dz >= dy) {
-+ dx = dx*STEPLEN/dz;
-+ dy = dy*STEPLEN/dz;
-+ if (cnc_quintic_init(&qprof, insn, (cnc_real_t)dz) == -1) {
-+ goto fail;
-+ }
-+ for (z = 0, t = 0.0;
-+ z < dz && t < MAXSTEPS;
-+ z++, t+=1.0) {
-+ x = (dx*xdir*t)/STEPLEN;
-+ y = (dy*ydir*t)/STEPLEN;
-+ if (cnc_estop_raised()) {
-+ goto fail;
-+ }
-+ cnc_move_axis(CNC_Z, zdir);
-+ if (x1+x != cnc_pos.v[CNC_X]) {
-+ cnc_move_axis(CNC_X, x);
-+ cnc_pos.v[CNC_X] = x1+x;
-+ }
-+ if (y1+y != cnc_pos.v[CNC_Y]) {
-+ cnc_move_axis(CNC_Y, y);
-+ cnc_pos.v[CNC_Y] = y1+y;
-+ }
-+ cnc_move_delay(&qprof, t, (cnc_real_t)dz);
-+ }
-+ } else {
-+ printf("MOVE: Bad case\n");
-+ goto fail;
-+ }
-+#endif
-+ return (0);
-+fail:
-+ printf("MOVE: Aborted instruction\n");
-+ return (-1);
-+}
-+
-+/*
-+ * Enter a precisely-calculated loop that will give us the proper delay
-+ * between two steps.
-+ */
-+void
-+cnc_move_delay(const struct cnc_quintic_profile *q, cnc_real_t t, cnc_real_t L)
-+{
-+ cnc_real_t v;
-+ u_long delay;
-+ u_long j;
-+
-+ v = cnc_quintic_step(q, t*(q->Ta + q->To)/L)*q->F/(q->v0+q->v1+q->v2) +
-+ q->v0;
-+ delay = (u_long)(cnc_timebase/v);
-+ if (delay > cnc_timebase) {
-+ delay = cnc_timebase;
-+ }
-+#if 1
-+ for (j = 0; j < delay; j++)
-+ ;;
-+#else
-+ printf("[%lu] %s steps/sec (delay=%lu)\n", (u_long)t, cnc_fmt_real(v),
-+ delay);
-+#endif
-+}
-+
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_cbrt.c sys/dev/cnc/cnc_cbrt.c
---- sys.ORIG/dev/cnc/cnc_cbrt.c Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_cbrt.c Wed May 30 01:06:05 2007
- <at> <at> -0,0 +1,96 <at> <at>
-+/* <at> (#)s_cbrt.c 5.1 93/09/24 */
-+/*
-+ * ====================================================
-+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-+ *
-+ * Developed at SunPro, a Sun Microsystems, Inc. business.
-+ * Permission to use, copy, modify, and distribute this
-+ * software is freely granted, provided that this notice
-+ * is preserved.
-+ * ====================================================
-+ */
-+
-+#if defined(LIBM_SCCS) && !defined(lint)
-+static char rcsid[] = "$NetBSD: s_cbrt.c,v 1.8 1995/05/10 20:46:49 jtc Exp $";
-+#endif
-+
-+#include <sys/param.h>
-+#include <sys/queue.h>
-+#include <sys/ioctl.h>
-+#include <sys/fcntl.h>
-+#include <sys/vnode.h>
-+#include <sys/systm.h>
-+#include <sys/kernel.h>
-+#include <sys/device.h>
-+
-+#include <sys/gpio.h>
-+#include <sys/cnc.h>
-+
-+#include <dev/gpio/gpiovar.h>
-+
-+#include "cnc_devicevar.h"
-+#include "cncvar.h"
-+#include "math_private.h"
-+
-+/* cbrt(x)
-+ * Return cube root of x
-+ */
-+static const u_int32_t
-+ B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
-+ B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
-+
-+static const double
-+C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */
-+D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
-+E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */
-+F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */
-+G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */
-+
-+double
-+cnc_cbrt(double x)
-+{
-+ int32_t hx;
-+ double r,s,t=0.0,w;
-+ u_int32_t sign;
-+ u_int32_t high,low;
-+
-+ GET_HIGH_WORD(hx,x);
-+ sign=hx&0x80000000; /* sign= sign(x) */
-+ hx ^=sign;
-+ if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
-+ GET_LOW_WORD(low,x);
-+ if((hx|low)==0)
-+ return(x); /* cbrt(0) is itself */
-+
-+ SET_HIGH_WORD(x,hx); /* x <- |x| */
-+ /* rough cbrt to 5 bits */
-+ if(hx<0x00100000) /* subnormal number */
-+ {SET_HIGH_WORD(t,0x43500000); /* set t= 2**54 */
-+ t*=x; GET_HIGH_WORD(high,t); SET_HIGH_WORD(t,high/3+B2);
-+ }
-+ else
-+ SET_HIGH_WORD(t,hx/3+B1);
-+
-+
-+ /* new cbrt to 23 bits, may be implemented in single precision */
-+ r=t*t/x;
-+ s=C+r*t;
-+ t*=G+F/(s+E+D/s);
-+
-+ /* chopped to 20 bits and make it larger than cbrt(x) */
-+ GET_HIGH_WORD(high,t);
-+ INSERT_WORDS(t,high+0x00000001,0);
-+
-+
-+ /* one step newton iteration to 53 bits with error less than 0.667 ulps */
-+ s=t*t; /* t*t is exact */
-+ r=x/s;
-+ w=t+t;
-+ r=(r-t)/(w+r); /* r-s is exact */
-+ t=t+t*r;
-+
-+ /* retore the sign bit */
-+ GET_HIGH_WORD(high,t);
-+ SET_HIGH_WORD(t,high|sign);
-+ return(t);
-+}
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_device.c sys/dev/cnc/cnc_device.c
---- sys.ORIG/dev/cnc/cnc_device.c Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_device.c Thu Jun 7 03:12:27 2007
- <at> <at> -0,0 +1,113 <at> <at>
-+/* $OpenBSD$ */
-+
-+/*
-+ * Copyright (c) 2007 Hypertriton, Inc. <http://www.hypertriton.com/>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * Generic CNC device code.
-+ */
-+
-+#include <sys/param.h>
-+#include <sys/queue.h>
-+#include <sys/ioctl.h>
-+#include <sys/fcntl.h>
-+#include <sys/vnode.h>
-+#include <sys/systm.h>
-+#include <sys/kernel.h>
-+#include <sys/device.h>
-+#include <sys/pool.h>
-+#include <sys/conf.h>
-+#include <sys/lock.h>
-+#include <sys/kthread.h>
-+
-+#include <sys/cnc.h>
-+
-+#include "cnc_devicevar.h"
-+#include "cncvar.h"
-+
-+struct cnc_deviceq cnc_devices;
-+int cnc_initialized = 0;
-+
-+int
-+cnc_device_attach(void *p, enum cnc_device_type type)
-+{
-+ struct cnc_device *cd = p;
-+
-+ if (!cnc_initialized) {
-+ TAILQ_INIT(&cnc_devices);
-+ cnc_initialized = 1;
-+ }
-+ cd->cd_type = type;
-+ cd->cd_flags = 0;
-+ TAILQ_INSERT_TAIL(&cnc_devices, cd, devices);
-+
-+ switch (type) {
-+ case CNC_DEVICE_SERVO:
-+ if ((cnc_nservos+1) <= CNC_NAXES) {
-+ printf(": axis %d\n", cnc_nservos);
-+ cnc_servos[cnc_nservos++] = cd;
-+ } else {
-+ printf(": ignored (bump CNC_NAXES)\n");
-+ }
-+ break;
-+ case CNC_DEVICE_SPINDLE:
-+ if ((cnc_nspindles+1) <= CNC_MAX_SPINDLES) {
-+ printf(": spindle %d\n", cnc_nspindles);
-+ cnc_spindles[cnc_nspindles++] = cd;
-+ } else {
-+ printf(": ignored (bump CNC_MAX_SPINDLES)\n");
-+ }
-+ break;
-+ case CNC_DEVICE_ESTOP:
-+ if ((cnc_nestops+1) <= CNC_MAX_ESTOPS) {
-+ printf(": estop %d\n", cnc_nestops);
-+ cnc_estops[cnc_nestops++] = cd;
-+ } else {
-+ printf(": ignored (bump CNC_MAX_ESTOPS)\n");
-+ }
-+ break;
-+ default:
-+ printf(": unimplemented\n");
-+ break;
-+ }
-+ printf("%s", cd->cd_dev.dv_xname);
-+ return (0);
-+}
-+
-+int
-+cnc_device_detach(void *p)
-+{
-+ struct cnc_device *cd = p;
-+
-+ TAILQ_REMOVE(&cnc_devices, cd, devices);
-+ return (0);
-+}
-+
-+int
-+cnc_device_activate(void *p)
-+{
-+ return (0);
-+}
-+
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_devicevar.h sys/dev/cnc/cnc_devicevar.h
---- sys.ORIG/dev/cnc/cnc_devicevar.h Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_devicevar.h Thu Jun 7 03:07:52 2007
- <at> <at> -0,0 +1,26 <at> <at>
-+/* $OpenBSD$ */
-+/* Public domain */
-+
-+enum cnc_device_type {
-+ CNC_DEVICE_ESTOP, /* Emergency stop device */
-+ CNC_DEVICE_SERVO, /* Servo motor controller */
-+ CNC_DEVICE_SPINDLE, /* Machine spindle controller */
-+ CNC_DEVICE_ATC, /* Automatic tool changer */
-+ CNC_DEVICE_LASER, /* Laser power supply controller */
-+ CNC_DEVICE_PICKPLACE /* Pick and place controller */
-+};
-+
-+struct cnc_device {
-+ struct device cd_dev;
-+ enum cnc_device_type cd_type;
-+ int cd_flags;
-+ TAILQ_ENTRY(cnc_device) devices;
-+};
-+
-+TAILQ_HEAD(cnc_deviceq,cnc_device);
-+extern struct cnc_deviceq cnc_devices;
-+
-+int cnc_device_attach(void *, enum cnc_device_type);
-+int cnc_device_detach(void *);
-+int cnc_device_activate(void *);
-+
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_estop.c sys/dev/cnc/cnc_estop.c
---- sys.ORIG/dev/cnc/cnc_estop.c Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_estop.c Fri Jun 8 01:40:04 2007
- <at> <at> -0,0 +1,130 <at> <at>
-+/* $OpenBSD$ */
-+
-+/*
-+ * Copyright (c) 2007 Hypertriton, Inc. <http://www.hypertriton.com/>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * Driver for emergency stop button.
-+ */
-+
-+#include <sys/param.h>
-+#include <sys/queue.h>
-+#include <sys/ioctl.h>
-+#include <sys/fcntl.h>
-+#include <sys/vnode.h>
-+#include <sys/systm.h>
-+#include <sys/kernel.h>
-+#include <sys/device.h>
-+#include <sys/pool.h>
-+#include <sys/conf.h>
-+#include <sys/lock.h>
-+
-+#include <sys/gpio.h>
-+#include <sys/cnc.h>
-+
-+#include <dev/gpio/gpiovar.h>
-+
-+#include <dev/cnc/cnc_devicevar.h>
-+#include <dev/cnc/cncvar.h>
-+#include <dev/cnc/cnc_estopvar.h>
-+
-+int estop_match(struct device *, void *, void *);
-+void estop_attach(struct device *, struct device *, void *);
-+int estop_detach(struct device *, int);
-+int estop_activate(struct device *, enum devact);
-+void estop_abort_all(void);
-+
-+struct cfattach estop_ca = {
-+ sizeof(struct estop_softc),
-+ estop_match,
-+ estop_attach,
-+ estop_detach,
-+ estop_activate
-+};
-+
-+struct cfdriver estop_cd = {
-+ NULL, "estop", DV_DULL
-+};
-+
-+int
-+estop_match(struct device *parent, void *match, void *aux)
-+{
-+ struct cfdata *cf = match;
-+
-+ return (strcmp(cf->cf_driver->cd_name, "estop") == 0);
-+}
-+
-+void
-+estop_attach(struct device *parent, struct device *self, void *aux)
-+{
-+ struct estop_softc *sc = (struct estop_softc *)self;
-+ struct gpio_attach_args *ga = aux;
-+ int caps, ctl;
-+
-+ sc->sc_flags = 0;
-+
-+ if (gpio_npins(ga->ga_mask) != ESTOP_NPINS) {
-+ printf(": invalid pin mask\n");
-+ return;
-+ }
-+ sc->sc_gpio = ga->ga_gpio;
-+ sc->sc_map.pm_map = sc->__map;
-+ if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
-+ &sc->sc_map)) {
-+ printf(": can't map pins\n");
-+ return;
-+ }
-+
-+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, ESTOP_PIN);
-+ if (!(caps & GPIO_PIN_INPUT)) {
-+ printf(": ESTOP pin is unable to read input\n");
-+ gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
-+ return;
-+ }
-+ printf(": ESTOP[%d]\n", sc->sc_map.pm_map[ESTOP_PIN]);
-+ ctl = GPIO_PIN_INPUT;
-+ if (caps & GPIO_PIN_PUSHPULL) { ctl |= GPIO_PIN_PUSHPULL; }
-+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, ESTOP_PIN, ctl);
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, ESTOP_PIN, GPIO_PIN_LOW);
-+}
-+
-+int
-+estop_detach(struct device *self, int flags)
-+{
-+ return (0);
-+}
-+
-+int
-+estop_activate(struct device *self, enum devact act)
-+{
-+ return (0);
-+}
-+
-+int
-+estop_get_state(void *p)
-+{
-+ struct estop_softc *sc = p;
-+ return (gpio_pin_read(sc->sc_gpio, &sc->sc_map, ESTOP_PIN));
-+}
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_estopvar.h sys/dev/cnc/cnc_estopvar.h
---- sys.ORIG/dev/cnc/cnc_estopvar.h Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_estopvar.h Fri Jun 8 01:39:48 2007
- <at> <at> -0,0 +1,16 <at> <at>
-+/* $OpenBSD$ */
-+/* Public domain */
-+
-+#define ESTOP_NPINS 1
-+#define ESTOP_PIN 0
-+
-+struct estop_softc {
-+ struct cnc_device sc_cdev;
-+
-+ int sc_flags;
-+ void *sc_gpio;
-+ struct gpio_pinmap sc_map;
-+ int __map[ESTOP_NPINS];
-+};
-+
-+int estop_get_state(void *);
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_log10.S sys/dev/cnc/cnc_log10.S
---- sys.ORIG/dev/cnc/cnc_log10.S Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_log10.S Wed May 30 02:07:00 2007
- <at> <at> -0,0 +1,13 <at> <at>
-+/* $OpenBSD: e_log10.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
-+/*
-+ * Written by J.T. Conklin <jtc-S783fYmB3Ccdnm+yROfE0A <at> public.gmane.org>.
-+ * Public domain.
-+ */
-+
-+#include <machine/asm.h>
-+
-+ENTRY(cnc_log10)
-+ fldlg2
-+ fldl 4(%esp)
-+ fyl2x
-+ ret
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_math.c sys/dev/cnc/cnc_math.c
---- sys.ORIG/dev/cnc/cnc_math.c Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_math.c Wed May 30 09:19:43 2007
- <at> <at> -0,0 +1,96 <at> <at>
-+/* $OpenBSD$ */
-+/* Public domain */
-+
-+#include <sys/param.h>
-+#include <sys/queue.h>
-+#include <sys/ioctl.h>
-+#include <sys/fcntl.h>
-+#include <sys/vnode.h>
-+#include <sys/systm.h>
-+#include <sys/kernel.h>
-+#include <sys/device.h>
-+
-+#include <sys/gpio.h>
-+#include <sys/cnc.h>
-+
-+#include <dev/gpio/gpiovar.h>
-+
-+#include "cnc_devicevar.h"
-+#include "cncvar.h"
-+
-+void
-+cnc_vec_init(cnc_vec_t v)
-+{
-+ int i;
-+
-+ for (i = 0; i < CNC_NAXES; i++)
-+ v.v[i] = 0;
-+}
-+
-+/* Return (v1-v2) in vDst. */
-+void
-+cnc_vec_sub(cnc_vec_t *vDst, const cnc_vec_t *v1, const cnc_vec_t *v2)
-+{
-+ int i;
-+
-+ for (i = 0; i < CNC_NAXES; i++)
-+ vDst->v[i] = v1->v[i] - v2->v[i];
-+}
-+
-+/* Return (v1+v2) in vDst. */
-+void
-+cnc_vec_add(cnc_vec_t *vDst, const cnc_vec_t *v1, const cnc_vec_t *v2)
-+{
-+ int i;
-+
-+ for (i = 0; i < CNC_NAXES; i++)
-+ vDst->v[i] = v1->v[i] + v2->v[i];
-+}
-+
-+/* Return real dot product of v1 and v2. */
-+cnc_real_t
-+cnc_vec_dotprod(cnc_vec_t *vDst, const cnc_vec_t *v1, const cnc_vec_t *v2)
-+{
-+ cnc_real_t dot = 0.0;
-+ int i;
-+
-+ for (i = 0; i < CNC_NAXES; i++) {
-+ dot += ((cnc_real_t)v1->v[i])*((cnc_real_t)v2->v[i]);
-+ }
-+ return (dot);
-+}
-+
-+/* Return real length of vector v. */
-+cnc_real_t
-+cnc_vec_length(const cnc_vec_t *v)
-+{
-+ cnc_real_t len_2 = 0.0;
-+ int i;
-+
-+ for (i = 0; i < CNC_NAXES; i++) {
-+ len_2 += ((cnc_real_t)v->v[i])*((cnc_real_t)v->v[i]);
-+ }
-+ return (cnc_sqrt(len_2));
-+}
-+
-+/* Return real distance between vectors v1 and v2. */
-+cnc_real_t
-+cnc_vec_distance(const cnc_vec_t *v1, const cnc_vec_t *v2)
-+{
-+ cnc_vec_t vd;
-+
-+ cnc_vec_sub(&vd, v2, v1);
-+ return (cnc_vec_length(&vd));
-+}
-+
-+char *
-+cnc_fmt_real(cnc_real_t v)
-+{
-+ static char s[64];
-+ double fpart;
-+ double ipart;
-+
-+ fpart = cnc_modf(v, &ipart);
-+ snprintf(s, sizeof(s), "%ld.%ld", (long)ipart, (long)(fpart*10000.0));
-+ return (s);
-+}
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_math.h sys/dev/cnc/cnc_math.h
---- sys.ORIG/dev/cnc/cnc_math.h Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_math.h Wed May 30 08:50:13 2007
- <at> <at> -0,0 +1,21 <at> <at>
-+/* $OpenBSD$ */
-+
-+typedef float cnc_real_t;
-+
-+#define CNC_PI 3.14159265358979323846 /* pi */
-+#define CNC_PI_2 1.57079632679489661923 /* pi/2 */
-+#define CNC_MSECS(s) ((u_long)(s*1e3))
-+
-+double cnc_sin(double);
-+double cnc_sqrt(double);
-+double cnc_cbrt(double);
-+double cnc_log10(double);
-+double cnc_modf(double, double *);
-+char *cnc_fmt_real(cnc_real_t);
-+
-+void cnc_vec_init(cnc_vec_t);
-+void cnc_vec_sub(cnc_vec_t *, const cnc_vec_t *, const cnc_vec_t *);
-+void cnc_vec_add(cnc_vec_t *, const cnc_vec_t *, const cnc_vec_t *);
-+cnc_real_t cnc_vec_dotprod(cnc_vec_t *, const cnc_vec_t *, const cnc_vec_t *);
-+cnc_real_t cnc_vec_length(const cnc_vec_t *);
-+cnc_real_t cnc_vec_distance(const cnc_vec_t *, const cnc_vec_t *);
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_modf.c sys/dev/cnc/cnc_modf.c
---- sys.ORIG/dev/cnc/cnc_modf.c Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_modf.c Wed May 30 06:45:59 2007
- <at> <at> -0,0 +1,90 <at> <at>
-+/* <at> (#)s_modf.c 5.1 93/09/24 */
-+/*
-+ * ====================================================
-+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-+ *
-+ * Developed at SunPro, a Sun Microsystems, Inc. business.
-+ * Permission to use, copy, modify, and distribute this
-+ * software is freely granted, provided that this notice
-+ * is preserved.
-+ * ====================================================
-+ */
-+
-+#if defined(LIBM_SCCS) && !defined(lint)
-+static char rcsid[] = "$NetBSD: s_modf.c,v 1.8 1995/05/10 20:47:55 jtc Exp $";
-+#endif
-+
-+/*
-+ * modf(double x, double *iptr)
-+ * return fraction part of x, and return x's integral part in *iptr.
-+ * Method:
-+ * Bit twiddling.
-+ *
-+ * Exception:
-+ * No exception.
-+ */
-+
-+#include <sys/param.h>
-+#include <sys/queue.h>
-+#include <sys/ioctl.h>
-+#include <sys/fcntl.h>
-+#include <sys/vnode.h>
-+#include <sys/systm.h>
-+#include <sys/kernel.h>
-+#include <sys/device.h>
-+
-+#include <sys/gpio.h>
-+#include <sys/cnc.h>
-+
-+#include <dev/gpio/gpiovar.h>
-+
-+#include "cnc_devicevar.h"
-+#include "cncvar.h"
-+#include "math_private.h"
-+
-+static const double one = 1.0;
-+
-+double
-+cnc_modf(double x, double *iptr)
-+{
-+ int32_t i0,i1,j0;
-+ u_int32_t i;
-+ EXTRACT_WORDS(i0,i1,x);
-+ j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
-+ if(j0<20) { /* integer part in high x */
-+ if(j0<0) { /* |x|<1 */
-+ INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */
-+ return x;
-+ } else {
-+ i = (0x000fffff)>>j0;
-+ if(((i0&i)|i1)==0) { /* x is integral */
-+ u_int32_t high;
-+ *iptr = x;
-+ GET_HIGH_WORD(high,x);
-+ INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
-+ return x;
-+ } else {
-+ INSERT_WORDS(*iptr,i0&(~i),0);
-+ return x - *iptr;
-+ }
-+ }
-+ } else if (j0>51) { /* no fraction part */
-+ u_int32_t high;
-+ *iptr = x*one;
-+ GET_HIGH_WORD(high,x);
-+ INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
-+ return x;
-+ } else { /* fraction part in low x */
-+ i = ((u_int32_t)(0xffffffff))>>(j0-20);
-+ if((i1&i)==0) { /* x is integral */
-+ u_int32_t high;
-+ *iptr = x;
-+ GET_HIGH_WORD(high,x);
-+ INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
-+ return x;
-+ } else {
-+ INSERT_WORDS(*iptr,i0,i1&(~i));
-+ return x - *iptr;
-+ }
-+ }
-+}
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_quintic.c sys/dev/cnc/cnc_quintic.c
---- sys.ORIG/dev/cnc/cnc_quintic.c Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_quintic.c Fri Jun 8 06:58:07 2007
- <at> <at> -0,0 +1,167 <at> <at>
-+/* $OpenBSD$ */
-+/*
-+ * Copyright (c) 2007 Hypertriton, Inc. <http://www.hypertriton.com/>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * Quintic velocity profile generation.
-+ */
-+
-+#include <sys/param.h>
-+#include <sys/queue.h>
-+#include <sys/ioctl.h>
-+#include <sys/fcntl.h>
-+#include <sys/vnode.h>
-+#include <sys/systm.h>
-+#include <sys/kernel.h>
-+#include <sys/device.h>
-+
-+#include <sys/gpio.h>
-+#include <sys/cnc.h>
-+
-+#include <dev/gpio/gpiovar.h>
-+
-+#include "cnc_devicevar.h"
-+#include "cncvar.h"
-+
-+/*
-+ * Initialize constants to values that will yield an optimal time-energy
-+ * velocity profile under acceleration and jerk constraints.
-+ */
-+int
-+cnc_quintic_init(struct cnc_quintic_profile *q, const struct cnc_insn *insn,
-+ cnc_real_t L)
-+{
-+ cnc_real_t F = ((cnc_real_t)insn->i_F);
-+ cnc_real_t Amax = ((cnc_real_t)insn->i_Amax);
-+ cnc_real_t Jmax = ((cnc_real_t)insn->i_Jmax);
-+ cnc_real_t k;
-+
-+ q->F = F;
-+
-+// if (F >= CNC_PI_2*((Amax*Amax)/Jmax) ) {
-+ /*
-+ * Feedrate F is achievable by using maximum acceleration
-+ * and maximum jerk.
-+ */
-+ if (L >= ( (L*L)/Amax + CNC_PI_2*((Amax*F)/Jmax) )){
-+ /* Feedrate F is achievable at Amax acceleration. */
-+ printf("case 1.1\n");
-+ q->Ts = CNC_PI_2*(Amax/Jmax);
-+ q->Ta = (F/Amax) + q->Ts;
-+ q->To = L/F;
-+ } else if (L < ( (F*F)/Amax + CNC_PI_2*((Amax*F)/Jmax) ) &&
-+ L >= ( (CNC_PI*CNC_PI)/2.0) * (Amax*Amax*Amax) /
-+ (Jmax*Jmax) ) {
-+ /* Feedrate F is unachievable, Amax is achievable. */
-+ printf("case 1.2\n");
-+ q->Ts = CNC_PI_2*(Amax/Jmax);
-+ q->Ta = ( (-CNC_PI*(Amax*Amax) +
-+ cnc_sqrt((CNC_PI*CNC_PI)*(Amax*Amax*Amax*Amax) +
-+ 16.0*Amax*(Jmax*Jmax)*L) ) /
-+ (4.0*Jmax*Amax) ) + q->Ts;
-+ q->To = q->Ta;
-+ } else if (L <= ( ((CNC_PI*CNC_PI)/2.0)*(Amax*Amax*Amax) /
-+ (Jmax*Jmax) )) {
-+ /* Neither F nor Amax are achievable. */
-+ printf("case 1.3\n");
-+ q->Ts = cnc_cbrt( (CNC_PI*L)/(4.0*Jmax) );
-+ q->Ta = 2.0*q->Ts;
-+ q->To = q->Ta;
-+// } else {
-+// printf("MOVE: Illegal parameters (1)\n");
-+// return (-1);
-+ }
-+// } else if (F < CNC_PI_2*((Amax*Amax)/Jmax) ) {
-+ /*
-+ * Feedrate F is achievable without using maximum
-+ * acceleration.
-+ */
-+ if (L >= cnc_sqrt( (2.0*CNC_PI*(F*F*F))/Jmax ) ) {
-+ /* F is achievable, Amax is unachievable. */
-+ printf("case 2.1\n");
-+ q->Ts = cnc_sqrt( (CNC_PI*F)/(2.0*Jmax) );
-+ q->Ta = 2.0*q->Ts;
-+ q->To = L/F;
-+ } else if (L < cnc_sqrt( (2.0*CNC_PI*F*F*F)/Jmax )) {
-+ /* Neither F nor Amax are achievable. */
-+ printf("case 2.2\n");
-+ q->Ts = cnc_cbrt( (CNC_PI*L)/(4.0*Jmax) );
-+ q->Ta = 2.0*q->Ts;
-+ q->To = q->Ta;
-+ } else {
-+ printf("MOVE: Illegal parameters (2)\n");
-+ return (-1);
-+ }
-+// }
-+
-+ k = CNC_PI/(2.0*q->Ts);
-+ q->Aref = L/(q->Ta - q->Ts) * q->To;
-+ q->v0 = ((cnc_real_t)insn->i_v0);
-+ q->v1 = (q->Aref/2.0) * (q->Ts - cnc_sin(2.0*k*q->Ts)/(2.0*k) );
-+ q->v2 = q->Aref*(q->Ta - 2.0*q->Ts) + q->v1;
-+
-+ printf("MOVE: ");
-+ printf("F=%s ", cnc_fmt_real(F));
-+ printf("v1=%s ", cnc_fmt_real(q->v1));
-+ printf("v2=%s ", cnc_fmt_real(q->v2));
-+ printf("v3=%s ", cnc_fmt_real(q->v1+q->v2));
-+ printf("Amax=%s ", cnc_fmt_real(Amax));
-+ printf("Jmax=%s ", cnc_fmt_real(Jmax));
-+ printf("Ta=%s ", cnc_fmt_real(q->Ta));
-+ printf("Ts=%s ", cnc_fmt_real(q->Ts));
-+ printf("To=%s\n", cnc_fmt_real(q->To));
-+ return (0);
-+}
-+
-+cnc_real_t
-+cnc_quintic_step(const struct cnc_quintic_profile *q, cnc_real_t t)
-+{
-+ cnc_real_t t2, t5, t6;
-+ cnc_real_t k = CNC_PI/(2.0*q->Ts);
-+
-+ t2 = q->Ta - q->Ts;
-+ t5 = q->To + q->Ts;
-+ t6 = q->To + q->Ta - q->Ts;
-+
-+ if (t <= q->Ts) {
-+ return (q->Aref/2.0)*( t - cnc_sin(2.0*k*t)/(2.0*k) );
-+ } else if (t <= (q->Ta - q->Ts)) {
-+ return q->Aref*(t - q->Ts) + q->v1;
-+ } else if (t <= q->Ta) {
-+ return (q->Aref/2.0)*( (t-t2) + cnc_sin(2.0*k*(t-t2))/(2.0*k) )
-+ + q->v2;
-+ } else if (t <= q->To) {
-+ return (q->v1 + q->v2);
-+ } else if (t <= t5) {
-+ return -(q->Aref/2.0) *
-+ ( (t - q->To) - cnc_sin(2.0*k*(t - q->To))/(2.0*k) )
-+ + (q->v1 + q->v2);
-+ } else if (t <= t6) {
-+ return -q->Aref*(t-t5) + q->v2;
-+ } else {
-+ return -(q->Aref/2.0)*( (t-t6) + cnc_sin(2.0*k*(t-t6))/(2.0*k) )
-+ + q->v1;
-+ }
-+}
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_quintic.h sys/dev/cnc/cnc_quintic.h
---- sys.ORIG/dev/cnc/cnc_quintic.h Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_quintic.h Tue Jun 5 23:48:28 2007
- <at> <at> -0,0 +1,16 <at> <at>
-+/* Public domain */
-+
-+struct cnc_quintic_profile {
-+ cnc_real_t F; /* User-given feed rate */
-+ cnc_real_t v0; /* User-given min velocity */
-+ cnc_real_t Aref; /* Effective acceleration */
-+ cnc_real_t Ts; /* Domain of third-order sine */
-+ cnc_real_t Ta; /* Total acceleration time */
-+ cnc_real_t To; /* Total time before deceleration */
-+ cnc_real_t v1; /* Velocity at Ts */
-+ cnc_real_t v2; /* Velocity at Ta-Ts */
-+};
-+
-+int cnc_quintic_init(struct cnc_quintic_profile *, const struct cnc_insn *,
-+ cnc_real_t);
-+cnc_real_t cnc_quintic_step(const struct cnc_quintic_profile *, cnc_real_t);
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_servo.c sys/dev/cnc/cnc_servo.c
---- sys.ORIG/dev/cnc/cnc_servo.c Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_servo.c Wed Jun 6 23:45:33 2007
- <at> <at> -0,0 +1,227 <at> <at>
-+/* $OpenBSD$ */
-+
-+/*
-+ * Copyright (c) 2007 Hypertriton, Inc. <http://www.hypertriton.com/>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * Stepper/servo motor control with step/direction signal.
-+ */
-+
-+#include <sys/param.h>
-+#include <sys/queue.h>
-+#include <sys/fcntl.h>
-+#include <sys/vnode.h>
-+#include <sys/systm.h>
-+#include <sys/kernel.h>
-+#include <sys/device.h>
-+#include <sys/pool.h>
-+#include <sys/conf.h>
-+#include <sys/lock.h>
-+
-+#include <sys/gpio.h>
-+#include <sys/cnc.h>
-+
-+#include <dev/gpio/gpiovar.h>
-+
-+#include <dev/cnc/cnc_devicevar.h>
-+#include <dev/cnc/cncvar.h>
-+#include <dev/cnc/cnc_servovar.h>
-+
-+int servo_match(struct device *, void *, void *);
-+void servo_attach(struct device *, struct device *, void *);
-+int servo_detach(struct device *, int);
-+int servo_activate(struct device *, enum devact);
-+
-+struct cfattach servo_ca = {
-+ sizeof(struct servo_softc),
-+ servo_match,
-+ servo_attach,
-+ servo_detach,
-+ servo_activate
-+};
-+
-+struct cfdriver servo_cd = {
-+ NULL, "servo", DV_DULL
-+};
-+
-+int
-+servo_match(struct device *parent, void *match, void *aux)
-+{
-+ struct cfdata *cf = match;
-+
-+ return (strcmp(cf->cf_driver->cd_name, "servo") == 0);
-+}
-+
-+void
-+servo_attach(struct device *parent, struct device *self, void *aux)
-+{
-+ struct servo_softc *sc = (struct servo_softc *)self;
-+ struct gpio_attach_args *ga = aux;
-+ int caps, ctl;
-+
-+ /* Generic CNC device initialization. */
-+ if (cnc_device_attach(sc, CNC_DEVICE_SERVO) == -1)
-+ goto fail;
-+
-+ /* Check that we have enough pins */
-+ if (gpio_npins(ga->ga_mask) != SERVO_NPINS) {
-+ printf(": invalid pin mask\n");
-+ return;
-+ }
-+
-+ /* Map pins */
-+ sc->sc_gpio = ga->ga_gpio;
-+ sc->sc_map.pm_map = sc->__map;
-+ if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
-+ &sc->sc_map)) {
-+ printf(": can't map pins\n");
-+ return;
-+ }
-+
-+ /* Configure STEP pin (output). Initialize to LOW. */
-+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, SERVO_PIN_STEP);
-+ if (!(caps & GPIO_PIN_OUTPUT)) {
-+ printf(": STEP pin is unable to drive output\n");
-+ goto fail;
-+ }
-+ printf(": STEP[%d]", sc->sc_map.pm_map[SERVO_PIN_STEP]);
-+ ctl = GPIO_PIN_OUTPUT;
-+ if (caps & GPIO_PIN_PUSHPULL) { ctl |= GPIO_PIN_PUSHPULL; }
-+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, SERVO_PIN_STEP, ctl);
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SERVO_PIN_STEP, GPIO_PIN_LOW);
-+ sc->sc_step = 0;
-+
-+ /* Configure DIR pin (output). Initialize to LOW. */
-+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, SERVO_PIN_DIR);
-+ if (!(caps & GPIO_PIN_OUTPUT)) {
-+ printf(": DIR pin is unable to drive output\n");
-+ goto fail;
-+ }
-+ printf(" DIR[%d]", sc->sc_map.pm_map[SERVO_PIN_DIR]);
-+ ctl = GPIO_PIN_OUTPUT;
-+ if (caps & GPIO_PIN_PUSHPULL) { ctl |= GPIO_PIN_PUSHPULL; }
-+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, SERVO_PIN_DIR, ctl);
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SERVO_PIN_DIR, GPIO_PIN_LOW);
-+ sc->sc_dir = 0;
-+
-+ printf("\n");
-+ return;
-+fail:
-+ gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
-+}
-+
-+int
-+servo_detach(struct device *self, int flags)
-+{
-+ return (cnc_device_detach(self));
-+}
-+
-+int
-+servo_activate(struct device *self, enum devact act)
-+{
-+ return (cnc_device_activate(self));
-+}
-+
-+void
-+servo_set_dir(void *arg, int dir)
-+{
-+ struct servo_softc *sc = arg;
-+
-+ if (sc->sc_dir != dir) {
-+ sc->sc_dir = dir;
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SERVO_PIN_DIR,
-+ dir ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
-+ }
-+}
-+
-+void
-+servo_step(void *arg, int dir)
-+{
-+ struct servo_softc *sc = arg;
-+
-+ if (sc->sc_dir != dir) {
-+ sc->sc_dir = dir;
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SERVO_PIN_DIR,
-+ (dir == 1) ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
-+ }
-+ sc->sc_step = !sc->sc_step;
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SERVO_PIN_STEP,
-+ sc->sc_step ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
-+}
-+
-+#if 0
-+void
-+servo_accel_test(void *p)
-+{
-+ struct servo_softc *sc = p;
-+ int j, k, delay;
-+ int slow = 8000;
-+ int fast = 800;
-+ int steady = 10000;
-+ int accel = 100;
-+ int decel = 100;
-+
-+ printf("%s: velocity test\n", sc->sc_cdev.cd_dev.dv_xname);
-+
-+ delay = slow;
-+ k = 0;
-+ while (1) {
-+ sc->sc_step = !sc->sc_step;
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SERVO_PIN_STEP,
-+ sc->sc_step ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
-+ for (j = 0; j < delay; j++)
-+ ;;
-+ if (++k == accel) {
-+ k = 0;
-+ if (delay > fast) {
-+ delay -= 10;
-+ } else {
-+ if (--steady == 0)
-+ goto next;
-+ }
-+ }
-+ }
-+next:
-+ delay = fast;
-+ k = 0;
-+ while (1) {
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SERVO_PIN_STEP,
-+ sc->sc_step ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
-+ for (j = 0; j < delay; j++)
-+ ;;
-+ if (++k == decel) {
-+ k = 0;
-+ if (delay < slow) {
-+ delay += 10;
-+ } else {
-+ goto out;
-+ }
-+ }
-+ }
-+out:
-+ printf("%s: velocity test done\n", sc->sc_cdev.cd_dev.dv_xname);
-+ return;
-+}
-+#endif
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_servovar.h sys/dev/cnc/cnc_servovar.h
---- sys.ORIG/dev/cnc/cnc_servovar.h Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_servovar.h Thu May 24 05:43:01 2007
- <at> <at> -0,0 +1,18 <at> <at>
-+/* $OpenBSD$ */
-+/* Public domain */
-+
-+#define SERVO_NPINS 2
-+#define SERVO_PIN_STEP 0
-+#define SERVO_PIN_DIR 1
-+
-+struct servo_softc {
-+ struct cnc_device sc_cdev;
-+ void *sc_gpio;
-+ struct gpio_pinmap sc_map;
-+ int __map[SERVO_NPINS];
-+ int sc_step; /* last step */
-+ int sc_dir; /* last direction */
-+};
-+
-+void servo_set_dir(void *, int);
-+void servo_step(void *, int);
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_sin.S sys/dev/cnc/cnc_sin.S
---- sys.ORIG/dev/cnc/cnc_sin.S Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_sin.S Mon May 21 11:41:14 2007
- <at> <at> -0,0 +1,25 <at> <at>
-+/* $OpenBSD: s_sin.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
-+/*
-+ * Written by J.T. Conklin <jtc-S783fYmB3Ccdnm+yROfE0A <at> public.gmane.org>.
-+ * Public domain.
-+ */
-+
-+#include <machine/asm.h>
-+
-+ENTRY(cnc_sin)
-+ fldl 4(%esp)
-+ fsin
-+ fnstsw %ax
-+ andw $0x400,%ax
-+ jnz 1f
-+ ret
-+1: fldpi
-+ fadd %st(0)
-+ fxch %st(1)
-+2: fprem1
-+ fnstsw %ax
-+ andw $0x400,%ax
-+ jnz 2b
-+ fstp %st(1)
-+ fsin
-+ ret
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_spindle.c sys/dev/cnc/cnc_spindle.c
---- sys.ORIG/dev/cnc/cnc_spindle.c Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_spindle.c Sat May 26 23:21:14 2007
- <at> <at> -0,0 +1,303 <at> <at>
-+/* $OpenBSD$ */
-+
-+/*
-+ * Copyright (c) 2007 Hypertriton, Inc. <http://www.hypertriton.com/>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * Spindle controller with closed-loop control (direction output,
-+ * tachometer input and increment/decrement output signals).
-+ */
-+
-+#include <sys/param.h>
-+#include <sys/queue.h>
-+#include <sys/fcntl.h>
-+#include <sys/vnode.h>
-+#include <sys/systm.h>
-+#include <sys/kernel.h>
-+#include <sys/device.h>
-+#include <sys/pool.h>
-+#include <sys/conf.h>
-+#include <sys/lock.h>
-+
-+#include <sys/gpio.h>
-+#include <sys/cnc.h>
-+
-+#include <dev/gpio/gpiovar.h>
-+
-+#include <dev/cnc/cnc_devicevar.h>
-+#include <dev/cnc/cncvar.h>
-+#include <dev/cnc/cnc_spindlevar.h>
-+
-+int spindle_match(struct device *, void *, void *);
-+void spindle_attach(struct device *, struct device *, void *);
-+int spindle_detach(struct device *, int);
-+int spindle_activate(struct device *, enum devact);
-+
-+struct cfattach spindle_ca = {
-+ sizeof(struct spindle_softc),
-+ spindle_match,
-+ spindle_attach,
-+ spindle_detach,
-+ spindle_activate
-+};
-+
-+struct cfdriver spindle_cd = {
-+ NULL, "spindle", DV_DULL
-+};
-+
-+int
-+spindle_match(struct device *parent, void *match, void *aux)
-+{
-+ struct cfdata *cf = match;
-+
-+ return (strcmp(cf->cf_driver->cd_name, "spindle") == 0);
-+}
-+
-+void
-+spindle_attach(struct device *parent, struct device *self, void *aux)
-+{
-+ struct spindle_softc *sc = (struct spindle_softc *)self;
-+ struct gpio_attach_args *ga = aux;
-+ int caps, ctl;
-+
-+ /* Generic CNC device initialization. */
-+ if (cnc_device_attach(sc, CNC_DEVICE_SPINDLE) == -1)
-+ goto fail;
-+
-+ /* Check that we have enough pins */
-+ if (gpio_npins(ga->ga_mask) != SPINDLE_NPINS) {
-+ printf(": invalid pin mask\n");
-+ return;
-+ }
-+
-+ /* Map pins */
-+ sc->sc_gpio = ga->ga_gpio;
-+ sc->sc_map.pm_map = sc->__map;
-+ if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
-+ &sc->sc_map)) {
-+ printf(": can't map pins\n");
-+ return;
-+ }
-+
-+ /* Initialize DIR pin to LOW (CW) */
-+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_DIR);
-+ if (!(caps & GPIO_PIN_OUTPUT)) {
-+ printf(": DIR pin is unable to drive output\n");
-+ goto fail;
-+ }
-+ printf(": DIR[%d]", sc->sc_map.pm_map[SPINDLE_PIN_DIR]);
-+ ctl = GPIO_PIN_OUTPUT;
-+ if (caps & GPIO_PIN_PUSHPULL) { ctl |= GPIO_PIN_PUSHPULL; }
-+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_DIR, ctl);
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_DIR, GPIO_PIN_LOW);
-+ sc->sc_dir = 1;
-+
-+ /* Initialize INCREMENT pin to LOW. */
-+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_INCREMENT);
-+ if (!(caps & GPIO_PIN_OUTPUT)) {
-+ printf(": INCREMENT pin is unable to drive output\n");
-+ goto fail;
-+ }
-+ printf(" INCREMENT[%d]", sc->sc_map.pm_map[SPINDLE_PIN_INCREMENT]);
-+ ctl = GPIO_PIN_OUTPUT;
-+ if (caps & GPIO_PIN_PUSHPULL) { ctl |= GPIO_PIN_PUSHPULL; }
-+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_INCREMENT, ctl);
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_INCREMENT,
-+ GPIO_PIN_LOW);
-+
-+ /* Initialize DECREMENT pin to LOW. */
-+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_DECREMENT);
-+ if (!(caps & GPIO_PIN_OUTPUT)) {
-+ printf(": DECREMENT pin is unable to drive output\n");
-+ goto fail;
-+ }
-+ printf(" DECREMENT[%d]", sc->sc_map.pm_map[SPINDLE_PIN_DECREMENT]);
-+ ctl = GPIO_PIN_OUTPUT;
-+ if (caps & GPIO_PIN_PUSHPULL) { ctl |= GPIO_PIN_PUSHPULL; }
-+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_DECREMENT, ctl);
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_DECREMENT,
-+ GPIO_PIN_LOW);
-+
-+ /* Configure TACHO pin for input. */
-+ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_TACHO);
-+ if (!(caps & GPIO_PIN_INPUT)) {
-+ printf(": TACHO pin is unable to read input\n");
-+ goto fail;
-+ }
-+ printf(" TACHO[%d]", sc->sc_map.pm_map[SPINDLE_PIN_TACHO]);
-+ ctl = GPIO_PIN_INPUT;
-+ gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_TACHO, ctl);
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_TACHO,
-+ GPIO_PIN_LOW);
-+
-+ /* Initialize the structure. */
-+ sc->sc_speed = 0;
-+ sc->sc_speed_tacho = 0;
-+ sc->sc_speed_max = 3000; /* XXX configure */
-+
-+ printf("\n");
-+ return;
-+fail:
-+ gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
-+}
-+
-+int
-+spindle_detach(struct device *self, int flags)
-+{
-+ return (cnc_device_detach(self));
-+}
-+
-+int
-+spindle_activate(struct device *self, enum devact act)
-+{
-+ return (cnc_device_activate(self));
-+}
-+
-+void
-+spindle_set_dir(void *arg, int dir)
-+{
-+ struct spindle_softc *sc = arg;
-+
-+ if (sc->sc_dir != dir) {
-+ sc->sc_dir = dir;
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_DIR,
-+ dir ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
-+ }
-+}
-+
-+void
-+spindle_step(void *arg, int dir)
-+{
-+ struct spindle_softc *sc = arg;
-+
-+ if (sc->sc_dir != dir) {
-+ sc->sc_dir = dir;
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_DIR,
-+ dir ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
-+ }
-+ sc->sc_step = !sc->sc_step;
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_STEP,
-+ sc->sc_step ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
-+}
-+
-+/*
-+ * Process CNC_SPINDLE_SPEED instruction. We do this by pulsing the
-+ * INCREMENT or DECREMENT pin until the tachometer returns the target
-+ * speed, within error.
-+ */
-+int
-+spindle_speed(void *p, struct cnc_insn *insn)
-+{
-+ struct spindle_softc *sc = p;
-+
-+ if (insn.i_spindle_speed > sc->sc_speed_max) {
-+ printf("%s: %u rpm exceeds spindle limit (%u)\n",
-+ sc->sc_dev.dv_xname, insn.i_spindle_speed,
-+ sc->sc_speed_max);
-+ return (EINVAL);
-+ }
-+ sc->sc_speed = insn.i_spindle_speed;
-+ /* TODO */
-+ return (0);
-+}
-+
-+/* Process CNC_SPINDLE_START instruction. */
-+/* XXX block until target speed is reached? */
-+int
-+spindle_start(void *p, struct cnc_insn *insn)
-+{
-+ struct spindle_softc *sc = p;
-+
-+ /* TODO */
-+ printf("%s: startup\n", sc->sc_dev.dv_xname);
-+ return (0);
-+}
-+
-+/* Process CNC_SPINDLE_STOP instruction. */
-+/* XXX block until target speed is reached? */
-+int
-+spindle_stop(void *p, struct cnc_insn *insn)
-+{
-+ struct spindle_softc *sc = p;
-+
-+ /* TODO */
-+ printf("%s: spindle stopped\n", sc->sc_dev.dv_xname);
-+ return (0);
-+}
-+
-+#if 0
-+void
-+spindle_accel_test(void *p)
-+{
-+ struct spindle_softc *sc = p;
-+ int j, k, delay;
-+ int slow = 8000;
-+ int fast = 800;
-+ int steady = 10000;
-+ int accel = 100;
-+ int decel = 100;
-+
-+ printf("%s: velocity test\n", sc->sc_cdev.cd_dev.dv_xname);
-+
-+ delay = slow;
-+ k = 0;
-+ while (1) {
-+ sc->sc_step = !sc->sc_step;
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_STEP,
-+ sc->sc_step ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
-+ for (j = 0; j < delay; j++)
-+ ;;
-+ if (++k == accel) {
-+ k = 0;
-+ if (delay > fast) {
-+ delay -= 10;
-+ } else {
-+ if (--steady == 0)
-+ goto next;
-+ }
-+ }
-+ }
-+next:
-+ delay = fast;
-+ k = 0;
-+ while (1) {
-+ gpio_pin_write(sc->sc_gpio, &sc->sc_map, SPINDLE_PIN_STEP,
-+ sc->sc_step ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
-+ for (j = 0; j < delay; j++)
-+ ;;
-+ if (++k == decel) {
-+ k = 0;
-+ if (delay < slow) {
-+ delay += 10;
-+ } else {
-+ goto out;
-+ }
-+ }
-+ }
-+out:
-+ printf("%s: velocity test done\n", sc->sc_cdev.cd_dev.dv_xname);
-+ return;
-+}
-+#endif
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_spindlevar.h sys/dev/cnc/cnc_spindlevar.h
---- sys.ORIG/dev/cnc/cnc_spindlevar.h Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_spindlevar.h Sat May 26 23:21:03 2007
- <at> <at> -0,0 +1,23 <at> <at>
-+/* $OpenBSD$ */
-+/* Public domain */
-+
-+#define SPINDLE_NPINS 4
-+#define SPINDLE_PIN_DIR 0 /* direction signal (0=CW, 1=CCW) */
-+#define SPINDLE_PIN_TACHO 1 /* tachometer input (1 pulse/rev) */
-+#define SPINDLE_PIN_INCREMENT 2 /* speed controller increment */
-+#define SPINDLE_PIN_DECREMENT 3 /* speed controller decrement */
-+
-+struct spindle_softc {
-+ struct cnc_device sc_cdev;
-+ void *sc_gpio;
-+ struct gpio_pinmap sc_map;
-+ int __map[SERVO_NPINS];
-+ int sc_dir; /* current direction (1=CW, -1=CCW) */
-+ int sc_speed; /* desired speed (rpm) */
-+ u_int sc_speed_tacho; /* last measured speed (rpm) */
-+ u_int sc_speed_max; /* maximum allowed speed (rpm) */
-+};
-+
-+int spindle_speed(void *, struct cnc_insn *);
-+int spindle_start(void *, struct cnc_insn *);
-+int spindle_stop(void *, struct cnc_insn *);
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cnc_sqrt.S sys/dev/cnc/cnc_sqrt.S
---- sys.ORIG/dev/cnc/cnc_sqrt.S Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cnc_sqrt.S Tue May 22 05:05:54 2007
- <at> <at> -0,0 +1,12 <at> <at>
-+/* $OpenBSD: e_sqrt.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */
-+/*
-+ * Written by J.T. Conklin <jtc-S783fYmB3Ccdnm+yROfE0A <at> public.gmane.org>.
-+ * Public domain.
-+ */
-+
-+#include <machine/asm.h>
-+
-+ENTRY(cnc_sqrt)
-+ fldl 4(%esp)
-+ fsqrt
-+ ret
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/cncvar.h sys/dev/cnc/cncvar.h
---- sys.ORIG/dev/cnc/cncvar.h Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/cncvar.h Thu Jun 7 03:21:45 2007
- <at> <at> -0,0 +1,34 <at> <at>
-+/* $OpenBSD$ */
-+/* Public domain */
-+
-+#include "cnc_math.h"
-+#include "cnc_quintic.h"
-+
-+extern const char *cnc_insn_names[];
-+extern struct cnc_device *cnc_servos[CNC_NAXES];
-+extern struct cnc_device *cnc_spindles[CNC_MAX_SPINDLES];
-+extern struct cnc_device *cnc_estops[CNC_MAX_ESTOPS];
-+extern int cnc_nservos;
-+extern int cnc_nspindles;
-+extern int cnc_nestops;
-+extern u_long cnc_timebase;
-+
-+int cncopen(dev_t, int, int, struct proc *);
-+int cncclose(dev_t, int, int, struct proc *);
-+int cncioctl(dev_t, u_long, caddr_t, int, struct proc *);
-+int cncwrite(dev_t, struct uio *, int);
-+void cncattach(int);
-+int cncdetach(struct device *, int);
-+int cncactivate(struct device *, enum devact);
-+
-+void cnc_cal_update(void *);
-+int cnc_move(struct cnc_insn *);
-+int cnc_prog_exec(void);
-+void cnc_prog_reset(void);
-+__inline void cnc_move_axis(enum cnc_axis, int);
-+__inline struct cnc_device *cnc_get_spindle(int);
-+__inline void cnc_move_delay(const struct cnc_quintic_profile *, cnc_real_t,
-+ cnc_real_t);
-+u_long cnc_calibrate_timebase(void);
-+__inline int cnc_estop_raised(void);
-+
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/files.cnc sys/dev/cnc/files.cnc
---- sys.ORIG/dev/cnc/files.cnc Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/files.cnc Tue Jun 5 00:30:31 2007
- <at> <at> -0,0 +1,33 <at> <at>
-+# $OpenBSD$
-+
-+# CNC controller interface.
-+pseudo-device cnc
-+file dev/cnc/cnc.c cnc needs-flag
-+file dev/cnc/cnc_device.c cnc needs-flag
-+file dev/cnc/cnc_math.c cnc needs-flag
-+file dev/cnc/cnc_sin.S cnc needs-flag
-+file dev/cnc/cnc_sqrt.S cnc needs-flag
-+file dev/cnc/cnc_cbrt.c cnc needs-flag
-+file dev/cnc/cnc_log10.S cnc needs-flag
-+file dev/cnc/cnc_modf.c cnc needs-flag
-+file dev/cnc/cnc_quintic.c cnc needs-flag
-+
-+# Servo or stepping motor with clock/direction interface.
-+device servo
-+attach servo at gpio
-+file dev/cnc/cnc_servo.c servo needs-flag
-+
-+# Machine tool spindle controller.
-+device spindle
-+attach spindle at gpio
-+file dev/cnc/cnc_spindle.c spindle needs-flag
-+
-+# Control panel for CNC machining equipment.
-+device cncpanel
-+attach cncpanel at gpio
-+file dev/cnc/cnc_panel.c cncpanel needs-flag
-+
-+# Emergency stop button and/or limit switches.
-+device estop
-+attach estop at gpio
-+file dev/cnc/cnc_estop.c estop needs-flag
-diff -uNr --exclude=.svn sys.ORIG/dev/cnc/math_private.h sys/dev/cnc/math_private.h
---- sys.ORIG/dev/cnc/math_private.h Wed Dec 31 20:00:00 1969
-+++ sys/dev/cnc/math_private.h Wed May 30 00:13:18 2007
- <at> <at> -0,0 +1,154 <at> <at>
-+/* $OpenBSD: math_private.h,v 1.6 2002/02/16 21:27:27 millert Exp $ */
-+/*
-+ * ====================================================
-+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-+ *
-+ * Developed at SunPro, a Sun Microsystems, Inc. business.
-+ * Permission to use, copy, modify, and distribute this
-+ * software is freely granted, provided that this notice
-+ * is preserved.
-+ * ====================================================
-+ */
-+
-+/*
-+ * from: <at> (#)fdlibm.h 5.1 93/09/24
-+ */
-+
-+#ifndef _MATH_PRIVATE_H_
-+#define _MATH_PRIVATE_H_
-+
-+#include <sys/types.h>
-+
-+/* The original fdlibm code used statements like:
-+ n0 = ((*(int*)&one)>>29)^1; * index of high word *
-+ ix0 = *(n0+(int*)&x); * high word of x *
-+ ix1 = *((1-n0)+(int*)&x); * low word of x *
-+ to dig two 32 bit words out of the 64 bit IEEE floating point
-+ value. That is non-ANSI, and, moreover, the gcc instruction
-+ scheduler gets it wrong. We instead use the following macros.
-+ Unlike the original code, we determine the endianness at compile
-+ time, not at run time; I don't see much benefit to selecting
-+ endianness at run time. */
-+
-+/* A union which permits us to convert between a double and two 32 bit
-+ ints. */
-+
-+/*
-+ * The arm32 port is little endian except for the FP word order which is
-+ * big endian.
-+ */
-+
-+#if (BYTE_ORDER == BIG_ENDIAN) || defined(arm32)
-+
-+typedef union
-+{
-+ double value;
-+ struct
-+ {
-+ u_int32_t msw;
-+ u_int32_t lsw;
-+ } parts;
-+} ieee_double_shape_type;
-+
-+#endif
-+
-+#if (BYTE_ORDER == LITTLE_ENDIAN) && !defined(arm32)
-+
-+typedef union
-+{
-+ double value;
-+ struct
-+ {
-+ u_int32_t lsw;
-+ u_int32_t msw;
-+ } parts;
-+} ieee_double_shape_type;
-+
-+#endif
-+
-+/* Get two 32 bit ints from a double. */
-+
-+#define EXTRACT_WORDS(ix0,ix1,d) \
-+do { \
-+ ieee_double_shape_type ew_u; \
-+ ew_u.value = (d); \
-+ (ix0) = ew_u.parts.msw; \
-+ (ix1) = ew_u.parts.lsw; \
-+} while (0)
-+
-+/* Get the more significant 32 bit int from a double. */
-+
-+#define GET_HIGH_WORD(i,d) \
-+do { \
-+ ieee_double_shape_type gh_u; \
-+ gh_u.value = (d); \
-+ (i) = gh_u.parts.msw; \
-+} while (0)
-+
-+/* Get the less significant 32 bit int from a double. */
-+
-+#define GET_LOW_WORD(i,d) \
-+do { \
-+ ieee_double_shape_type gl_u; \
-+ gl_u.value = (d); \
-+ (i) = gl_u.parts.lsw; \
-+} while (0)
-+
-+/* Set a double from two 32 bit ints. */
-+
-+#define INSERT_WORDS(d,ix0,ix1) \
-+do { \
-+ ieee_double_shape_type iw_u; \
-+ iw_u.parts.msw = (ix0); \
-+ iw_u.parts.lsw = (ix1); \
-+ (d) = iw_u.value; \
-+} while (0)
-+
-+/* Set the more significant 32 bits of a double from an int. */
-+
-+#define SET_HIGH_WORD(d,v) \
-+do { \
-+ ieee_double_shape_type sh_u; \
-+ sh_u.value = (d); \
-+ sh_u.parts.msw = (v); \
-+ (d) = sh_u.value; \
-+} while (0)
-+
-+/* Set the less significant 32 bits of a double from an int. */
-+
-+#define SET_LOW_WORD(d,v) \
-+do { \
-+ ieee_double_shape_type sl_u; \
-+ sl_u.value = (d); \
-+ sl_u.parts.lsw = (v); \
-+ (d) = sl_u.value; \
-+} while (0)
-+
-+/* A union which permits us to convert between a float and a 32 bit
-+ int. */
-+
-+typedef union
-+{
-+ float value;
-+ u_int32_t word;
-+} ieee_float_shape_type;
-+
-+/* Get a 32 bit int from a float. */
-+
-+#define GET_FLOAT_WORD(i,d) \
-+do { \
-+ ieee_float_shape_type gf_u; \
-+ gf_u.value = (d); \
-+ (i) = gf_u.word; \
-+} while (0)
-+
-+/* Set a float from a 32 bit int. */
-+
-+#define SET_FLOAT_WORD(d,i) \
-+do { \
-+ ieee_float_shape_type sf_u; \
-+ sf_u.word = (i); \
-+ (d) = sf_u.value; \
-+} while (0)
-+
-+#endif /* _MATH_PRIVATE_H_ */
-diff -uNr --exclude=.svn sys.ORIG/sys/cnc.h sys/sys/cnc.h
---- sys.ORIG/sys/cnc.h Wed Dec 31 20:00:00 1969
-+++ sys/sys/cnc.h Thu Jun 7 03:12:20 2007
- <at> <at> -0,0 +1,135 <at> <at>
-+/* $OpenBSD$ */
-+/* Public domain */
-+
-+#ifndef _SYS_CNC_H_
-+#define _SYS_CNC_H_
-+
-+#include <sys/stdint.h>
-+
-+#define CNC_BUF_SIZE 1024 /* size of instruction buffer */
-+#define CNC_MAX_AXES 3 /* max axes (min. 1) */
-+#define CNC_NAXES CNC_MAX_AXES
-+#define CNC_MAX_SPINDLES 2 /* max spindles */
-+#define CNC_MAX_ESTOPS 13 /* max e-stops/limit switches */
-+
-+enum cnc_axis {
-+ CNC_X, CNC_Y, CNC_Z,
-+ CNC_A, CNC_B, CNC_C
-+};
-+
-+typedef uint64_t cnc_step_t;
-+typedef int64_t cnc_pos_t;
-+typedef int64_t cnc_time_t;
-+
-+enum cnc_insn_type {
-+ /* servo(4) operations */
-+ CNC_MOVE, /* coordinated move to given position */
-+ CNC_SET_INTERP, /* set interpolation mode */
-+ /* spindle(4) operations */
-+ CNC_SPINDLE_DIR, /* change current direction */
-+ CNC_SPINDLE_SPEED, /* set revolutions per minute */
-+ CNC_SPINDLE_START, /* start spindle rotation */
-+ CNC_SPINDLE_STOP, /* stop spindle rotation */
-+ /* atc(4) operations */
-+ CNC_ATC_PREPARE, /* prepare tool for next change */
-+ CNC_ATC_CHANGE, /* change tool in spindle */
-+ /* laser(4) operations */
-+ CNC_LASER_ON, /* TTL trigger high */
-+ CNC_LASER_OFF, /* TTL trigger low */
-+ CNC_LASER_CURRENT, /* set steady-state current */
-+ /* pickplace(4) operations */
-+ CNC_PICKPLACE_REEL, /* advance specified reel */
-+ CNC_PICKPLACE_SUCTION, /* enable suction cup vacuum */
-+ CNC_PICKPLACE_RELEASE, /* release suction cup vacuum */
-+ /* miscellaneous */
-+ CNC_PREEMPT, /* delay (with interrupts reenabled) */
-+ CNC_DWELL, /* precise delay (no interrupts) */
-+ CNC_COOL_MIST, /* toggle mist coolant */
-+ CNC_COOL_FLOOD, /* toggle flood or thru-tool coolant */
-+ CNC_COOL_VORTEX, /* toggle vortex tube */
-+ CNC_LAST_INSN
-+};
-+
-+/* Mode of interpolation between coordinates */
-+enum cnc_interp_mode {
-+ CNC_INTERP_LINEAR, /* linear interpolation */
-+ CNC_INTERP_LAST
-+};
-+
-+/* Velocity curve generation algorithm */
-+enum cnc_velocity_mode {
-+ CNC_VEL_BLENDED_SCURVE, /* blended s-curve (second-order) */
-+ CNC_VEL_SQUARED_SINE, /* squared sine (third-order) */
-+};
-+
-+/* Position vector */
-+typedef struct cnc_vector {
-+ cnc_pos_t v[CNC_NAXES];
-+} cnc_vec_t;
-+
-+/*
-+ * Kinematic limits. These values must be adjusted based on the physical
-+ * limits of the motors and of the load they are driving.
-+ */
-+struct cnc_kinematics {
-+ int k_Ts; /* third-order jerk limit (ms) */
-+ int k_Vmax; /* maximum velocity (steps/sec) */
-+};
-+
-+/* Program instruction */
-+struct cnc_insn {
-+ enum cnc_insn_type i_type;
-+ union {
-+ struct {
-+ cnc_vec_t i_pos; /* relative target coords */
-+ u_long i_v0; /* minimum velocity (steps/s) */
-+ u_long i_F; /* maximum velocity (steps/s) */
-+ u_long i_Amax; /* max acceleration (steps/ms^2) */
-+ u_long i_Jmax; /* max jerk (steps/ms^3) */
-+ } i_move;
-+ struct {
-+ int i_id; /* name of spindle */
-+ int i_dir; /* 1=CW, -1=CCW */
-+ u_int i_speed; /* speed in RPM */
-+ } i_spindle;
-+ enum cnc_interp_mode i_interp_mode; /* for SET_INTERP */
-+ cnc_step_t i_delay; /* for DWELL and PREEMPT */
-+ struct {
-+ int i_atc_id; /* name of ATC controller */
-+ int i_tool_idx; /* name of tool */
-+ int i_tgt_spindle; /* name of target spindle */
-+ } i_atc;
-+ int i_laser_current; /* for LASER_CURRENT */
-+ int i_pickplace_reel; /* for PICKPLACE_REEL */
-+ } i_arg;
-+#define i_pos i_arg.i_move.i_pos
-+#define i_F i_arg.i_move.i_F
-+#define i_v0 i_arg.i_move.i_v0
-+#define i_Amax i_arg.i_move.i_Amax
-+#define i_Jmax i_arg.i_move.i_Jmax
-+#define i_interp_mode i_arg.i_interp_mode
-+#define i_spindle_id i_arg.i_spindle.i_id
-+#define i_spindle_dir i_arg.i_spindle.i_dir
-+#define i_spindle_speed i_arg.i_spindle.i_speed
-+#define i_delay i_arg.i_delay
-+#define i_atc_id i_arg.i_atc.i_atc_id
-+#define i_atc_tool_idx i_arg.i_atc.i_tool_idx
-+#define i_atc_tgt_spindle i_arg.i_atc.i_tgt_spindle
-+#define i_laser_current i_arg.i_laser_current
-+ TAILQ_ENTRY(cnc_insn) prog;
-+};
-+
-+#define CNC_EXECPROG _IO('C', 0)
-+#define CNC_RESETPROG _IO('C', 1)
-+#define CNC_GETPOS _IOR('C', 2, struct cnc_vector)
-+#define CNC_SETPOS _IOWR('C', 3, struct cnc_vector)
-+#define CNC_GETNSERVOS _IOR('C', 4, int)
-+#define CNC_GETNSPINDLES _IOR('C', 5, int)
-+#define CNC_GETKINLIMITS _IOR('C', 6, struct cnc_kinematics)
-+#define CNC_SETKINLIMITS _IOWR('C', 7, struct cnc_kinematics)
-+#define CNC_GETTIMEBASE _IOR('C', 8, u_long)
-+#define CNC_SETTIMEBASE _IOWR('C', 9, u_long)
-+#define CNC_CALTIMEBASE _IOWR('C', 10, u_long)
-+#define CNC_GETNESTOPS _IOR('C', 11, int)
-+
-+#endif /* !_SYS_CNC_H_ */
diff -uNr --exclude=.svn sys.ORIG/sys/conf.h sys/sys/conf.h
--- sys.ORIG/sys/conf.h Tue Aug 1 07:14:38 2006
+++ sys/sys/conf.h Thu Apr 26 08:51:48 2007
RSS Feed