]> mj.ucw.cz Git - misc.git/commitdiff
Merge branch 'master' of git+ssh://git.ucw.cz/home/mj/GIT/misc master
authorMartin Mares <mj@ucw.cz>
Sat, 29 Jan 2022 20:13:07 +0000 (21:13 +0100)
committerMartin Mares <mj@ucw.cz>
Sat, 29 Jan 2022 20:13:07 +0000 (21:13 +0100)
sphinx/sphinx.c
verbose-copy.c [new file with mode: 0644]

index f70fd7e8ddcb09f3c1057249831fc2787e11ff66..5af69b346d09421196d1742f9fbfdc1ee651b8d6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     The Sphinx -- A Device for Asking Riddles at the Entrance to the Garage
  *
- *     (c) 2017 Martin Mares <mj@ucw.cz>
+ *     (c) 2017--2019 Martin Mares <mj@ucw.cz>
  */
 
 /*
@@ -9,13 +9,24 @@
  *
  *                     +-------------------+
  *                     | RESET*        VCC |
- *     button*         | PB3       PB2=SCK |
- *     output          | PB4      PB1=MISO |
+ *     button*         | PB3       PB2=SCK |   signal "closed" from drive*
+ *     output to drive | PB4      PB1=MISO |   corridor LED
  *                     | GND      PB0=MOSI |   diagnostic LED*
  *                     +-------------------+
  *
- *     Note that MOSI is used for programming, so the LED is connected
- *     via jumper, which must be open during programming.
+ *     Note that MISO, MOSI, and SCK are used for programming, so our signals
+ *     are connected via jumpers, which must be kept open during programming.
+ *
+ *     Connections to door control unit:
+ *
+ *             3 = +24V
+ *             1 = GND
+ *             2 = output
+ *
+ *     Connections to EP 161 module:
+ *
+ *             H1 = signal +
+ *             92 = signal -
  */
 
 #define F_CPU 1200000UL
@@ -45,24 +56,19 @@ static byte debounce;
 static byte pressed;
 static u16 press_timer;
 #define LONG_PRESS 150
