diff --git a/cereal/log.capnp b/cereal/log.capnp index 70508f36e2..68ea3099b8 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -2440,6 +2440,14 @@ struct Microphone { filteredSoundPressureWeightedDb @2 :Float32; } +struct Touch { + sec @0 :Int64; + usec @1 :Int64; + type @2 :UInt8; + code @3 :Int32; + value @4 :Int32; +} + struct Event { logMonoTime @0 :UInt64; # nanoseconds valid @67 :Bool = true; @@ -2520,6 +2528,9 @@ struct Event { logMessage @18 :Text; errorLogMessage @85 :Text; + # touch frame + touch @135 :List(Touch); + # navigation navInstruction @82 :NavInstruction; navRoute @83 :NavRoute; diff --git a/cereal/services.py b/cereal/services.py index 771338f507..b8728fefdd 100755 --- a/cereal/services.py +++ b/cereal/services.py @@ -22,6 +22,7 @@ _services: dict[str, tuple] = { "temperatureSensor2": (True, 2., 200), "gpsNMEA": (True, 9.), "deviceState": (True, 2., 1), + "touch": (True, 20.), "can": (True, 100., 2053), # decimation gives ~3 msgs in a full segment "controlsState": (True, 100., 10), "selfdriveState": (True, 100., 10), diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index 48c916b146..49eb1e0fda 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -2,6 +2,7 @@ import os import json import queue +import struct import threading import time from collections import OrderedDict, namedtuple @@ -59,6 +60,32 @@ def set_offroad_alert_if_changed(offroad_alert: str, show_alert: bool, extra_tex prev_offroad_states[offroad_alert] = (show_alert, extra_text) set_offroad_alert(offroad_alert, show_alert, extra_text) +def touch_thread(end_event): + pm = messaging.PubMaster(["touch"]) + + event_format = "llHHi" + event_size = struct.calcsize(event_format) + event_frame = [] + + with open("/dev/input/by-path/platform-894000.i2c-event", "rb") as event_file: + while not end_event.is_set(): + event = event_file.read(event_size) + if event: + (sec, usec, etype, code, value) = struct.unpack(event_format, event) + if etype != 0 or code != 0 or value != 0: + touch = log.Touch.new_message() + touch.sec = sec + touch.usec = usec + touch.type = etype + touch.code = code + touch.value = value + event_frame.append(touch) + else: # end of frame, push new log + msg = messaging.new_message('touch', len(event_frame), valid=True) + msg.touch = event_frame + pm.send('touch', msg) + event_frame = [] + def hw_state_thread(end_event, hw_queue): """Handles non critical hardware state, and sends over queue""" @@ -420,6 +447,9 @@ def main(): threading.Thread(target=hardware_thread, args=(end_event, hw_queue)), ] + if TICI: + threads.append(threading.Thread(target=touch_thread, args=(end_event,))) + for t in threads: t.start()