aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2021-02-07 16:59:18 -0500
committerKevin O'Connor <kevin@koconnor.net>2021-03-13 11:29:41 -0500
commita20f4a8759563737eb14e1047416ab049ba35b06 (patch)
treeb0d12e0a7ccfc6f764369edc1fb3e60dd7048d98
parent8b4ad34e22245694fad76e4856afd37f7478b3d6 (diff)
downloadkutter-a20f4a8759563737eb14e1047416ab049ba35b06.tar.gz
kutter-a20f4a8759563737eb14e1047416ab049ba35b06.tar.xz
kutter-a20f4a8759563737eb14e1047416ab049ba35b06.zip
serialhdl: Add support for communicating over a CAN bus
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--klippy/serialhdl.py47
-rw-r--r--scripts/klippy-requirements.txt1
2 files changed, 47 insertions, 1 deletions
diff --git a/klippy/serialhdl.py b/klippy/serialhdl.py
index 0d03b1bb..19b67088 100644
--- a/klippy/serialhdl.py
+++ b/klippy/serialhdl.py
@@ -4,7 +4,7 @@
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging, threading, os
-import serial
+import serial, can
import msgproto, chelper, util
@@ -102,6 +102,51 @@ class SerialReader:
self.ffi_lib.serialqueue_set_receive_window(
self.serialqueue, receive_window)
return True
+ def connect_canbus(self, canbus_uuid, canbus_nodeid, canbus_iface="can0"):
+ txid = canbus_nodeid * 2 + 256
+ filters = [{"can_id": txid+1, "can_mask": 0x7ff, "extended": False}]
+ # Prep for SET_NODEID command
+ try:
+ uuid = int(canbus_uuid, 16)
+ except ValueError:
+ uuid = -1
+ if uuid < 0 or uuid > 0xffffffffffff:
+ raise error("Invalid CAN uuid")
+ uuid = [(uuid >> (40 - i*8)) & 0xff for i in range(6)]
+ CANBUS_ID_ADMIN = 0x3f0
+ CMD_SET_NODEID = 0x01
+ set_id_cmd = [CMD_SET_NODEID] + uuid + [canbus_nodeid]
+ set_id_msg = can.Message(arbitration_id=CANBUS_ID_ADMIN,
+ data=set_id_cmd, is_extended_id=False)
+ # Start connection attempt
+ logging.info("Starting CAN connect")
+ start_time = self.reactor.monotonic()
+ while 1:
+ if self.reactor.monotonic() > start_time + 90.:
+ raise error("Unable to connect")
+ try:
+ bus = can.interface.Bus(channel=canbus_iface,
+ can_filters=filters,
+ bustype='socketcan')
+ bus.send(set_id_msg)
+ except can.CanError as e:
+ logging.warn("Unable to open CAN port: %s", e)
+ self.reactor.pause(self.reactor.monotonic() + 5.)
+ continue
+ bus.close = bus.shutdown # XXX
+ ret = self._start_session(bus, 'c', txid)
+ if not ret:
+ continue
+ # Verify correct canbus_nodeid to canbus_uuid mapping
+ try:
+ params = self.send_with_response('get_canbus_id', 'canbus_id')
+ got_uuid = bytearray(params['canbus_uuid'])
+ if got_uuid == bytearray(uuid):
+ break
+ except:
+ logging.exception("Error in canbus_uuid check")
+ logging.info("Failed to match canbus_uuid - retrying..")
+ self.disconnect()
def connect_pipe(self, filename):
logging.info("Starting connect")
start_time = self.reactor.monotonic()
diff --git a/scripts/klippy-requirements.txt b/scripts/klippy-requirements.txt
index 7d0c667c..c783ba53 100644
--- a/scripts/klippy-requirements.txt
+++ b/scripts/klippy-requirements.txt
@@ -6,3 +6,4 @@ cffi==1.12.2
pyserial==3.4
greenlet==0.4.15
Jinja2==2.10.1
+python-can==3.3.4