]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/raspi_23/pulseio/PulseIn.py
proper deiniting
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / raspi_23 / pulseio / PulseIn.py
1 import array
2 import time
3 import subprocess
4 import os, signal
5 import traceback
6 import signal
7 import sysv_ipc
8 import atexit
9 import random
10
11 DEBUG = False
12 queues = []
13 procs = []
14
15 # The message queues live outside of python space, and must be formally cleaned!
16 def final():
17     if DEBUG:
18         print("Cleaning up message queues", queues)
19         print("Cleaning up processes", procs)
20     for q in queues:
21         q.remove()
22     for proc in procs:
23         proc.terminate()
24 atexit.register(final)
25
26 class PulseIn:
27     def __init__(self, pin, maxlen=2, idle_state=False):
28         self._pin = pin
29         self._maxlen = maxlen
30         self._idle_state = idle_state
31         self._queue_key = random.randint(1, 9999)
32         try:
33             self._mq = sysv_ipc.MessageQueue(None, flags=sysv_ipc.IPC_CREX)
34             if DEBUG:
35                 print("Message Queue Key: ", self._mq.key)
36             queues.append(self._mq)
37         except sysv_ipc.ExistentialError:
38             raise RuntimeError("Message queue creation failed")
39
40         cmd = ["/home/pi/libgpiod_pulsein/src/libgpiod_pulsein",
41                "--pulses", str(maxlen),
42                "--queue", str(self._mq.key)]
43         if not idle_state:
44             cmd.append("-i")
45         cmd.append("gpiochip0")
46         cmd.append(str(pin))
47         if DEBUG:
48             print(cmd)
49         
50         self._process = subprocess.Popen(cmd)
51         procs.append(self._process)
52
53         # wait for it to start up
54         if DEBUG:
55             print("Waiting for startup success message from subprocess")
56         message = self._mq.receive(type=2)
57         if message[0] != b'!':
58             raise RuntimeError("Could not establish message queue with subprocess")
59
60
61     def deinit(self):
62         # Clean up after ourselves
63         self._process.terminate()
64         procs.remove(self._process)
65         self._mq.remove()
66         queues.remove(self._mq)
67
68     def __enter__(self):
69         return self
70
71     def __exit__(self, exc_type, exc_value, tb):
72         self.deinit()
73
74     def resume(self, trigger_duration=0):
75         if trigger_duration != 0:
76             self._mq.send("t%d" % trigger_duration, True, type=1)
77         else:
78             self._mq.send("r", True, type=1)
79
80     def pause(self):
81         self._mq.send("p", True, type=1)
82
83     def clear(self):
84         self._mq.send("c", True, type=1)
85
86     def popleft(self):
87         self._mq.send("^", True, type=1)
88         message = self._mq.receive(type=2)
89         reply = int(message[0].decode('utf-8'))
90         if reply == -1:
91             reply = None
92         return reply
93
94     def __len__(self):
95         self._mq.send("l", True, type=1)
96         message = self._mq.receive(type=2)
97         return int(message[0].decode('utf-8'))