pkernel programmer init
authorBernhard Urban <lewurm@gmx.net>
Sun, 13 Dec 2009 07:03:18 +0000 (08:03 +0100)
committerBernhard Urban <lewurm@gmx.net>
Sun, 13 Dec 2009 07:03:18 +0000 (08:03 +0100)
.gitignore
SerialPort_linux.py [new file with mode: 0644]
kernel.py [new file with mode: 0755]

index 12320f8711d9fd5e2cab4a10c17712bfb79e552e..2e9fb11259dfacf0d648161c8f3db187c1fbd1cd 100644 (file)
@@ -6,3 +6,4 @@
 .deps/*
 cscope.out
 tags
+*.pyc
diff --git a/SerialPort_linux.py b/SerialPort_linux.py
new file mode 100644 (file)
index 0000000..de8d697
--- /dev/null
@@ -0,0 +1,329 @@
+# -*- coding: iso-8859-1 -*-\r
+\r
+##########################################################################\r
+# USPP Library (Universal Serial Port Python Library)\r
+#\r
+# Copyright (C) 2006 Isaac Barona <ibarona@gmail.com>\r
+# \r
+# This library is free software; you can redistribute it and/or\r
+# modify it under the terms of the GNU Lesser General Public\r
+# License as published by the Free Software Foundation; either\r
+# version 2.1 of the License, or (at your option) any later version.\r
+# \r
+# This library is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+# Lesser General Public License for more details.\r
+\r
+# You should have received a copy of the GNU Lesser General Public\r
+# License along with this library; if not, write to the Free Software\r
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
+##########################################################################\r
+\r
+#------------------------------------------------------------------------\r
+# Project:   USPP Library (Universal Serial Port Python Library)\r
+# Name:      SerialPort_linux.py\r
+# Purpose:   Handle low level access to serial port in linux.\r
+#\r
+# Author:    Isaac Barona Martinez <ibarona@gmail.com>\r
+# Copyright: (c) 2006 by Isaac Barona Martínez\r
+# Licence:   LGPL\r
+#\r
+# Created:   26 June 2001\r
+# History:\r
+# 20 January 2002 : Damien Geranton <dgeranton@voila.fr>\r
+#  - NCCS worry fixed. We must not use TERMIOS\r
+#  - inWaiting call fixed.\r
+# 09 Sept 2005: Douglas Jones <dfj23@drexel.edu>\r
+#  - readline method.\r
+#\r
+#-------------------------------------------------------------------------\r
+\r
+"""\r
+SerialPort_linux.py - Handle low level access to serial port in linux.\r
+\r
+See also uspp module docstring.\r
+\r
+\r
+"""\r
+\r
+import os\r
+from termios import *\r
+import fcntl\r
+import exceptions\r
+import struct\r
+import array\r
+\r
+\r
+class SerialPortException(exceptions.Exception):\r
+    """Exception raise in the SerialPort methods"""\r
+    def __init__(self, args=None):\r
+        self.args=args\r
+\r
+\r
+class SerialPort:\r
+    """Encapsulate methods for accesing to a serial port."""\r
+\r
+    BaudRatesDic={\r
+        110: B110,\r
+        300: B300,\r
+        600: B600,\r
+        1200: B1200,\r
+        2400: B2400,\r
+        4800: B4800, \r
+        9600: B9600,\r
+        19200: B19200,\r
+        38400: B38400,\r
+        57600: B57600,\r
+        115200: B115200\r
+        }\r
+    buf = array.array('h', '\000'*4)\r
+\r
+    def __init__(self, dev, timeout=None, speed=None, mode='232', params=None):\r
+        """Open the serial port named by the string 'dev'\r
+\r
+        'dev' can be any of the following strings: '/dev/ttyS0', '/dev/ttyS1',\r
+        ..., '/dev/ttySX' or '/dev/cua0', '/dev/cua1', ..., '/dev/cuaX'.\r
+        \r
+        'timeout' specifies the inter-byte timeout or first byte timeout\r
+        (in miliseconds) for all subsequent reads on SerialPort.\r
+        If we specify None time-outs are not used for reading operations\r
+        (blocking reading).\r
+        If 'timeout' is 0 then reading operations are non-blocking. It\r
+        specifies that the reading operation is to return inmediately\r
+        with the bytes that have already been received, even if\r
+        no bytes have been received.\r
+        \r
+        'speed' is an integer that specifies the input and output baud rate to\r
+        use. Possible values are: 110, 300, 600, 1200, 2400, 4800, 9600,\r
+        19200, 38400, 57600 and 115200.\r
+        If None a default speed of 9600 bps is selected.\r
+        \r
+        'mode' specifies if we are using RS-232 or RS-485. The RS-485 mode\r
+        is half duplex and use the RTS signal to indicate the\r
+        direction of the communication (transmit or recive).\r
+        Default to RS232 mode (at moment, only the RS-232 mode is\r
+        implemented).\r
+\r
+        'params' is a list that specifies properties of the serial \r
+        communication.\r
+        If params=None it uses default values for the number of bits\r
+        per byte (8), the parity (NOPARITY) and the number of stop bits (1)\r
+        else params is the termios package mode array to use for \r
+        initialization.\r
+\r
+        """\r
+        self.__devName, self.__timeout, self.__speed=dev, timeout, speed\r
+        self.__mode=mode\r
+        self.__params=params\r
+        try:\r
+               self.__handle=os.open(dev, os.O_RDWR)\r
+        except:\r
+            raise SerialPortException('Unable to open port')\r
+\r
+        self.__configure()\r
+\r
+    def __del__(self):\r
+        """Close the serial port and restore its initial configuration\r
+        \r
+        To close the serial port we have to do explicity: del s\r
+        (where s is an instance of SerialPort)\r
+        """\r
+       \r
+       tcsetattr(self.__handle, TCSANOW, self.__oldmode)\r
+       \r
+        try:\r
+            os.close(self.__handle)\r
+        except IOError:\r
+            raise SerialPortException('Unable to close port')\r
+\r
+\r
+    def __configure(self):\r
+        """Configure the serial port.\r
+\r
+        Private method called in the class constructor that configure the \r
+        serial port with the characteristics given in the constructor.\r
+        """\r
+        if not self.__speed:\r
+            self.__speed=9600\r
+        \r
+        # Save the initial port configuration\r
+        self.__oldmode=tcgetattr(self.__handle)\r
+        if not self.__params:\r
+            # self.__params is a list of attributes of the file descriptor\r
+            # self.__handle as follows:\r
+            # [c_iflag, c_oflag, c_cflag, c_lflag, c_ispeed, c_ospeed, cc]\r
+            # where cc is a list of the tty special characters.\r
+            self.__params=[]\r
+            # c_iflag\r
+            self.__params.append(IGNPAR)           \r
+            # c_oflag\r
+            self.__params.append(0)                \r
+            # c_cflag\r
+            self.__params.append(CS8|CLOCAL|CREAD) \r
+            # c_lflag\r
+            self.__params.append(0)                \r
+            # c_ispeed\r
+            self.__params.append(SerialPort.BaudRatesDic[self.__speed]) \r
+            # c_ospeed\r
+            self.__params.append(SerialPort.BaudRatesDic[self.__speed]) \r
+           cc=[0]*NCCS\r
+        if self.__timeout==None:\r
+            # A reading is only complete when VMIN characters have\r
+            # been received (blocking reading)\r
+            cc[VMIN]=1\r
+            cc[VTIME]=0\r
+        elif self.__timeout==0:\r
+            # Non-blocking reading. The reading operation returns\r
+            # inmeditately, returning the characters waiting to \r
+            # be read.\r
+            cc[VMIN]=0\r
+            cc[VTIME]=0\r
+        else:\r
+            # Time-out reading. For a reading to be correct\r
+            # a character must be recieved in VTIME*100 seconds.\r
+            cc[VMIN]=0\r
+            cc[VTIME]=self.__timeout/100\r
+        self.__params.append(cc)               # c_cc\r
+        \r
+        tcsetattr(self.__handle, TCSANOW, self.__params)\r
+    \r
+\r
+    def fileno(self):\r
+        """Return the file descriptor for opened device.\r
+\r
+        This information can be used for example with the \r
+        select funcion.\r
+        """\r
+        return self.__handle\r
+\r
+\r
+    def __read1(self):\r
+        """Read 1 byte from the serial port.\r
+\r
+        Generate an exception if no byte is read and self.timeout!=0 \r
+        because a timeout has expired.\r
+        """\r
+        byte = os.read(self.__handle, 1)\r
+        if len(byte)==0 and self.__timeout!=0: # Time-out\r
+            raise SerialPortException('Timeout')\r
+        else:\r
+            return byte\r
+            \r
+\r
+    def read(self, num=1):\r
+        """Read num bytes from the serial port.\r
+\r
+        Uses the private method __read1 to read num bytes. If an exception\r
+        is generated in any of the calls to __read1 the exception is reraised.\r
+        """\r
+        s=''\r
+        for i in range(num):\r
+            s=s+SerialPort.__read1(self)\r
+        \r
+        return s\r
+\r
+\r
+    def readline(self):\r
+        """Read a line from the serial port.  Returns input once a '\n'\r
+        character is found.\r
+        Douglas Jones (dfj23@drexel.edu) 09/09/2005.\r
+        """\r
+\r
+        s = ''\r
+        while not '\n' in s:\r
+            s = s+SerialPort.__read1(self)\r
+\r
+        return s \r
+\r
+        \r
+    def write(self, s):\r
+        """Write the string s to the serial port"""\r
+\r
+        os.write(self.__handle, s)\r
+\r
+        \r
+    def inWaiting(self):\r
+        """Returns the number of bytes waiting to be read"""\r
+       data = struct.pack("L", 0)\r
+        data=fcntl.ioctl(self.__handle, TIOCINQ, data)\r
+       return struct.unpack("L", data)[0]\r
+\r
+    def outWaiting(self):\r
+        """Returns the number of bytes waiting to be write\r
+        mod. by J.Grauheding\r
+        result needs some finetunning\r
+        """\r
+        rbuf=fcntl.ioctl(self.__handle, TIOCOUTQ, self.buf)\r
+        return rbuf\r
+\r
+    def getlsr(self):\r
+        """Returns the status of the UART LSR Register\r
+        J.Grauheding\r
+        """\r
+        rbuf=fcntl.ioctl(self.__handle, TIOCSERGETLSR, self.buf)\r
+        return ord(rbuf[0])\r
+\r
+    def get_temt(self):\r
+        """Returns the Tranmitterbuffer Empty Bit of LSR Register\r
+        J.Grauheding\r
+        test result against TIOCSER_TEMT\r
+        """\r
+        rbuf=fcntl.ioctl(self.__handle, TIOCSERGETLSR, self.buf)\r
+        return ord(rbuf[0]) & TIOSER_TEMT\r
+\r
+\r
+    def flush(self):\r
+        """Discards all bytes from the output or input buffer"""\r
+        tcflush(self.__handle, TCIOFLUSH)\r
+\r
+    def rts_on(self):\r
+        """ J.Grauheding """\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMGET, SerialPort.buf)\r
+        SerialPort.buf[1] = ord(rbuf[3]) | TIOCM_RTS\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMSET, SerialPort.buf)\r
+        return rbuf\r
+\r
+    def rts_off(self):\r
+        """ J.Grauheding """\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)\r
+        self.buf[1]=ord(rbuf[3]) & ~TIOCM_RTS\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMSET, self.buf)\r
+        return rbuf\r
+\r
+    def dtr_on(self):\r
+        """ J.Grauheding """\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMGET, SerialPort.buf)\r
+        SerialPort.buf[1] = ord(rbuf[3]) | TIOCM_DTR\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMSET, SerialPort.buf)\r
+        return rbuf\r
+\r
+    def dtr_off(self):\r
+        """ J.Grauheding """\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)\r
+        self.buf[1]=ord(rbuf[3]) & ~TIOCM_DTR\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMSET, self.buf)\r
+        return rbuf\r
+\r
+    def cts(self):\r
+        """ J.Grauheding """\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)\r
+        return ord(rbuf[3]) & TIOCM_CTS\r
+\r
+    def cd(self):\r
+        """ J.Grauheding """\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)\r
+        return ord(rbuf[3]) & TIOCM_CAR\r
+\r
+    def dsr(self):\r
+        """ J.Grauheding """\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)\r
+        return ord(rbuf[2]) & (TIOCM_DSR>>8)\r
+\r
+    def ri(self):\r
+        """ J.Grauheding """\r
+        rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)\r
+        return ord(rbuf[3]) & TIOCM_RNG\r
+\r
+        \r
+\r
diff --git a/kernel.py b/kernel.py
new file mode 100755 (executable)
index 0000000..89f7d7c
--- /dev/null
+++ b/kernel.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+import sys, time
+from SerialPort_linux import *
+
+# serial device to communicate with
+DEVICE="/dev/ttyUSB0"
+# baudrate used for communication with pkernel
+KERNEL_BAUDRATE=38400
+
+print "Initializing serial port..."
+tty = SerialPort(DEVICE, 500, INIT_BAUDRATE)
+
+while 1:
+       tty.write('V')
+       tty.flush()
+       try: 
+               if tty.read() == 'F':
+                       break
+       except SerialPortException: 
+               # timeout happened, who cares ;-)
+               pass
+
+print "OK, trying to set baudrate..."
+# set baudrate
+cmdBAUDRATE(REAL_BAUDRATE)
+tty = SerialPort(DEVICE, 100, REAL_BAUDRATE)
+
+"""
+print
+sendByte(0x01)
+print recvByte()
+sendByte(0x02)
+print recvByte()
+sys.exit(0)
+"""
+"""
+# execute (existing) program in ram
+cmdCALL(0x00033ffc)
+sys.exit(0)
+"""
+
+# read something from the IRAM
+#print cmdREAD(0x00030000, 32)
+
+#data = []
+#for i in range(0, 32):
+#      data.append(i)
+#cmdWRITE(0x00030000, 32, data)
+
+
+"""
+# write something to the begin of the IRAM
+data_wr = []
+checksum = 0
+for i in range(0, 0x400):
+       value = i%256
+       data_wr.append(value)
+       checksum = (checksum + value) % (2**16)
+
+print "Calculated checksum:", checksum
+print "Writing", data_wr, "to the IRAM..."
+cmdWRITE(0x00030000, len(data_wr), data_wr)
+print "Received Checksum:", last_checksum
+print
+
+print "Reading from the IRAM again..."
+data_re = cmdREAD(0x00030000, len(data_wr))
+print "Received data:", data_re, "Checksum:", last_checksum
+"""
+
+"""
+# see whats in the iram at the moment
+data_wr = []
+print "Reading from the IRAM..."
+data_re = cmdREAD(0x00030000, 0x10000-4)
+print "Received data:", data_re, "Checksum:", last_checksum
+"""
+
+"""
+# see whats in the dram at the moment
+data_wr = []
+print "Reading from the DRAM..."
+data_re = cmdREAD(0x0002C000, 0x10000-0xC000-4)
+print "Received data:", data_re, "Checksum:", last_checksum
+"""
+
+"""
+# blank the iram
+data_wr = []
+for i in range(0, 0x10000-4):
+       value = 0
+       data_wr.append(value)
+
+print "Writing", data_wr, "to the IRAM..."
+cmdWRITE(0x00030000, len(data_wr), data_wr)
+print "Received Checksum:", last_checksum
+print
+"""
+
+"""
+# blank the dram
+data_wr = []
+for i in range(0, 0x10000-0xC000-4):
+       value = 0
+       data_wr.append(value)
+
+print "Writing", data_wr, "to the DRAM..."
+cmdWRITE(0x0002C000, len(data_wr), data_wr)
+print "Received Checksum:", last_checksum
+print
+"""
+
+
+# write some data in the iram and try to execute it
+data_wr =[
+               0x9B,0x00,
+               0x0D,0x4e,
+               0xcf,0xf1,
+               0x16,0x01,
+               0x9b,0x05,
+               0x04,0xc7,
+               0xc1,0x06,
+               0x16,0x56,
+               0xe0,0xfb, #branch
+               0x9f,0xa0,0x9f,0xa0,0x9f,0xa0, #nop
+               0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
+               0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
+               0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
+               0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
+               0x9f,0xa0,0x9f,0xa0,0x9f,0xa0,
+               0x9f,0xa0,0x9f,0xa0,0x9f,0xa0]
+print "Writing", data_wr, "to the IRAM..."
+cmdWRITE(0x00030000, len(data_wr), data_wr)
+print "Received Checksum:", last_checksum
+print
+cmdCALL(0x00030000)