initial commit
authortheStack <sebastian.falbesoner@gmail.com>
Sat, 12 Dec 2009 03:10:12 +0000 (04:10 +0100)
committertheStack <sebastian.falbesoner@gmail.com>
Sat, 12 Dec 2009 03:10:12 +0000 (04:10 +0100)
SerialPort_linux.py [new file with mode: 0644]
frprog.py [new file with mode: 0755]

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/frprog.py b/frprog.py
new file mode 100755 (executable)
index 0000000..a36d6d1
--- /dev/null
+++ b/frprog.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+import sys, time
+from SerialPort_linux import *
+
+# contains the last received checksum from a READ, WRITE or CHECKSUM command
+last_checksum = 0
+
+def sendByte(byte):
+       time.sleep(0.01) # just to get sure, wait 10ms
+       tty.write(chr(byte))
+       tty.flush()
+
+def sendWord(word):
+       sendByte(word & 0xFF)
+       sendByte((word >> 8) & 0xFF)
+
+def sendDWord(dword):
+       sendByte(dword & 0xFF)
+       sendByte((dword >> 8) & 0xFF)
+       sendByte((dword >> 16) & 0xFF)
+       sendByte((dword >> 24) & 0xFF)
+
+def recvByte():
+       return ord(tty.read())
+
+def recvChecksum():
+       global last_checksum
+       # get checksum
+       last_checksum = recvByte()
+       last_checksum |= (recvByte() << 8)
+
+def cmdREAD(address, size):
+       # send READ command
+       sendByte(0x01)
+       if (recvByte() != 0xF1):
+               raise Exception
+       sendByte(0x02)
+       if (recvByte() != 0x82):
+               raise Exception
+       # tell desired address and size
+       sendDWord(address)
+       sendWord(size)
+       # get binary stream of data
+       data = []
+       for i in range(0, size):
+               data.append(recvByte())
+       # get checksum
+       recvChecksum()
+       return data
+
+def cmdWRITE(address, size, data):
+       # send WRITE command
+       sendByte(0x01)
+       if (recvByte() != 0xF1):
+               raise Exception
+       sendByte(0x03)
+       if (recvByte() != 0x83):
+               raise Exception
+       # tell desired address and size
+       sendDWord(address)
+       sendWord(size)
+       # write binary stream of data
+       for i in range(0, size):
+               sendByte(data[i])
+       # get checksum
+       recvChecksum()
+
+def cmdBAUDRATE(baudrate):
+       global last_checksum
+
+       # send BAUDRATE command
+       sendByte(0x01)
+       if (recvByte() != 0xF1):
+               raise Exception
+       sendByte(0x06)
+       if (recvByte() != 0x86):
+               raise Exception
+       # send desired baudrate
+       sendByte(baudrate & 0xFF)
+       sendByte((baudrate >> 8) & 0xFF)
+       sendByte((baudrate >> 16) & 0xFF)
+       sendByte((baudrate >> 24) & 0xFF)
+
+print "Initializing serial port..."
+tty = SerialPort("/dev/ttyUSB0", 100, 9600)
+
+print "Please press RESET on your 1337 board..."
+
+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(19200)
+tty = SerialPort("/dev/ttyUSB0", 100, 19200)
+
+print
+
+# write something to the begin of the IRAM
+data = [255, 2, 3, 4]
+print "Writing", data, "to the IRAM..."
+cmdWRITE(0x00030000, 4, data)
+print "Received Checksum:", last_checksum
+print
+
+print "Reading from the IRAM again..."
+data2 = cmdREAD(0x00030000, 4)
+print "Received data:", data2, "Checksum:", last_checksum