#emc-devel | Logs for 2008-12-10

[02:39:26] <jepler> jmkasunich: I now have xilinx ise 10.1 installed on windows xp in virtualbox, so I can try running the python-based hm2 builder when it gets to that point
[02:39:43] <jepler> (webpack or whatever they call the free-beer one)
[02:40:06] <jmkasunich> cool, thanks
[02:40:36] <jmkasunich> how many jigabytes did it use?
[02:40:44] <SWPadnos> oh good. that makes it so I don't have to delete stuff off this machine to try installing
[02:41:02] <SWPadnos> (onto an old Athlon 1800 system with Windows 2000, which probably wouldn't work anyway)
[02:41:47] <SWPadnos> oh. it looks like I have 9.2i installed, so we can see if it works across versions also (if it ever starts up)
[02:42:39] <jmkasunich> I think I have 8.something ;-)
[02:42:56] <SWPadnos> too funny. the last project I looked at was hostmot2 :)
[02:43:06] <SWPadnos> (with this Windows install)
[02:43:48] <SWPadnos> which (at the time) used about 15% of a 5i22-1.5
[02:45:25] <SWPadnos> jepler, what version of Python did you install?
[02:45:29] <SWPadnos> I have IDLE 2.4
[02:46:36] <jmkasunich> I got my 7i40 servoamp today, should get my encoder on Monday
[02:46:50] <SWPadnos> cool. how does it look?
[02:49:06] <jmkasunich> small
[02:49:17] <jmkasunich> it amazes me what can be stuffed onto a board
[02:49:34] <jmkasunich> 7A cont, 10A peak, 80V, two channel
[02:50:02] <jmkasunich> 2.5" x 4"
[02:50:38] <SWPadnos> about the size of a gecko
[02:50:45] <SWPadnos> maybe a little bigger
[02:52:35] <jepler> Oh I didn't install python yet
[02:52:44] <jepler> I'll probably get the newest
[02:52:48] <jepler> 2.6, that is, not 3.0
[02:53:43] <jepler> jmkasunich: using the 7i40 for spindle, or for axis motors?
[02:53:58] <SWPadnos> interesting. they show 2.5 as the "current" one, but 2.6 is listed in the "additional files" area
[02:54:04] <SWPadnos> http://sourceforge.net/project/platformdownload.php?group_id=78018
[02:54:09] <jepler> SWPadnos: huh, really
[02:54:33] <SWPadnos> well, it's not really marked current, but it is hi,lighted and above all the others
[02:54:34] <jepler> jmkasunich: 2.67GB left on a 9.99GB disk, according to windows explorer
[02:54:46] <jepler> that's a fresh 10GB disk created for the xilinx environment only
[02:55:57] <jepler> SWPadnos: how did you happen to arrive at sf for download of python?
[02:56:02] <jmkasunich> jepler: just experimenting for now
[02:56:14] <jmkasunich> but it will be for position control, like an axis
[02:56:21] <SWPadnos> python.org -> Windows -> that SF page
[02:56:31] <SWPadnos> oh, I guess that
[02:56:40] <SWPadnos> that's just some add-ons
[02:57:03] <jepler> I went python.org -> download -> found link to 2.6.1 installer
[02:57:23] <SWPadnos> oh, there it is
[02:57:39] <jmkasunich> the Ametek servos are good for maybe 100W continuous, 400W peak - kind of puny for a spindle
[02:57:40] <SWPadnos> I had actually searched for "python windows", and got another page on the python.org site
[02:59:38] <jepler> ok, python installed so now I'm really ready
[03:01:08] <SWPadnos> remember to reboot ;)
[03:03:58] <jepler> grgrgrngrgn
[03:08:10] <jepler> hm, something tells me I'll have to allocate more than 384MB RAM to effectively run the xilinx tools
[03:19:37] <jmkasunich> jepler: if I want to open a file for reading, and handle the case where it doesn't exist,
[03:19:51] <jmkasunich> should I use try:, or just test the return value of open?
[03:24:05] <jepler> jmkasunich: open throws an exception in that case
[03:24:22] <jmkasunich> so I must use try, right?
[03:24:27] <jepler> right
[03:24:32] <jmkasunich> joy
[03:26:30] <jepler> you could write a single wrapper for open that makes it return a failure value, and use that everywhere
[03:26:48] <jmkasunich> that's ok - I gotta learn how to use try sooner or later
[03:27:07] <jmkasunich> I won't be doing lots of opens, but I will be doing lots of things that might fail one way or another
[03:29:08] <jmkasunich> the simple approach is just try: open() except: handle_it
[03:29:25] <jmkasunich> but that handler will be invoked for any error, not just file-not-found
[03:30:00] <jmkasunich> I'm not sure if I should care.... but if I do, how to I tell it "except IOError: [Errno 2] No such file or directory:" ?
[03:30:23] <jmkasunich> the doc page for except goes into a bunch of class stuff that I don't follow
[03:30:51] <jepler> if it's "file doesn't exist" that you want to treat specially, then you could write:
[03:31:01] <jepler> if os.path.exists(filename): f = open(filename)
[03:31:07] <jepler> else: handle case where it doesn't exist yet
[03:31:23] <jepler> now, if the open fails for some other reason, python will exit and tell the user why
[03:31:35] <jepler> in a way only a programmer would love, but this is a tool for programmers so it's OK
[03:31:49] <jmkasunich> heh
[03:32:07] <jmkasunich> since I can't anticipate what other ways it might fail, I can't really do much to handle them anyway
[03:33:05] <SWPadnos> -EDISK_EXPLODED
[03:34:44] <jepler> if you want to do it with exceptions, here's how you look at the errno value associated with an IOError:
[03:34:47] <jepler> try:
[03:34:50] <jepler> open(filename)
[03:34:52] <jepler> except IOError, detail:
[03:34:55] <jepler> if detail.errno == errno.ENOENT: print "wasn't there"
[03:34:57] <jepler> else: print "other error", detail.errno, str(detail)
[03:35:23] <jmkasunich> cool
[03:36:10] <SWPadnos> try/except (or try/catch) can be used basically the same way as you use standard error returns, but they're a little uglier that way
[03:36:34] <jmkasunich> yesterday (I think?) I mentioned that the spec file is just a few python statements, identifier = """value""", etc
[03:36:43] <jepler> yeah -- in that example, think of 'detail' as the name of the variable where the "error return value" goes
[03:36:58] <jepler> (in fact it is just a variable, though you'll often see it called 'detail')
[03:37:04] <SWPadnos> once you get used to them, they can make the code a lot easier to read and maintain, because the "real work" is done in one string of instructions, and the error handling is logically separated into the except/catch blocks
[03:37:07] <jepler> yes you did mention that
[03:37:27] <jmkasunich> so, I've opened it - now I think I want to exec() it
[03:37:39] <jmkasunich> again, error handling - the user could have typed any stupid thing in there
[03:37:49] <SWPadnos> is that exec or eval?
[03:38:00] <jmkasunich> well, that is part of my question
[03:38:03] <SWPadnos> heh
[03:38:10] <jmkasunich> since I have several assignments in the file, I think I need exec
[03:38:22] <jmkasunich> eval would only work if the whole file was an expression (I think)
[03:38:32] <SWPadnos> I don't know
[03:38:36] <SWPadnos> good thing jepler is here :)
[03:38:44] <jepler> use execfile()
[03:38:55] <jepler> it will report error messages in a way that a programmer can love
[03:39:02] <jepler> Traceback (most recent call last):
[03:39:02] <jepler> File "tw.py", line 1, in <module>
[03:39:02] <jepler> execfile("totallywacky.spec")
[03:39:02] <jepler> File "totallywacky.spec", line 1
[03:39:02] <jepler> I like traffic lights
[03:39:05] <jepler> ^
[03:39:07] <jepler> SyntaxError: invalid syntax
[03:39:20] <jmkasunich> at least it points to the file
[03:39:22] <SWPadnos> thank you, Monty Python :)
[03:39:40] <jepler> jmkasunich: yes, it'll point at the spec file somewhere near the python syntax problem
[03:39:46] <jmkasunich> I originally used execfile, then I changed to open/exec because I wanted to handle file-not-found
[03:39:52] <jmkasunich> but the exists thing deals with that
[03:40:08] <jepler> >>> execfile("/tmp/doesnotexist")
[03:40:13] <jepler> IOError: [Errno 2] No such file or directory: '/tmp/doesnotexist'
[03:40:25] <jepler> ^^^ so you can handle that kind of error from execfile if you care to (just like open)
[03:40:52] <jmkasunich> if os.path.exists(spec_fname):
[03:40:52] <jmkasunich> specfile = execfile(spec_fname)
[03:40:52] <jmkasunich> else:
[03:40:52] <jmkasunich> print "spec file '%s' not found" % spec_fname
[03:40:52] <jmkasunich> sys.exit(1)
[03:41:03] <jmkasunich> oops, the specfile= part goes away
[03:41:12] <jmkasunich> left over from when I had open()
[03:45:46] <jepler> 'night all
[03:45:51] <jmkasunich> goodnight
[03:45:57] <jepler> jmkasunich: maybe drop me an e-mail if you have questions left at the end of your night
[03:46:16] <jmkasunich> ok
[04:27:48] <garage_seb> anyone awake?
[04:28:22] <garage_seb> cradek (or anyone): i'd like feedback on encoder velocity estimation
[04:28:29] <garage_seb> http://highlab.com/~seb/emc2/
[04:28:34] <garage_seb> am i doing it right?
[04:28:52] <jmkasunich> garage_seb: O
[04:28:55] <jmkasunich> oops
[04:28:59] <garage_seb> hi jmkasunich
[04:29:13] <jmkasunich> I'm in the middle of something, but I'll try to look at that tomorrow sometime
[04:29:13] <garage_seb> is that a 0 as in false as in you're doing it wrong? ;-)
[04:29:22] <garage_seb> ok thanks :-)
[04:29:24] <jmkasunich> fat fingers
[04:29:46] <garage_seb> i'll commit this for now and change it tomorrow if it's wrong
[04:29:48] <jmkasunich> I have strong opinions on velocity estimation ;-)
[04:29:49] <jmkasunich> sure
[04:30:20] <garage_seb> oh good :-)
[04:30:42] <jmkasunich> I just got a 7i40 board (servo amp), I already have some motors, and will be getting an encoder that fits on Monday, so I'll be playing with servoish stuff over the holidays
[04:30:58] <jmkasunich> my vacation starts Friday 8-)
[04:31:29] <garage_seb> yay, servo vacation!
[04:31:38] <garage_seb> some might say you're wierd, but i understand ;-)
[04:31:51] <garage_seb> which one is the 7i40?
[04:32:08] <jmkasunich> dual H bridge, 7A cont, 10A peak, 80V
[04:32:17] <garage_seb> sweet :-)
[04:32:36] <garage_seb> pwm in?
[04:32:42] <SWPadnos> hmmm. that would turn my 50 oz-in motors quite nicel
[04:32:42] <garage_seb> or +-10?
[04:32:42] <jmkasunich> I believe so
[04:32:44] <SWPadnos> y
[04:33:08] <garage_seb> SWPadnos: you have opinions! what do you think of the encoder velocity plots i posted?
[04:33:11] <jmkasunich> you can put two of them on one cable, standard servo pinout, for four axes
[04:33:17] <SWPadnos> I didn't see them
[04:33:21] <garage_seb> http://highlab.com/~seb/emc2/
[04:33:52] <garage_seb> the high speed one is easy, because the encoder has updated each time we look at it
[04:34:07] <garage_seb> on the low-speed ones it has to smooth across multiple servo periods
[04:34:29] <garage_seb> those pics have a 1 ms servo period, and 10 ms per vertical rule
[04:34:29] <cradek> sorry I have not tried it yet - I will try to soon
[04:34:30] <SWPadnos> can I see the code?
[04:34:37] <SWPadnos> or have you committed it?
[04:35:03] <garage_seb> i have not committed it to cvs yet
[04:35:07] <SWPadnos> ok.
[04:35:39] <SWPadnos> I think you shouldn't need to do any special smoothing - the decay should just come out of the math (until some threshold where you call the velocity 0)
[04:38:51] <garage_seb> SWPadnos: you can see the code here (via http or bzr): http://highlab.com/~seb/bzr/emc2/hostmot2/
[04:39:19] <garage_seb> http://highlab.com/~seb/bzr/emc2/hostmot2/src/hal/drivers/mesa-hostmot2/encoder.c
[04:39:32] <SWPadnos> thanks
[04:39:41] <garage_seb> it's, ah, a bit icky
[04:39:52] <SWPadnos> no problem. I do the same thing most of the time :)
[04:40:16] <garage_seb> line 815 has the function that runs each servo period
[04:40:33] <garage_seb> (for each instance)
[04:40:38] <garage_seb> encoder instance that is
[04:40:53] <garage_seb> the estimate_velocity() function has the new code
[04:41:45] <garage_seb> i'm using something similar to the Auslander velocity estimator
[04:42:13] <jmkasunich> did you happen to look a the estimator in the emc software encoder module?
[04:42:45] <garage_seb> i didnt... probably should have
[04:43:05] <garage_seb> the hm2 one is a bit different since the fpga gives you a timestamp when the encoder count changed
[04:43:17] <jmkasunich> the software encoder does _exactly_ the same thing
[04:43:27] <jmkasunich> only difference is that the timestamp resolution is a lot coarser
[04:43:35] <garage_seb> with a timestamp granularity of base_period, right
[04:43:54] <garage_seb> i'm using a 1 MHz timestamp clock right now
[04:44:14] <jmkasunich> thats about 20-50x better than software
[04:44:29] <jmkasunich> but it should work the same way
[04:44:33] <garage_seb> * garage_seb reads the sw encoder code
[04:45:19] <SWPadnos> line 548 and thereabouts
[04:45:53] <garage_seb> SWPadnos: ?
[04:45:59] <SWPadnos> in encoder.c
[04:46:06] <garage_seb> that file has 547 lines
[04:46:17] <jmkasunich> lol
[04:46:25] <SWPadnos> right!
[04:46:32] <garage_seb> the vel estimator is on the *hidden* final line ;-)
[04:46:34] <SWPadnos> how about 396
[04:47:11] <SWPadnos> silly me reads [396:1] 548 as line 548, when it's actually 390 *of* 548 :)
[04:47:59] <SWPadnos> it looks good by the way, the word "filtering" just made me wonder :)
[04:48:07] <SWPadnos> oops, "smoothing"
[04:50:10] <garage_seb> yeah, looks like we do the same thing in different ways
[04:50:51] <garage_seb> software encoder.c is cleaner & simpler to understand i think
[04:52:28] <SWPadnos> the one thing you have to deal with that encoder doesn't is asynchronous reset
[04:52:45] <garage_seb> part of what makes my code hairier is having to deal with roll-over in both count and timestamp
[04:53:05] <garage_seb> they're 16 bits in hm2, 32? in sw encoder
[04:53:08] <SWPadnos> that's a separate calculation though - it shouldn't be part of the vel calcs
[04:53:10] <jmkasunich> rollover can be a pita
[04:53:24] <SWPadnos> is there a rollover flag for the timer?
[04:53:31] <jmkasunich> ideally, you are already doing rollover handling for the counts
[04:53:32] <garage_seb> you just gotta watch out for it
[04:53:35] <garage_seb> SWPadnos: no
[04:53:38] <SWPadnos> hmmm
[04:53:41] <SWPadnos> that's a problem
[04:53:47] <garage_seb> no problem
[04:53:49] <jmkasunich> if timestamp < prev_timestamp, you had a rollover
[04:53:56] <jmkasunich> or you are using a too-slow thread
[04:54:06] <SWPadnos> no, the timer updates when an edge occurs
[04:54:28] <garage_seb> the code starts reading the raw timestamp counter if no edge happens
[04:54:45] <jmkasunich> clever ;-)
[04:54:45] <garage_seb> around line 720
[04:55:00] <jmkasunich> bedtime for me, I'll look closer tomorrow
[04:55:01] <SWPadnos> ok, so you use "now" instead of "last edge" if no edges were detected
[04:55:05] <SWPadnos> that's good :)
[04:55:06] <garage_seb> SWPadnos: right
[04:55:07] <SWPadnos> see you jmk
[04:55:16] <garage_seb> jmkasunich: goodnight :-)
[04:55:43] <garage_seb> SWPadnos: then if a roll-over is imminent, it calls it quits and says vel=0 ;-)
[04:55:49] <SWPadnos> heh
[04:55:58] <SWPadnos> 16 bits worth of microseconds isn't a lot :)
[04:56:06] <garage_seb> i stop at 50 ms
[04:56:11] <SWPadnos> hmmm
[04:56:12] <garage_seb> short of 65.5 ms
[04:56:29] <jmkasunich> seems to me that it would make sense to extend the timestamp value to 32 bits as well
[04:56:36] <SWPadnos> note the comment in encoder.c, where he changed from a 100ms timeout to a 1 scond timeout
[04:56:41] <jmkasunich> then you can stop where it makes sense, instead of when registers get full
[04:56:42] <garage_seb> it'd be fairly straightforward to keep track of the roll-overs
[04:56:55] <garage_seb> doable
[04:57:12] <SWPadnos> harder than it seems though ;)
[04:57:35] <SWPadnos> unless there's an atomic "latch all timers and encoders" signal in there somewhere
[04:57:49] <SWPadnos> including a copy of the raw timestamp counter
[04:57:57] <garage_seb> it's one of those things: hard to do perfectly, easy to do well enough
[04:58:13] <garage_seb> there's no such "latch everything" button in hm2
[04:58:15] <SWPadnos> except that you have opportunuities 16 times a second for it to screw up
[04:59:55] <SWPadnos> note that Chris Morley may have had a problem that only happens once every few hundred k parport accesses
[05:00:12] <garage_seb> chris morley?
[05:00:23] <SWPadnos> err - Eric Johnson
[05:00:27] <SWPadnos> same thing :)
[05:00:28] <garage_seb> oh right
[05:00:36] <garage_seb> "one of those people on the internet"
[05:00:55] <SWPadnos> "who's been asking for 7i43 help a lot lately" :)
[05:01:15] <garage_seb> uh right... but actual electrical signals are a bit harder to manage than just bits
[05:01:28] <garage_seb> i think it'd be pretty easy to get that roll-over code right
[05:01:36] <garage_seb> no biggie ;-)
[05:01:39] <SWPadnos> no, there's a race condition for the timers
[05:02:10] <SWPadnos> if you want to use a combination of the raw timer and the encoder timestamps
[05:02:35] <garage_seb> are you worried about reading the count/ts register, seeing no change, then reading the timestamp register to estimate velocity against the previous change?
[05:03:05] <garage_seb> i'm not sure i see the problem you're talking about
[05:03:06] <SWPadnos> no, I'm concerned about extending the timestamp register by looking at both it and the raw timer
[05:03:22] <SWPadnos> the timestamp won't change every servo cycle, but the timestamp will
[05:03:25] <SWPadnos> err
[05:03:28] <SWPadnos> but the timer will
[05:03:38] <garage_seb> i agree
[05:03:54] <SWPadnos> oh, is the raw timer on the same clock as the timestamps?
[05:04:00] <garage_seb> but the change in the timer will be small compared to the rollover time
[05:04:06] <SWPadnos> yes
[05:04:08] <garage_seb> yes it's all one clock
[05:04:09] <SWPadnos> ok
[05:04:14] <SWPadnos> so 1 MHZ
[05:04:17] <garage_seb> right
[05:04:44] <SWPadnos> ok, so the algorithm I have in mind is that you read the timer every cycle, and you extend it to 32 bits (or more) that way
[05:05:09] <garage_seb> i see
[05:05:13] <SWPadnos> the easy way to extend the timestamps is to use the high word of the extended timer, since they're on the same timebase
[05:05:39] <garage_seb> that wont work
[05:05:57] <garage_seb> you'd need an atomic latch for that, or you *will* have 16 chances per second to glitch
[05:06:05] <SWPadnos> the problem is that there may be an encoder edge or a timer rollover during the finite time it takes the CPU to read all the registers
[05:06:12] <SWPadnos> right ;)
[05:06:22] <garage_seb> i was imagining a different algorithm
[05:06:31] <SWPadnos> well ok then :)
[05:06:56] <garage_seb> ok good night people
[05:07:05] <SWPadnos> see ya
[05:07:11] <garage_seb> i'm going back inside, it's frakking freezing out here
[05:41:04] <CIA-42> EMC: 03seb 07TRUNK * 10emc2/src/hal/drivers/mesa-hostmot2/ (TODO encoder.c hostmot2.h): This is an attempt at low-speed encoder velocity estimation.
[10:07:38] <alex_joni> buildmaster: hello
[10:07:38] <buildmaster> yes?
[11:42:51] <micges> hello all
[11:43:54] <micges> I've importand problem: after some errors/warnings from EMC AXIS starts working like G64P1 but gcode initalize it to G64P0.01
[11:47:28] <micges> can I connect P parameter to debug pin to watch it ?
[13:56:58] <cradek_> cradek_ is now known as cradek
[19:46:51] <micges> when I'm compiling v2_2_branch I have error:
[19:47:06] <micges> "/home/michu/EMC2/emc-machine/emc/src/objects/hal/components/updown.c:120:1: warning: "max" redefined"
[19:47:56] <micges> warning not error
[19:49:21] <seb_kuzminsky> micges: what kernel and rtai version do you have?
[19:54:38] <micges> ubuntu 6.06
[19:55:15] <micges> 2.6.15-magmA
[19:57:43] <seb_kuzminsky> ah yes
[19:58:15] <seb_kuzminsky> the buildbot sees it too: http://emc2-buildbot.colorado.edu/buildbot-admin/builders/dapper-x86-2.2-realtime-rip/builds/42/steps/compile/logs/stdio
[19:58:20] <seb_kuzminsky> oops sorry
[19:58:47] <seb_kuzminsky> here's the public non-admin url: http://emc2-buildbot.colorado.edu/buildbot/builders/dapper-x86-2.2-realtime-rip/builds/42/steps/compile/logs/stdio
[19:58:56] <seb_kuzminsky> trunk doesnt do this
[19:59:05] <seb_kuzminsky> maybe a fix went into trunk and didnt get merged into 2.2?
[19:59:43] <cradek> I bet not much priority is given to fixing entirely-harmless warnings in the stable branch
[20:01:08] <jepler> in TRUNK, comp emits a #undef before the #define for access to pins and parameters
[20:01:35] <seb_kuzminsky> jepler: thanks
[20:01:45] <jepler> comp.g revision 1.41
[20:01:45] <jepler> date: 2008/05/04 17:04:57; author: jepler; state: Exp; lines: +14 -0
[20:01:45] <jepler> undef'ing each macro before defining it reduces unhelpful warnings
[20:02:16] <jepler> but like chris I don't get too exercised about a dumb warning like that in the stable version
[20:02:37] <seb_kuzminsky> no problem ;-)
[22:20:21] <skunkworks_> seb_kuzminsky: nice find.
[22:22:05] <seb_kuzminsky> ?
[22:22:20] <seb_kuzminsky> the compile warning on dapper? that was micges
[22:22:37] <skunkworks_> 'So yeah, the manufacturer admits that their hardware is broken'
[22:22:57] <seb_kuzminsky> oh that :-)
[22:23:17] <seb_kuzminsky> yeah sheesh man, they claim on the box they do epp, but do they? no
[22:23:43] <skunkworks_> scary
[22:24:00] <seb_kuzminsky> in the awesome future there wont be any big asics (like the moschip 9805) in our computers, there'll just be fpgas
[22:24:17] <seb_kuzminsky> the drivers include the vhdl for the hardware they drive
[22:24:24] <SWPadnos> guess which chip is on my PCIe parallel port card
[22:24:41] <seb_kuzminsky> when you insmod parport.ko, it allocates the requisite number of gates in an available fpga and put their hardware there
[22:24:48] <SWPadnos> though it does say moschip, not netmos :)
[22:24:49] <seb_kuzminsky> SWPadnos: my sources say 9805
[22:24:53] <SWPadnos> heh
[22:25:40] <seb_kuzminsky> actually it was the faq for their whole 98xx line of chips, i said the wrong thing in the email: the 9815 etc are affected too
[22:25:51] <SWPadnos> interesting. there's a place for a second header and I believe an EEPROM chip. I wonder how hard it would be to make this a dual parport card
[22:26:38] <seb_kuzminsky> some of the moschip chips use an eeprom, and some support multiple ports
[22:26:47] <seb_kuzminsky> could be you have a unified pcb for several of their chips
[22:26:55] <SWPadnos> could be
[22:26:58] <seb_kuzminsky> the 9805 only supports one parport afaict
[22:26:58] <SWPadnos> it's s 9805
[22:27:01] <SWPadnos> a
[22:27:03] <SWPadnos> bummer
[22:27:28] <jepler> oh, an eeprom with setup data? an eeprom seems like overkill to tell a chip whether it has 0 or 1 or 2 parports
[22:27:54] <seb_kuzminsky> i'm not sure what all they put in there
[22:28:20] <seb_kuzminsky> i wish we could just rip off the entire linux parport subsystem
[22:28:29] <SWPadnos> default configs for stuff like base addresses and stuiff maybe
[22:28:32] <SWPadnos> modes ...
[22:32:17] <jepler> hm, is this line too clever?
[22:32:17] <jepler> if (!(((long)buf | length) & 0x03)) {
[22:32:28] <jepler> (check that buf and length are 4-byte aligned)
[22:32:35] <jepler> I certainly missed it the first time
[22:32:40] <SWPadnos> I'd need syntax hilighting to be able to tell :)
[22:34:59] <seb_kuzminsky> jepler: that's too hairy
[22:35:08] <SWPadnos> length isn't a long, only buf
[22:35:18] <SWPadnos> and it deosn't tell which is screwy
[22:36:41] <jepler> SWPadnos: indeed
[22:37:08] <SWPadnos> and it takes several looks to find that out :)
[22:39:32] <seb_kuzminsky> it's better to write legible code than clever code
[22:39:51] <seb_kuzminsky> Rob Collins said "Optimize for folk reading the code." :-)
[22:40:11] <SWPadnos> in the words of - uh - someone I can't remember:
[22:40:51] <SWPadnos> paraphrasing: "Don't write clever code. Since you need to be more clever to debug code than to write it, you will by definition be unable to debug the most clever code you can write."
[22:40:59] <seb_kuzminsky> heh
[22:41:17] <jepler> I wonder if any compiler will optimize ((buf & 0x3) || (length & 0x3)) into the same sequence as the original I showed
[22:41:37] <SWPadnos> hmmm
[22:42:08] <SWPadnos> it does save one instruction
[22:42:42] <SWPadnos> s/does/should/
[22:44:40] <jepler> SWPadnos: more importantly, it saves a jump
[22:45:09] <SWPadnos> oh, if it uses short-circuit evaluation
[22:45:22] <jepler> || "must be" short-circuit in C
[22:45:54] <SWPadnos> by definition or because "that's the way it is"?
[22:46:43] <jepler> by definition
[22:47:15] <SWPadnos> hmmm
[22:47:16] <jepler> so if((x == NULL) || (x[0] == '\0')) is an acceptable way of checking whether a string is NULL or empty
[22:48:41] <jepler> showing that gcc doesn't perform the optimization: http://pastebin.ca/1282063
[22:49:02] <jepler> but trying to save one branch when you're about to do at least one I/O instruction is .. silly
[22:49:16] <SWPadnos> heh
[22:49:45] <SWPadnos> I should look at where that code is :)
[22:50:21] <jepler> parport_pc.c, trying to decide whether to insl or insb a series of epp reads
[22:50:40] <SWPadnos> ah
[22:50:45] <jepler> (using insl instead of a loop over inl seems like it's unlikely to make much difference either)
[22:51:29] <SWPadnos> insl auto-decrements the [E]CX register though
[22:51:40] <SWPadnos> or increments or whatever
[22:52:27] <SWPadnos> of course it makes no difference if the CPU is halted during the actual read though
[22:52:33] <jepler> I assume it compiles into 'rep insl' instead of at least 3 instructions (inl / addl / loop)
[22:53:25] <SWPadnos> it also stores to memory
[22:53:44] <jepler> ok, 4 instructions :-P
[22:53:47] <SWPadnos> so it replaces inl / movl / inc(dec) / loop
[22:54:19] <SWPadnos> and lots of code space actually. rep insl is two bytes long
[23:01:58] <jepler> yeah but can you measure a performance difference?
[23:03:00] <seb_kuzminsky> if it runs a bajillion times it's still quicker than the time it took me to understand what the code meant ;-)
[23:10:16] <jepler> I couldn't find any indication that the netmos is blacklisted for epp mode by the linux kernel, which is what I was looking for..
[23:13:56] <alex_joni> http://lists.infradead.org/pipermail/linux-parport/2004-February/000024.html
[23:15:53] <jepler> more to the point: http://lists.infradead.org/pipermail/linux-parport/2004-February/000027.html
[23:16:10] <jepler> 1/8 the performance of hardware epp is probably too slow
[23:19:21] <seb_kuzminsky> jepler: i agree, too slow
[23:19:38] <seb_kuzminsky> it already takes about 100 us to do 4-channel servo on the 7i43
[23:20:13] <jepler> bbl
[23:26:31] <alex_joni> jepler: I think you already quoted from here: http://www.moschip.com/data/products/NM/FAQ_98XX.pdf
[23:26:45] <alex_joni> page 8 is the interesting one :)
[23:27:54] <seb_kuzminsky> that's what i posted to emc-users an hour or two ago
[23:30:43] <alex_joni> right
[23:44:54] <SWPadnos> so, I've thought of a couple of problems with command-line completion
[23:45:19] <SWPadnos> hmmm. number 1 may not be a problem actually
[23:45:42] <SWPadnos> 2) it requires realtime to be loaded when you're at the bash prompt
[23:45:54] <SWPadnos> otherwise the hal_startup won't work
[23:47:58] <SWPadnos> 3) I'd have to change the halcmd_completer function (or add another one) because it needs to know whether the command-line options (like --R, -k -f ...) are valid (which they are at the command line, but not while it's running interactively)
[23:50:48] <seb_kuzminsky> later