PK#tJjTTcpsamd_kernel/__init__.py"""A Jupyter kernel for CircuitPython on CPSAMD""" from .kernel import __version__ PKDtJ=Vcpsamd_kernel/__main__.pyfrom ipykernel.kernelapp import IPKernelApp from .kernel import CpsamdKernel IPKernelApp.launch_instance(kernel_class=CpsamdKernel) PKLtJcpsamd_kernel/cpsamd.pyfrom serial import Serial from serial.tools.list_ports import comports CPSAMD_PID = 516 CPSAMD_VID = 3368 BAUDRATE = 115200 PARITY = 'N' def find_cpsamd(): """Returns the port for the first samd found connected to the computer.""" for port in comports(): if port.vid == CPSAMD_VID and port.pid == CPSAMD_PID: return port.device def connect(): """Returns a pySerial Serial object to talk to the samd""" #s = Serial(find_cpsamd(), BAUDRATE, parity=PARITY) # Hardcoded current device s = Serial('/dev/tty.usbmodem1421', BAUDRATE, parity=PARITY) s.write(b'\x03\x01') # Ctrl-C: interrupt, Ctrl-A: switch to raw REPL s.read_until(b'raw REPL') s.read_until(b'\r\n>') # Wait for prompt return s PKEtJ cpsamd_kernel/install.pyimport json import os import sys from jupyter_client.kernelspec import install_kernel_spec from IPython.utils.tempdir import TemporaryDirectory kernel_json = {"argv": [sys.executable, "-m", "cpsamd_kernel", "-f", "{connection_file}"], "display_name":"cpsamd", "language":"python", } def install_my_kernel_spec(user=True): with TemporaryDirectory() as td: os.chmod(td, 0o755) # Starts off as 700, not user readable with open(os.path.join(td, 'kernel.json'), 'w') as f: json.dump(kernel_json, f, sort_keys=True) # TODO: Copy resources once they're specified print('Installing cpsamd kernel spec') install_kernel_spec(td, 'cpsamd', user=user, replace=True) def _is_root(): try: return os.geteuid() == 0 except AttributeError: return False # assume not an admin on non-Unix platforms def main(argv=[]): user = '--user' in argv or not _is_root() install_my_kernel_spec(user=user) if __name__ == '__main__': main(argv=sys.argv) PKݓtJ`y cpsamd_kernel/kernel.pyimport ast import re import sys import time from ipykernel.kernelbase import Kernel from .cpsamd import connect __version__ = '0.1' class CpsamdKernel(Kernel): implementation = 'cpsamd_kernel' implementation_version = __version__ language_info = {'name': 'python', 'version': '3', 'mimetype': 'text/x-python', 'file_extension': '.py', 'codemirror_mode': {'name': 'python', 'version': 3}, 'pygments_lexer': 'python3', } help_links = [ {'text': 'cpsamd CircuitPython', 'url': 'http://github.com/willingc/cpsamd.git' }, ] banner = "Hey cpsamd! Time to create fablab-ulous things." def __init__(self, **kwargs): """Set up connection to cpsamd""" super().__init__(**kwargs) self.serial = connect() def run_code(self, code): """Run a string of code, return strings for stdout and stderr""" self.serial.write(code.encode('utf-8') + b'\x04') result = bytearray() while not result.endswith(b'\x04>'): time.sleep(0.1) result.extend(self.serial.read_all()) assert result.startswith(b'OK') out, err = result[2:-2].split(b'\x04', 1) return out.decode('utf-8', 'replace'), err.decode('utf-8', 'replace') def do_execute(self, code, silent, store_history=True, user_expressions=None, allow_stdin=False): """Execute a user's code cell""" out, err = self.run_code(code) if out: self.send_response(self.iopub_socket, 'stream', { 'name': 'stdout', 'text': out }) if err: self.send_response(self.iopub_socket, 'stream', { 'name': 'stderr', 'text': err }) return {'status': 'ok', 'execution_count': self.execution_count, 'payload': [], 'user_expressions': {}} def _eval(self, expr): out, err = self.run_code('print({})'.format(expr)) return ast.literal_eval(out) def do_complete(self, code, cursor_pos): """Support code completion""" code = code[:cursor_pos] m = re.search(r'(\w+\.)*(\w+)?$', code) if m: prefix = m.group() if '.' in prefix: obj, prefix = prefix.rsplit('.') names = self._eval('dir({})'.format(obj)) else: names = self._eval('dir()') matches = [n for n in names if n.startswith(prefix)] return {'matches': matches, 'cursor_start': cursor_pos - len(prefix), 'cursor_end': cursor_pos, 'metadata': {}, 'status': 'ok'} else: return {'matches': [], 'cursor_start': cursor_pos, 'cursor_end': cursor_pos, 'metadata': {}, 'status': 'ok'} PK!H;@QP!cpsamd_kernel-0.1.dist-info/WHEEL1 0 RZq+D-Dv;_[*7Fp ܦpv/fݞoL(*IPK!H(Ӓd$cpsamd_kernel-0.1.dist-info/METADATATn0+K%g HQIP7TN[LKc5rȒ+EQJ͛b< 38O/،+̠uNdGYzΊwM9| 蠃8 WFP OE>aߌ5q!XFkLKF;!r4 JԞ\gǗ#Ѻ  /W7AŅp0GԆb?O}I%KX $>(d<ȭufU=˝۴IG<Lt@]I+ܳTcoX >>9ЊrבۢiXQh.*ÃD:VZj[o]. !|[>pOyX2G'_ئ6ؼhs*d hhhC o1сi;+G wCM>=kǺ>m.٤M\ʮ: ,/7n}.!Q`ѣ9ދ1쉞"%JYo3 >Cϭx3 -^3eE]łeyN,dߋOz,e(^fi]_a*Jg22Qe8$VPK!H|W=k"cpsamd_kernel-0.1.dist-info/RECORD}ɒ@{? TQ [ (6-R,P觟Ü2FwN,.˯qLmxt~&PQd(pEK1=6@P?9iTG:*B?5\AE٭"rw/)͟ -M<7.+6AS \Eb [y1a];jQryB4dy7:j=YDM aD啿;iqa)wjnc|NPr4'Q_,AAQQFy#RV>m/~/\ͨG^@܃ Xݑ 17 JACC".;]qCJxM5zҋHOm}K>PK#tJjTTcpsamd_kernel/__init__.pyPKDtJ=Vcpsamd_kernel/__main__.pyPKLtJGcpsamd_kernel/cpsamd.pyPKEtJ jcpsamd_kernel/install.pyPKݓtJ`y cpsamd_kernel/kernel.pyPK!H;@QP!cpsamd_kernel-0.1.dist-info/WHEELPK!H(Ӓd$0cpsamd_kernel-0.1.dist-info/METADATAPK!H|W=k"cpsamd_kernel-0.1.dist-info/RECORDPKO