-static byte second_timer;
-static byte unlocked;
-#define UNLOCK_SECONDS 60
+static u16 unlock_timer;
+#define UNLOCK_SECONDS 30
+static byte blink_timer;
 
 ISR(TIM0_COMPA_vect)
 {
+       // Generate output pulse
        if (out_pulse) {
                if (!--out_pulse)
                        PORTB &= ~B(PB4);
        }
 
-       if (!second_timer) {
-               second_timer = 100;
-               if (unlocked)
-                       unlocked--;
-       }
-       second_timer--;
-
+       // Debounce the button
        if (PINB & B(PB3)) {
                // Switch open
                if (debounce)
@@ -77,14 +83,33 @@ ISR(TIM0_COMPA_vect)
                        pressed = 1;
        }
 
-       if (unlocked) {
-               if (!(second_timer & 7))
-                       PORTB ^= B(PB0);
+       // PB2 is 0 if the door is fully closed,
+       // we need to set door_open if it is at least partially open.
+       byte door_open;
+       if (PINB & B(PB2)) {
+               door_open = 1;
+               PORTB |= B(PB1);
+               unlock_timer = UNLOCK_SECONDS * 60;
+       } else {
+               door_open = 0;
+               PORTB &= ~B(PB1);
+       }
+
+       // Locking
+       if (unlock_timer) {
                if (pressed) {
+                       PORTB &= ~B(PB0);
                        if (out_pulse < 2)
                                out_pulse = 2;
                        PORTB |= B(PB4);
-                       unlocked = UNLOCK_SECONDS;
+                       unlock_timer = UNLOCK_SECONDS * 100;
+               } else if (door_open) {
+                       if (!(blink_timer & 63))
+                               PORTB ^= B(PB0);
+               } else {
+                       if (!(blink_timer & 15))
+                               PORTB ^= B(PB0);
+                       unlock_timer--;
                }
        } else {
                if (!pressed) {
@@ -94,14 +119,13 @@ ISR(TIM0_COMPA_vect)
                        PORTB &= ~B(PB0);
                        if (press_timer < LONG_PRESS) {
                                press_timer++;
-                               if (press_timer == LONG_PRESS) {
-                                       out_pulse = OUT_PULSE_WIDTH;
-                                       PORTB |= B(PB4);
-                                       unlocked = UNLOCK_SECONDS;
-                               }
+                               if (press_timer == LONG_PRESS)
+                                       unlock_timer = UNLOCK_SECONDS * 100;
                        }
                }
        }
+
+       blink_timer++;
 }
 
 int main(void)
@@ -109,6 +133,13 @@ int main(void)
        // PB0: output for diagnostic LED
        DDRB |= B(PB0);
 
+       // PB1: output for corridor LED
+       PORTB &= ~B(PB1);
+       DDRB |= B(PB1);
+
+       // PB2: signal "door closed" from the drive, needs pull up
+       PORTB |= B(PB2);
+
        // PB3: button input, needs pull up
        PORTB |= B(PB3);
 
@@ -127,11 +158,13 @@ int main(void)
        // Copy mode
        for (;;) {
                sleep(10);
-               if (PINB & B(PB3)) {
+               if (PINB & B(PB2)) {
                        PORTB |= B(PB0);
+                       PORTB &= ~B(PB1);
                        PORTB &= ~B(PB4);
                } else {
                        PORTB &= ~B(PB0);
+                       PORTB |= B(PB1);
                        PORTB |= B(PB4);
                }
        }
diff --git a/verbose-copy.c b/verbose-copy.c
new file mode 100644 (file)
index 0000000..6b7c136
--- /dev/null
@@ -0,0 +1,96 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <linux/fs.h>
+
+// XXX: Assuming block size == 512
+
+int main(int argc, char **argv)
+{
+       if (argc != 3) {
+               fprintf(stderr, "Usage: %s <from> <to>\n", argv[0]);
+               return 1;
+       }
+
+       int fi = open(argv[1], O_RDONLY);
+       if (fi < 0) {
+               fprintf(stderr, "Cannot open source %s: %m\n", argv[1]);
+               return 1;
+       }
+
+       int fo = open(argv[2], O_WRONLY);
+       if (fo < 0) {
+               fprintf(stderr, "Cannot open destination %s: %m\n", argv[1]);
+               return 1;
+       }
+
+       struct stat sti, sto;
+       if (fstat(fi, &sti) < 0 || fstat(fo, &sto) < 0) {
+               fprintf(stderr, "Stat failed: %m\n");
+               return 1;
+       }
+       if (!S_ISBLK(sti.st_mode)) {
+               fprintf(stderr, "Input is not a block device\n");
+               return 1;
+       }
+       if (!S_ISBLK(sto.st_mode)) {
+               fprintf(stderr, "Output is not a block device\n");
+               return 1;
+       }
+
+       unsigned long leni, leno;
+       if (ioctl(fi, BLKGETSIZE, &leni) < 0 ||
+           ioctl(fo, BLKGETSIZE, &leno) < 0) {
+               fprintf(stderr, "Cannot get device size: %m\n");
+               return 1;
+       }
+       if (leni > leno) {
+               fprintf(stderr, "Will not fit: %ld > %ld\n", leni, leno);
+               return 1;
+       }
+
+#define BUFSIZE 65536
+       char *buf = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+       if (buf == MAP_FAILED) {
+               fprintf(stderr, "Cannot mmap buffer: %m\n");
+               return 1;
+       }
+
+       unsigned int remi = leni;
+       int verb = 1;
+       while (remi) {
+               int s = (remi < BUFSIZE/512) ? remi : BUFSIZE/512;
+               int l = read(fi, buf, s*512);
+               if (l < 0) {
+                       fprintf(stderr, "Read error: %m\n");
+                       return 1;
+               }
+               if (l != s*512) {
+                       fprintf(stderr, "Short read: %d of %d. Recovering.\n", l, s*512);
+               }
+               int w = write(fo, buf, l);
+               if (w < 0) {
+                       fprintf(stderr, "Write error: %m\n");
+                       return 1;
+               }
+               if (w != l) {
+                       fprintf(stderr, "Short write: %d of %d\n", w, l);
+                       return 1;
+               }
+               remi -= s;
+               if (!--verb) {
+                       printf("\rCopied %d of %d MB (%d%%)...", (int)((leni-remi)/2048), (int)((leni+2047)/2048),
+                               (int)((double)(leni-remi) / leni * 100));
+                       verb = 64;
+               }
+       }
+
+       printf("Copied %d MB                                       \n", (int)((leni+2047)/2048));
+       close(fo);
+       close(fi);
+       return 0;
+}