Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
amforth [2007-07-09 19:19] nik |
amforth [2007-07-24 16:10] (current) nik |
||
---|---|---|---|
Line 22: | Line 22: | ||
</file> | </file> | ||
+ | |||
+ | |||
==== hello world (aka, blinking an LED) ==== | ==== hello world (aka, blinking an LED) ==== | ||
Line 91: | Line 93: | ||
<file> | <file> | ||
: blink -- , blink PORTC5 for 100ms 20 35 c! 64 ms 0 35 c! 64 ms ; | : blink -- , blink PORTC5 for 100ms 20 35 c! 64 ms 0 35 c! 64 ms ; | ||
- | </file>**(64 ms)**<code> | + | </file>**(64 ms)** |
- | + | ||
- | </code> | + | |
NOTE: 100 is 0x64 in hex, so pauses for 100ms. | NOTE: 100 is 0x64 in hex, so pauses for 100ms. | ||
Line 99: | Line 99: | ||
then a word to blink multiple times: | then a word to blink multiple times: | ||
- | | ||
<file> | <file> | ||
: blinks n -- , blink n times 0 do blink loops ; | : blinks n -- , blink n times 0 do blink loops ; | ||
- | </file>so now | + | </file> |
- | + | ||
+ | so now | ||
<file> | <file> | ||
Line 159: | Line 159: | ||
</file> | </file> | ||
+ | |||
==== backing up ==== | ==== backing up ==== | ||
Line 180: | Line 181: | ||
---- | ---- | ||
- | [[amforth-upload.py.txt]] | ||
- | <file> | ||
- | </file> | + | |
---- | ---- | ||
Libarynth > Libarynth Web > AmForth r4 - 09 Mar 2007 - 11:56 | Libarynth > Libarynth Web > AmForth r4 - 09 Mar 2007 - 11:56 | ||
---- | ---- | ||
+ | |||
+ | ==== amforth-upload.py ==== | ||
+ | <file> | ||
+ | |||
+ | |||
+ | #!/usr/bin/env python | ||
+ | |||
+ | # amforth-upload.py | ||
+ | # | ||
+ | # uploads text files containing forth commands to a microcontroller running amforth (v1.3) | ||
+ | # monitors the output from the microcontroller and uses the character echo to implement a kind of software flow control | ||
+ | # also waits for a prompt after each line to allow the compiler a chance to run | ||
+ | # | ||
+ | # in theory it should never overrun the input buffer on the controller, | ||
+ | # but it will easily get stuck if the output from the controller is unusual | ||
+ | # | ||
+ | # you have to kill any other processes that are accessing the serial port before running this, | ||
+ | # otherwise it will miss characters that are stolen by the other process and get stuck | ||
+ | # | ||
+ | # perhaps a better way to implement this would have been as a program that could be plugged into a terminal program | ||
+ | # like x/y/zmodem for minicom (except for the difficulty of killing it when it gets confused). oh well. | ||
+ | # | ||
+ | # mailto:pix@test.at | ||
+ | # http://pix.test.at/ | ||
+ | |||
+ | |||
+ | import sys | ||
+ | import getopt | ||
+ | import os | ||
+ | import re | ||
+ | |||
+ | def write_line_flow(string,dest): | ||
+ | # strip comments | ||
+ | # these probably will strip comment-like structures out of ." .." strings as well. | ||
+ | |||
+ | if debug: | ||
+ | print >>sys.stderr, "line before comment stripping: "+string | ||
+ | |||
+ | string = re.sub("(^| )\( .*?\)"," ",string) | ||
+ | string = re.sub("(^| )\( [^\)]*$"," \n",string) | ||
+ | string = re.sub("(^| )\\\\ .*","",string) | ||
+ | |||
+ | if re.match("^\s*$",string): | ||
+ | if verbose: | ||
+ | print >>sys.stderr, "skipping empty line" | ||
+ | return | ||
+ | |||
+ | if debug: | ||
+ | print >>sys.stderr, "line after comment stripping: "+string | ||
+ | |||
+ | if verbose: | ||
+ | print >>sys.stderr, "sending line: "+string | ||
+ | for o in list(string): | ||
+ | dest.write(o); | ||
+ | |||
+ | if o == "\t": | ||
+ | o = " " | ||
+ | |||
+ | while True: | ||
+ | i = dest.read(1) | ||
+ | #print "<"+i+"]", | ||
+ | #print >>sys.stderr, "["+i+"]" | ||
+ | sys.stdout.write(i) | ||
+ | sys.stdout.flush() | ||
+ | if i == o: | ||
+ | #print "|", | ||
+ | break | ||
+ | #dest.write("\n") | ||
+ | if verbose: | ||
+ | print >>sys.stderr, "waiting for prompt" | ||
+ | |||
+ | start, nl, space, o, gt = range(5) | ||
+ | |||
+ | state = start | ||
+ | |||
+ | while True: | ||
+ | #print >>sys.stderr, "{"+str(state)+"}" | ||
+ | #dest.write("") | ||
+ | i = dest.read(1) | ||
+ | #print "<"+i+"]", | ||
+ | #print >>sys.stderr, "["+i+"]" | ||
+ | sys.stdout.write(i) | ||
+ | sys.stdout.flush() | ||
+ | if state == start: | ||
+ | if i == "\r": | ||
+ | state = nl | ||
+ | elif i == " ": | ||
+ | state = space | ||
+ | continue | ||
+ | elif state == nl: | ||
+ | if i == ">": | ||
+ | state = gt | ||
+ | else: | ||
+ | state = start | ||
+ | continue | ||
+ | elif state == gt: | ||
+ | if i == " ": | ||
+ | if debug: | ||
+ | print >>sys.stderr, "<matched '^> '>" | ||
+ | break | ||
+ | else: | ||
+ | state = start | ||
+ | continue | ||
+ | elif state == space: | ||
+ | if i == "o": | ||
+ | state = o | ||
+ | else: | ||
+ | state = start | ||
+ | continue | ||
+ | elif state == o: | ||
+ | if i == "k": | ||
+ | if debug: | ||
+ | print >>sys.stderr, "<matched ' ok'>" | ||
+ | break | ||
+ | else: | ||
+ | state = start | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | def write_file_flow(in_file,dest): | ||
+ | while(True): | ||
+ | line = in_file.readline() | ||
+ | if len(line)>0: | ||
+ | write_line_flow(line,dest) | ||
+ | else: | ||
+ | break | ||
+ | |||
+ | def main(argv): | ||
+ | |||
+ | global verbose, debug | ||
+ | |||
+ | #in_file = file("file.frt") | ||
+ | #tty_dev = file("/dev/ttyS0","w+",0) | ||
+ | |||
+ | tty_dev_name = "/dev/ttyS0" | ||
+ | force = False | ||
+ | verbose = False | ||
+ | debug = False | ||
+ | |||
+ | try: | ||
+ | opts, args = getopt.getopt(argv,"ht:vfd") | ||
+ | except getopt.GetoptError: | ||
+ | print >>sys.stderr, "unknown option. try -h" | ||
+ | sys.exit(1) | ||
+ | |||
+ | for opt, arg in opts: | ||
+ | if opt == "-h": | ||
+ | print >>sys.stderr, "usage: amforth-upload [-h] [-v] [-f] [-t tty] [file1] [file2] [...]" | ||
+ | print >>sys.stderr, "\n default tty is "+tty_dev_name | ||
+ | print >>sys.stderr, "\n if no files are specified, input is read from the the terminal" | ||
+ | print >>sys.stderr, "\n -f will run without checking for other processes accessing the tty" | ||
+ | print >>sys.stderr, "\n -v will print extra information during execution" | ||
+ | sys.exit(1) | ||
+ | elif opt == "-t": | ||
+ | tty_dev_name = arg | ||
+ | elif opt == "-v": | ||
+ | verbose = True | ||
+ | elif opt == "-f": | ||
+ | force = True | ||
+ | elif opt == "-d": | ||
+ | debug = True | ||
+ | |||
+ | if not force: | ||
+ | if not os.system("which fuser >/dev/null 2>&1"): | ||
+ | if not os.system("fuser -u "+tty_dev_name): | ||
+ | print >>sys.stderr, "the above process is accessing "+tty_dev_name+"." | ||
+ | print >>sys.stderr, "please stop the process and try again." | ||
+ | sys.exit(1) | ||
+ | else: | ||
+ | print >>sys.stderr, "couldn't find fuser. so i can't check if "+tty_dev_name+" is in use." | ||
+ | print >>sys.stderr, "run with the -f option to force execution anyway" | ||
+ | |||
+ | |||
+ | tty_dev = file(tty_dev_name,"r+",0) | ||
+ | |||
+ | if len(args)<1: | ||
+ | if verbose: | ||
+ | print >>sys.stderr, "processing stdin" | ||
+ | write_file_flow(sys.stdin,tty_dev) | ||
+ | else: | ||
+ | for filename in args: | ||
+ | in_file = file(filename,"r") | ||
+ | if verbose: | ||
+ | print >>sys.stderr, "processing "+filename | ||
+ | write_file_flow(in_file,tty_dev) | ||
+ | in_file.close() | ||
+ | |||
+ | |||
+ | |||
+ | if __name__ == "__main__": | ||
+ | main(sys.argv[1:]) | ||
+ | |||
+ | </file> |