+;* bootROM, a very small bootloader for $NAME
+;*
+;* protocol details:
+;* abbrv: H = Host, CPU = C
+;*
+;* value/cmd | direction | comment
+;* ------------------------------------------------------------
+;* 'H' | H -> C | enter bootROM ("HI")
+;* 'O' | C -> H | ack bootROM entry ("OH HAI")
+;*
+;* 'W'0xZZZZZZZZ0xYYYYYYYY| H -> C | write instr (0xYY...Y) to
+;* | address (0xZZ...Z)
+;* 'D' | C -> H | instr write done
+;*
+;* 'R'0xZZZZZZZZ | H -> C | read instr from address (0xZZ..Z)
+;* 'F'0xYYYYYYYY | C -> H | instr read done and return instr
+;*
+;* 'Q'0xZZZZZZZZ0xYYYYYYYY| H -> C | write data (0xYY...Y) to
+;* | address (0xZZ...Z)
+;* 'A' | C -> H | data write done
+;*
+;* 'T'0xZZZZZZZZ | H -> C | read data from address (0xZZ..Z)
+;* 'G'0xYYYYYYYY | C -> H | read done and return data
+;*
+;* 'J'0xZZZZZZZZ | H -> C | jump to address (0xZZ...Z)
+;*/
.data
.text
call recv_byte
lls r1, r1, 8
- or r1, r0, r1
+ or r0, r0, r1
+ xor r1, r1, r1
- addi r0, r1, 0
ret
;-----
cmpi r0, 0x57 ; 'W'
breq- bt_W
- cmpi r0, 0x52 ; 'R'
- breq- bt_R
+ ;cmpi r0, 0x52 ; 'R'
+ ;breq- bt_R
cmpi r0, 0x51 ; 'Q'
breq- bt_Q
br bootrom
bt_W:
- ; call recv_word ; receive addr
- ; stw r0, PADDR(r11)
- ; call recv_word ; receive instr
- ; stw r0, PDATA(r11)
- ; ldi r1, 0x44 ; 'D'
- ; call send_byte
+ ldi r1, 0x57 ; 'W'
+ call send_byte
+ call recv_word ; receive addr
+ stw r0, PADDR(r11)
+ call recv_word ; receive instr
+ stw r0, PDATA(r11)
+ ldi r1, 0x44 ; 'D'
+ call send_byte
br bootrom
-bt_R:
+;bt_R: ;lesen von IRAM wird nicht unterstuetzt
;call recv_word ; receive addr
;mov r2, r0
;ldi r1, 0x46 ; 'F'
;ldx r1, 0(r2)
;call send_word
;br bootrom
- br tehend
bt_Q:
+ ldi r1, 0x51 ; 'Q'
+ call send_byte
call recv_word ; receive addr
- mov r6, r0
+ addi r6, r0, 0
call recv_word ; receive data
stw r0, 0(r6)
ldi r1, 0x41 ; 'A'
br bootrom
bt_J:
- call recv_word
- brr r0
-
tehend:
xor r1, r1, r1
ldi r1, 0x41 ; 'A'
+.data
+str:
+ .fill 0x41424344
+ .fill 0x0a0d0000
.text
+ .define UART_BASE, 0x2000
+ .define UART_STATUS, 0x0
+ .define UART_RECV, 0xc
+ .define UART_TRANS, 0x8
+
+ .define UART_TRANS_EMPTY, 0x1
+ .define UART_RECV_NEW, 0x2
start:
br+ main ;br+
br+ main
ret
main:
- ldi r0, 0x2000 ; status...
- ldi r1, 0x200b ;ldi r1, 8203
- ldi r2, 0x200c ;ldi r2, 8204
- ; ldi r4, 0x2024 ;ldi r4, 8228
- ; ldi r5, 3 ; enable interrupts
- ; stw r5, 0(r4)
- ldw r5, 0(r0)
- andx r5, 0x2
+ ldi r10, UART_BASE@lo
+ ldih r10, UART_BASE@hi
+ ldw r5, UART_STATUS(r10)
+ andx r5, UART_RECV_NEW
brzs+ main ; no new data?
- ldw r7, 0(r2) ; load data
+ ldw r7, UART_RECV(r10) ; load data
+
+ xor r1, r1, r1
+ xor r2, r2, r2
+ xor r3, r3, r3
+ ; ldi r1, str
+ ; ldi r1, 0x58
+ ; stb r1, str(r3)
+ ldw r1, str(r3)
+ ldi r2, 6
+ ;call send_string
+ call send_byte
+
+main2:
+ ldw r5, UART_STATUS(r10)
+ andx r5, UART_RECV_NEW
+ brzs+ main2 ; no new data?
+ ldw r7, UART_RECV(r10) ; load data
uartnrdy:
ldw r5, 0(r0)
- andx r5, 0x1
+ andx r5, UART_TRANS_EMPTY
brnz+ uartnrdy ; transmitter not ready yet?
- stw r7, 0(r1) ; send zeh shit!
- br main ; back to usual stuff
+ stw r7, UART_TRANS(r10) ; send zeh shit!
+ br main2 ; back to usual stuff
+
+send_string:
+ ; r1 = addr
+ ; r2 = len
+ addi r3, r1, 0
+send_string_int:
+ cmpi r2, 0
+ reteq-
+ ldb r1, 0(r3)
+ call send_byte
+ addi r2, r2, 0-1
+ addi r3, r3, 1
+ br send_string_int
+
+send_byte:
+ ldw r9, UART_STATUS(r10)
+ andx r9, UART_TRANS_EMPTY
+ brnz+ send_byte ; branch if not zero
+ stw r1, UART_TRANS(r10)
+ ret
when "0000111" => data_out <= x"eb000985"; -- call recv_byte
when "0001000" => data_out <= x"e4088800"; -- xor r1, r1, r1
when "0001001" => data_out <= x"ec800240"; -- cmpi r0, 0x48
- when "0001010" => data_out <= x"1b001803"; -- breq+ bt_H
+ when "0001010" => data_out <= x"1b001703"; -- breq+ bt_H
when "0001011" => data_out <= x"eb7ffe01"; -- br poll
when "0001100" => data_out <= x"e71d0000"; -- ldw r3, UART_STATUS(r10)
when "0001101" => data_out <= x"e2980008"; -- andx r3, UART_TRANS_EMPTY
when "0101000" => data_out <= x"e3080800"; -- or r1, r0, r1
when "0101001" => data_out <= x"eb7ff885"; -- call recv_byte
when "0101010" => data_out <= x"e508a000"; -- lls r1, r1, 8
- when "0101011" => data_out <= x"e3080800"; -- or r1, r0, r1
- when "0101100" => data_out <= x"e1008000"; -- addi r0, r1, 0
+ when "0101011" => data_out <= x"e3000800"; -- or r0, r0, r1
+ when "0101100" => data_out <= x"e4088800"; -- xor r1, r1, r1
when "0101101" => data_out <= x"eb000008"; -- ret
when "0101110" => data_out <= x"eb7ff605"; -- call recv_byte
when "0101111" => data_out <= x"e4088800"; -- xor r1, r1, r1
when "0110000" => data_out <= x"ec8002b8"; -- cmpi r0, 0x57
- when "0110001" => data_out <= x"1b000601"; -- breq- bt_W
- when "0110010" => data_out <= x"ec800290"; -- cmpi r0, 0x52
- when "0110011" => data_out <= x"1b000581"; -- breq- bt_R
- when "0110100" => data_out <= x"ec800288"; -- cmpi r0, 0x51
- when "0110101" => data_out <= x"1b000501"; -- breq- bt_Q
- when "0110110" => data_out <= x"ec8002a0"; -- cmpi r0, 0x54
- when "0110111" => data_out <= x"1b000781"; -- breq- bt_T
- when "0111000" => data_out <= x"ec800250"; -- cmpi r0, 0x4a
- when "0111001" => data_out <= x"1b000a01"; -- breq- bt_J
- when "0111010" => data_out <= x"ed080278"; -- ldi r1, 0x4f
- when "0111011" => data_out <= x"eb7fe885"; -- call send_byte
- when "0111100" => data_out <= x"eb7ff901"; -- br bootrom
- when "0111101" => data_out <= x"eb7ff881"; -- br bootrom
- when "0111110" => data_out <= x"eb000881"; -- br tehend
+ when "0110001" => data_out <= x"1b000501"; -- breq- bt_W
+ when "0110010" => data_out <= x"ec800288"; -- cmpi r0, 0x51
+ when "0110011" => data_out <= x"1b000881"; -- breq- bt_Q
+ when "0110100" => data_out <= x"ec8002a0"; -- cmpi r0, 0x54
+ when "0110101" => data_out <= x"1b000c01"; -- breq- bt_T
+ when "0110110" => data_out <= x"ec800250"; -- cmpi r0, 0x4a
+ when "0110111" => data_out <= x"1b000e81"; -- breq- bt_J
+ when "0111000" => data_out <= x"ed080278"; -- ldi r1, 0x4f
+ when "0111001" => data_out <= x"eb7fe985"; -- call send_byte
+ when "0111010" => data_out <= x"eb7ffa01"; -- br bootrom
+ when "0111011" => data_out <= x"ed0802b8"; -- ldi r1, 0x57
+ when "0111100" => data_out <= x"eb7fe805"; -- call send_byte
+ when "0111101" => data_out <= x"eb7ff185"; -- call recv_word
+ when "0111110" => data_out <= x"e7858004"; -- stw r0, PADDR(r11)
when "0111111" => data_out <= x"eb7ff085"; -- call recv_word
- when "1000000" => data_out <= x"e1300000"; -- mov r6, r0
- when "1000001" => data_out <= x"eb7fef85"; -- call recv_word
- when "1000010" => data_out <= x"e7830000"; -- stw r0, 0(r6)
- when "1000011" => data_out <= x"ed080208"; -- ldi r1, 0x41
- when "1000100" => data_out <= x"eb7fe405"; -- call send_byte
- when "1000101" => data_out <= x"eb7ff481"; -- br bootrom
+ when "1000000" => data_out <= x"e7858008"; -- stw r0, PDATA(r11)
+ when "1000001" => data_out <= x"ed080220"; -- ldi r1, 0x44
+ when "1000010" => data_out <= x"eb7fe505"; -- call send_byte
+ when "1000011" => data_out <= x"eb7ff581"; -- br bootrom
+ when "1000100" => data_out <= x"ed080288"; -- ldi r1, 0x51
+ when "1000101" => data_out <= x"eb7fe385"; -- call send_byte
when "1000110" => data_out <= x"eb7fed05"; -- call recv_word
- when "1000111" => data_out <= x"e1100000"; -- mov r2, r0
- when "1001000" => data_out <= x"ed080238"; -- ldi r1, 0x47
- when "1001001" => data_out <= x"eb7fe185"; -- call send_byte
- when "1001010" => data_out <= x"e7090000"; -- ldw r1, 0(r2)
- when "1001011" => data_out <= x"eb7fe305"; -- call send_word
+ when "1000111" => data_out <= x"e1300000"; -- addi r6, r0, 0
+ when "1001000" => data_out <= x"eb7fec05"; -- call recv_word
+ when "1001001" => data_out <= x"e7830000"; -- stw r0, 0(r6)
+ when "1001010" => data_out <= x"ed080208"; -- ldi r1, 0x41
+ when "1001011" => data_out <= x"eb7fe085"; -- call send_byte
when "1001100" => data_out <= x"eb7ff101"; -- br bootrom
- when "1001101" => data_out <= x"eb7fe985"; -- call recv_word
- when "1001110" => data_out <= x"eb800000"; -- brr r0
- when "1001111" => data_out <= x"e4088800"; -- xor r1, r1, r1
- when "1010000" => data_out <= x"ed080208"; -- ldi r1, 0x41
- when "1010001" => data_out <= x"eb7fdd85"; -- call send_byte
- when "1010010" => data_out <= x"e4088800"; -- xor r1, r1, r1
- when "1010011" => data_out <= x"ed080210"; -- ldi r1, 0x42
- when "1010100" => data_out <= x"eb7fdc05"; -- call send_byte
- when "1010101" => data_out <= x"e4088800"; -- xor r1, r1, r1
- when "1010110" => data_out <= x"ed080218"; -- ldi r1, 0x43
- when "1010111" => data_out <= x"eb7fda85"; -- call send_byte
+ when "1001101" => data_out <= x"eb7fe985"; -- call recv_word
+ when "1001110" => data_out <= x"e1100000"; -- mov r2, r0
+ when "1001111" => data_out <= x"ed080238"; -- ldi r1, 0x47
+ when "1010000" => data_out <= x"eb7fde05"; -- call send_byte
+ when "1010001" => data_out <= x"e7090000"; -- ldw r1, 0(r2)
+ when "1010010" => data_out <= x"eb7fdf85"; -- call send_word
+ when "1010011" => data_out <= x"eb7fed81"; -- br bootrom
+ when "1010100" => data_out <= x"e4088800"; -- xor r1, r1, r1
+ when "1010101" => data_out <= x"ed080208"; -- ldi r1, 0x41
+ when "1010110" => data_out <= x"eb7fdb05"; -- call send_byte
+ when "1010111" => data_out <= x"e4088800"; -- xor r1, r1, r1
+ when "1011000" => data_out <= x"ed080210"; -- ldi r1, 0x42
+ when "1011001" => data_out <= x"eb7fd985"; -- call send_byte
+ when "1011010" => data_out <= x"e4088800"; -- xor r1, r1, r1
+ when "1011011" => data_out <= x"ed080218"; -- ldi r1, 0x43
+ when "1011100" => data_out <= x"eb7fd805"; -- call send_byte
-- just nop until rom end!
when others => data_out <= x"fd000000";
end case;
--- /dev/null
+SerialPort_linux.pyc
--- /dev/null
+all: pylint
+
+pylint: frprog.py
+ pylint --indent-string="\t" $<
--- /dev/null
+# -*- 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
--- /dev/null
+#!/usr/bin/env python
+"""
+Aufruf:
+./dtprog.py <dthexfile> [-d /dev/ttyXXX]
+
+bootROM, a very small bootloader for $NAME
+
+protocol details:
+abbrv: H = Host, CPU = C
+
+value/cmd | direction | comment
+------------------------------------------------------------
+'H' | H -> C | enter bootROM ("HI")
+'O' | C -> H | ack bootROM entry ("OH HAI")
+
+'W'0xZZZZZZZZ0xYYYYYYYY| H -> C | write instr (0xYY...Y) to
+ | address (0xZZ...Z)
+'D' | C -> H | instr write done
+
+'R'0xZZZZZZZZ | H -> C | read instr from address (0xZZ..Z)
+'F'0xYYYYYYYY | C -> H | instr read done and return instr
+
+'Q'0xZZZZZZZZ0xYYYYYYYY| H -> C | write data (0xYY...Y) to
+ | address (0xZZ...Z)
+'A' | C -> H | data write done
+
+'T'0xZZZZZZZZ | H -> C | read data from address (0xZZ..Z)
+'G'0xYYYYYYYY | C -> H | read done and return data
+
+'J'0xZZZZZZZZ | H -> C | jump to address (0xZZ...Z)
+"""
+import sys, time
+from SerialPort_linux import SerialPort, SerialPortException
+
+BAUDRATE = 9600
+SPLIT = 30
+
+class RAMSequence(object):
+ def __init__(self, type, address, data):
+ self.type = type
+ self.addr = address
+ self.data = data
+
+def sendbyte(byte):
+ """
+ send a byte to the TTY-device
+ """
+ tty.write(chr(byte))
+
+def sendword(word):
+ """
+ send a word to the TTY-device
+ """
+ sendbyte(word & 0xFF)
+ sendbyte((word >> 8) & 0xFF)
+
+def senddword(dword):
+ """
+ send a dword to the TTY-device
+ """
+ sendbyte((dword >> 24) & 0xFF)
+ sendbyte((dword >> 16) & 0xFF)
+ sendbyte((dword >> 8) & 0xFF)
+ sendbyte(dword & 0xFF)
+
+def recvbyte():
+ """
+ receive a byte from the TTY-device
+ """
+ return ord(tty.read())
+
+def recvword():
+ return (recvbyte() << 24) & (recvbyte() << 16) & (recvbyte() << 8) & recvbyte()
+
+def bootromexec():
+ sendbyte(0x4a) # 'J'
+
+def brwriteinstr(address, data):
+ """
+ send a WRITE-command (instr) to the bootROM-firmware
+ """
+ # send WRITE instr command
+ sendbyte(0x57) # 'W'
+ # time.sleep(0.01)
+ if (recvbyte() != 0x57): # 'W'
+ print "host: write instr fail (1)"
+ raise Exception
+ senddword(address)
+ senddword(data)
+ time.sleep(0.01)
+ if (recvbyte() != 0x44): # 'D'
+ print "host: write instr fail (2)"
+ raise Exception
+
+def brwritedata(address, data):
+ """
+ send a WRITE-command (data) to the bootROM-firmware
+ """
+ # send WRITE instr command
+ sendbyte(0x51) # 'Q'
+ # time.sleep(0.01)
+ if (recvbyte() != 0x51): # 'Q'
+ print "host: write data fail (1)"
+ raise Exception
+ senddword(address)
+ senddword(data)
+ time.sleep(0.01)
+ if (recvbyte() != 0x41): # 'A'
+ print "host: write data fail (2)"
+ raise Exception
+
+def readdthexfile(filename): # desired dthex filename
+ """
+ proceeds a dthex file
+ """
+ filep = open(filename, "r")
+ retval = [] # returns a list of FlashSequence objects
+ linecount = 0
+ for line in filep:
+ linecount += 1
+ # get rid of newline characters
+ line = line.strip()
+
+ # we're only interested in 0 or 1
+ if line[0:1] == "0" or line[0:1] == "1":
+ # TODO: checks...
+ type = int(line[0:1], 10)
+ addr = int(line[2:10], 16)/4
+ data = int(line[11:19], 16)
+ # print "type: ", type, "; addr: ", hex(addr), "; data: ", hex(data)
+ retval.append(RAMSequence(type, addr, data))
+ filep.close()
+ return retval
+
+def usage(execf):
+ """
+ print usage of dtprog
+ """
+ print "Usage: " + execf + " <target dthex-file> [-d DEVICE]"
+
+def main(argv=None):
+ """
+ main function of frprog
+ """
+ # check command line arguments
+ if argv is None:
+ argv = sys.argv
+
+ if len(argv) == 2 and (argv[1] == "-v" or argv[1] == "--version"):
+ print "Version: lulz"
+ return 0
+
+ if len(argv) != 2 and len(argv) != 4:
+ usage(argv[0])
+ return 1
+
+ # standard serial device to communicate with
+ device = "/dev/ttyS0"
+
+ # overrule standard device if provided with -d
+ if len(argv) == 4:
+ if argv[2] == "-d":
+ device = argv[3]
+ else:
+ usage(argv[0])
+ return 1
+
+ # read in data from mhx-files before starting
+ try:
+ ramseqs = readdthexfile(argv[1])
+ except IOError, error:
+ print argv[0] + ": Error - couldn't open file " + error.filename + "!"
+ return 1
+
+ print "Initializing serial port... (", device, ")"
+ global tty
+ tty = SerialPort(device, 100, BAUDRATE)
+
+ while True:
+ tty.write('H')
+ tty.flush()
+ try:
+ if tty.read() == 'O':
+ break
+ except SerialPortException:
+ # timeout happened, who cares ;-)
+ print "host: cpu in BootROM?"
+ pass
+ print "bootrom: OH HAI!"
+
+ # save time at this point for evaluating the duration at the end
+ starttime = time.time()
+ time.sleep(0.1)
+
+ sdots = SPLIT
+ print "host: Transfering program to BootROM",
+ print #TODO: remove ;)
+ # let the fun begin!
+ for seq in ramseqs:
+ print "RAMing(", seq.type, ") ", hex(seq.data), " at address ",
+ if seq.type == 1:
+ # instruction
+ print "", hex(seq.addr)
+ print "host: writing instr"
+ brwriteinstr(seq.addr, seq.data)
+ elif seq.type == 0:
+ # data
+ print "", hex(seq.addr*4)
+ print "host: writing data"
+ brwritedata(seq.addr * 4, seq.data)
+ tty.flush()
+
+ sdots = sdots - 1
+ if sdots == 0:
+ sys.stdout.write(".")
+ sys.stdout.flush()
+ sdots = SPLIT
+ print
+
+ bootromexec()
+ print "Program was started. Have fun!"
+ duration = time.time() - starttime
+ print "Procedure complete, took", round(duration, 2), "seconds."
+
+if __name__ == '__main__':
+ sys.exit(main())