summaryrefslogtreecommitdiffstats
path: root/kernel/code/thing.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/code/thing.c')
-rw-r--r--kernel/code/thing.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/kernel/code/thing.c b/kernel/code/thing.c
new file mode 100644
index 0000000..d9b5eac
--- /dev/null
+++ b/kernel/code/thing.c
@@ -0,0 +1,207 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <linux/cp210x.h>
+
+/*
+ * bit 0: 1 left leg NPN base
+ * bit 1: 2 left leg PNP base
+ * bit 2: 4 right leg PNP base
+ * bit 3: 8 right leg NPN base
+ */
+
+#define LEFT_NPN_OFF 0
+#define LEFT_NPN_ON 1
+#define LEFT_PNP_OFF 2
+#define LEFT_PNP_ON 0
+
+#define LEFT_LOW (LEFT_NPN_ON | LEFT_PNP_OFF)
+#define LEFT_HI (LEFT_NPN_OFF | LEFT_PNP_ON)
+#define LEFT_OFF (LEFT_NPN_OFF | LEFT_PNP_OFF)
+
+#define RIGHT_NPN_OFF 0
+#define RIGHT_NPN_ON 8
+#define RIGHT_PNP_OFF 4
+#define RIGHT_PNP_ON 0
+
+
+#define RIGHT_LOW (RIGHT_NPN_ON | RIGHT_PNP_OFF)
+#define RIGHT_HI (RIGHT_NPN_OFF | RIGHT_PNP_ON)
+#define RIGHT_OFF (RIGHT_NPN_OFF | RIGHT_PNP_OFF)
+
+#define FORWARDS (RIGHT_LOW | LEFT_HI)
+#define BACKWARDS (RIGHT_HI | LEFT_LOW)
+#define OFF (RIGHT_OFF| LEFT_OFF)
+
+#define TIMEOUT 750000 /*75ms */
+#define RUN_IN 50
+#define RELEASE_TENSION 10
+
+int
+drive_motor (int fd, int dir)
+{
+ int i;
+
+ if (dir > 0)
+ {
+ printf (" Motor forwards\n");
+ i = FORWARDS;
+ }
+ else if (dir < 0)
+ {
+ printf (" Motor backwards\n");
+ i = BACKWARDS;
+ }
+ else
+ {
+ printf (" Motor off\n");
+ i = OFF;
+ }
+
+
+ return ioctl (fd, CPIOC_GPIOSET, &i);
+}
+
+int
+sensor_led_power (int fd, int on)
+{
+ int i = TIOCM_DTR;
+
+ printf (" Rotation sensor power %s\n", on ? "on" : "off");
+
+ return ioctl (fd, on ? TIOCMBIS : TIOCMBIC, &i);
+}
+
+
+static int
+count_steps (int fd, int count)
+{
+ struct timeval tv, tv_changed, tv_diff;
+ int cts, old_cts = -1;
+ int counted = 0;
+
+ printf (" Counting %d steps", count);
+
+ gettimeofday (&tv_changed, NULL);
+
+ while (count)
+ {
+ ioctl (fd, TIOCMGET, &cts);
+ cts &= TIOCM_CTS;
+
+ if (cts != old_cts)
+ {
+ if (cts)
+ {
+ counted++;
+ count--;
+ printf (".");
+ fflush (stdout);
+ }
+ gettimeofday (&tv_changed, NULL);
+ old_cts = cts;
+ }
+ gettimeofday (&tv, NULL);
+ timersub (&tv, &tv_changed, &tv_diff);
+
+ if (tv_diff.tv_sec || (tv_diff.tv_usec > TIMEOUT))
+ break;
+
+ }
+
+ printf ("%d steps\n", counted);
+ return counted;
+}
+
+
+
+
+static int
+drive_motor_home (int fd)
+{
+ int ret;
+ sensor_led_power (fd, 1);
+ drive_motor (fd, -1);
+ ret = count_steps (fd, -1);
+ drive_motor (fd, 0);
+ ret -= count_steps (fd, -1);
+ sensor_led_power (fd, 0);
+ return ret;
+}
+
+static int
+drive_motor_count (int fd, int dir, int steps)
+{
+ int ret;
+ sensor_led_power (fd, 1);
+ drive_motor (fd, dir);
+ ret = count_steps (fd, steps);
+ drive_motor (fd, 0);
+ ret += count_steps (fd, -1);
+ sensor_led_power (fd, 0);
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int overshoot, guard, pos, wanted, delta;
+
+ int fd = open (argv[1], O_RDWR);
+
+ if (fd < 0)
+ return -1;
+
+
+ pos = drive_motor_home (fd);
+
+ printf ("Motor was %d steps from home\n", pos);
+
+
+ if (argc == 2)
+ {
+ pos = drive_motor_count (fd, 1, RELEASE_TENSION);
+
+ printf ("Motor now %d steps from home\n", pos);
+ return 0;
+ }
+
+ pos = drive_motor_count (fd, 1, RUN_IN);
+
+ overshoot = pos - RUN_IN; /*overshot */
+
+ wanted = atoi (argv[2]);
+
+ delta = wanted - pos;
+ printf ("Now at %d want %d, delta %d\n", pos, wanted, delta);
+
+ guard = overshoot * 3;
+
+ if ((delta > -guard) && (delta < guard))
+ {
+ printf ("Too close\n");
+ pos += drive_motor_count (fd, 1, RUN_IN);
+ delta = wanted - pos;
+ printf ("Now at %d want %d, delta %d\n", pos, wanted, delta);
+ }
+
+
+ if (delta < 0)
+ {
+ pos -= drive_motor_count (fd, -1, (-delta) - overshoot);
+ }
+ else if (delta > 0)
+ {
+ pos += drive_motor_count (fd, 1, delta - overshoot);
+ }
+
+ printf ("Wanted %d steps, got %d steps\n", wanted, pos);
+
+ return 0;
+}