#emc-devel | Logs for 2005-11-30

[00:00:18] <SWPadnos_> true - a cycle may be divisor + pulse width + setup_time
[00:00:39] <jmkasunich> it is
[00:00:47] <jmkasunich> just changed pw from 4 to 2, and period changed
[00:00:50] <jmkasunich> lame shit
[00:01:11] <jmkasunich> I bet its just pw tho, not setup
[00:01:13] <SWPadnos_> the period remained the same for me
[00:01:22] <SWPadnos_> when I changed pulse width
[00:01:31] <SWPadnos_> maybe it's just N+4?
[00:01:36] <jmkasunich> nope
[00:01:45] <jmkasunich> hang on a bit
[00:02:08] <jmkasunich> ok, we're both right
[00:02:32] <jmkasunich> if desired freq = 1Mhz (divisor = 10) then period doesn't change as pw changes from 4 to 2
[00:03:01] <jmkasunich> but if desired freq = 1.6MHz (divisor = 6)
[00:03:45] <jmkasunich> then actual changes from 1MHz with pw = 2, to 834KHz with pw = 4
[00:04:24] <jmkasunich> ie actual divisor goes from 10 to 12
[00:04:45] <jmkasunich> * jmkasunich is gonna try some more values and make up a chart
[00:05:03] <SWPadnos_> brb - phone
[00:07:48] <SWPadnos_> I was going to write a program that uses the formulas and outputs a bunch of points
[00:07:49] <jmkasunich> * jmkasunich gets out the frequency counter...
[00:08:01] <SWPadnos_> got that on the scope :)
[00:08:27] <jmkasunich> mine will turn the cursor position into freq
[00:08:35] <jmkasunich> but I gotta set the cursor myself
[00:08:47] <jmkasunich> what kind of scope?
[00:10:34] <SWPadnos_> Agilent MSO
[00:10:41] <SWPadnos_> 2 analog + 16 digital channels
[00:10:49] <jmkasunich> nice
[00:10:53] <SWPadnos_> has a precision counter, so I get 5-digit frequencies
[00:10:53] <jmkasunich> tek 2440 here
[00:11:07] <SWPadnos_> 54622D
[00:11:08] <jmkasunich> DC504 counter
[00:11:39] <jmkasunich> but I can't seem to find the BNC to clip leads cable
[00:12:02] <jmkasunich> oh, this is 1Meg input Z, I can just use a probe....
[00:16:17] <SWPadnos_> still on phone ...
[00:18:48] <SWPadnos_> ok - off the phone
[00:19:30] <jmkasunich> this is making very little sense
[00:20:10] <jmkasunich> for one thing, the frequency parameter is displaying negative
[00:20:21] <jmkasunich> I think that has to do with the reversal you did
[00:20:24] <jmkasunich> easy to fix
[00:20:48] <SWPadnos_> the sign inversion?
[00:20:56] <jmkasunich> yeah
[00:21:14] <jmkasunich> I'm gonna undo that, and do it right at the point where the bits are set in the control word
[00:21:24] <SWPadnos_> ok
[00:21:27] <jmkasunich> but that can wait
[00:21:38] <SWPadnos_> I sis notice that the param numbers were negative
[00:21:40] <SWPadnos_> didi
[00:21:52] <SWPadnos_> did!
[00:22:25] <jmkasunich> heh
[00:22:42] <jmkasunich> ok, I've been trying pw of 6, 4, and 2
[00:22:59] <jmkasunich> and frequencies that should give divides of 10, 9, and 8
[00:23:04] <jmkasunich> so far:
[00:23:34] <jmkasunich> desired divide, actual divide (pw=6), actual div (pw=4), actual (pw=2)
[00:23:44] <jmkasunich> 10, 16, 14, 14
[00:23:48] <jmkasunich> 9 16, 14, 13
[00:23:55] <jmkasunich> 8, 16, 12, 12
[00:24:07] <SWPadnos_> what setup time?
[00:24:29] <jmkasunich> 10
[00:24:30] <SWPadnos_> and how did you measure the actual divider?
[00:24:59] <jmkasunich> 10MHz/fout
[00:25:11] <jmkasunich> setup time seems to make no diff
[00:25:23] <jmkasunich> I'd be very surprised if it did
[00:25:24] <SWPadnos_> ok. I actually instrumented the divider
[00:25:33] <jmkasunich> show-off
[00:25:38] <SWPadnos_> got it in a halmeter ;)
[00:25:45] <jmkasunich> ?huh
[00:25:55] <jmkasunich> you mean the desired one?
[00:25:57] <SWPadnos_> ppmc.0.stepgen.00.divisor
[00:26:06] <SWPadnos_> tha actual one output to the ppmc
[00:26:19] <SWPadnos_> the
[00:26:31] <SWPadnos_> care for the source file?
[00:26:38] <jmkasunich> when I said actual, I meant the actual one as determined by looking at the scope
[00:26:46] <jmkasunich> not the one output to the port
[00:26:46] <SWPadnos_> that's the other thing I use
[00:27:18] <jmkasunich> I believe the one that is output to the port is the desired value
[00:27:27] <jmkasunich> ie, if you ask for 1MHz, it outputs 10
[00:27:34] <SWPadnos_> I'm looking at + width, - width, and frequency, as measured by the scope
[00:27:41] <jmkasunich> but the hardware uses either 16 or 14 depending on pw
[00:27:47] <SWPadnos_> and the divisor, as provided by halmeter
[00:28:06] <jmkasunich> anyway, moving on to desired divider = 7
[00:29:40] <jmkasunich> desired 7, actual 16, 12, 11
[00:30:04] <SWPadnos_> ok - so setup-time has no effect
[00:30:41] <SWPadnos_> that's the thing - you're looking at the total period on the scope, but that's not the same as the divisor value
[00:31:08] <SWPadnos_> I'm looking at a scope period of 1.4 uS, and a divisor output of 10
[00:31:20] <SWPadnos_> so there are an extra 4 clock cycles in there somewhere
[00:31:33] <SWPadnos_> and those seem to be a constant 4 cycles
[00:31:40] <jmkasunich> what is your pw?
[00:31:49] <SWPadnos_> 200 ns
[00:31:55] <jmkasunich> iow, 2
[00:32:00] <jmkasunich> change it to 6
[00:32:12] <jmkasunich> or 4
[00:32:21] <SWPadnos_> that will change the divisor to 12, because it can't go below 2x the pulse width
[00:32:47] <jmkasunich> duh, that explains part of what I see
[00:32:50] <SWPadnos_> I tried pulse widths from 2 - 6, and the divisor only changed from 10 to 12 when the pulse width was 6
[00:33:12] <SWPadnos_> the setup time has no effect, except that it will neverbe lower than the pulse width
[00:33:19] <jmkasunich> with pw = 6, actual divisor is always 16, for desired divisor = 10 (and SW writing 12)
[00:33:26] <SWPadnos_> would you like the code that tells you the divisor?
[00:33:35] <jmkasunich> nah
[00:33:52] <SWPadnos_> it's not 16 - that's the problem. there are an extra 4 clock cycles in there
[00:34:43] <jmkasunich> not always 4 I don't think
[00:34:52] <SWPadnos_> at a 2MHz requested speed, I get 1.11 MHz (200 ns up, 700 ns down)
[00:35:10] <SWPadnos_> so in that case, it's onluy 2 cycles extra
[00:35:15] <jmkasunich> actual divider = 8, desired divider = 5
[00:35:19] <jmkasunich> 3 extra
[00:35:29] <jmkasunich> sorry, actual = 9
[00:35:37] <jmkasunich> so it is still 4 extra
[00:35:40] <SWPadnos_> right - sorry, it is 4
[00:36:09] <jmkasunich> I think it will actually be more informative to look at lower freqs
[00:36:12] <jmkasunich> like 500KHz
[00:36:16] <jmkasunich> desired divisor 20
[00:36:27] <SWPadnos_> at lower frequencies, the difference is still only 4
[00:36:48] <jmkasunich> because them we can change pw without changing what is written to the hw
[00:36:54] <SWPadnos_> I think - I noticed that the counter showed me 3.97KHz when I asked for 4 KHz (or something close to that)
[00:38:09] <SWPadnos_> yep - 500KHz requested gives me 416.65 KHz actual
[00:38:22] <jmkasunich> 24 actual divisor
[00:38:26] <SWPadnos_> = 2.4 uS period, rather than 2 uS
[00:38:36] <SWPadnos_> but the divisor is 20
[00:38:46] <jmkasunich> and I just confirmed that it is off by 4 for any pw from 1 to 10
[00:38:50] <jmkasunich> (as expected)
[00:39:08] <jmkasunich> at pw = 11, it goes into frequency limit, and outputs 22 instead of 20
[00:39:10] <SWPadnos_> I'd bet that there's a 2-cycle counter reset penalty when the pulse state changes
[00:39:15] <jmkasunich> yeilding 26 actual instead of 24
[00:39:17] <SWPadnos_> output state, that is
[00:39:45] <jmkasunich> well, its easy enough to deal with, just subtract 4 from the value to output
[00:40:02] <jmkasunich> correcting the limits to match will be a little more fun
[00:40:05] <SWPadnos_> and change the maximum frequency accordingly
[00:40:09] <jmkasunich> yeah
[00:40:12] <SWPadnos_> yep
[00:40:28] <jmkasunich> true max isn't 5MHz like the docs say, probably 2.5
[00:40:53] <jmkasunich> heh, this probably explains why I couldn't get 100nS pulse width, minimum is actually 200nS
[00:41:06] <jmkasunich> did Jon even test this thing?
[00:41:22] <SWPadnos_> probably, but he only specs it to 300 KHz, I think
[00:41:33] <jmkasunich> he specs the stepgen higher
[00:41:46] <SWPadnos_> I'd add another parameter - the min pulse spacing
[00:41:48] <jmkasunich> thing is, he probably never tested it standalone like we are
[00:41:59] <jmkasunich> because it was never easy to do
[00:42:03] <SWPadnos_> I was looking at the gecko specs, and the high time is different from the low time
[00:42:07] <SWPadnos_> true
[00:42:23] <SWPadnos_> you'd think his diags program would have a "rate=xxx" mode
[00:42:38] <jmkasunich> who knows
[00:42:58] <jmkasunich> he's looking more amateurish the further we go :-/
[00:43:03] <SWPadnos_> heh
[00:43:06] <SWPadnos_> I've noticed
[00:43:19] <SWPadnos_> I have a firend who bought his Gecko Servo Interface (as did I)
[00:43:37] <SWPadnos_> he's a mechanical engineer, but he's still annoyed by the lack of documentation
[00:44:00] <SWPadnos_> I think Jon wrote the docs when I bought mine - I think I was his first customer for it
[00:44:10] <jmkasunich> when did you buy it?
[00:44:26] <SWPadnos_> within the last year, but definitely before Fest
[00:44:39] <jmkasunich> he had it with him when I met him for the first time at NAMES 2002
[00:44:46] <SWPadnos_> I got the GSI and USC at the same time - could even have been last fall
[00:44:48] <jmkasunich> (the USC, not the UPC)
[00:44:58] <jmkasunich> oh, first customer for the GSI
[00:45:01] <SWPadnos_> yep
[00:45:37] <SWPadnos_> he doesn't even tell you how much current the thing can take (and it's supposed to be the "master switch" for the servos)
[00:46:21] <jmkasunich> ok, I'm gonna rewrite the divisor calcs and velocity limits
[00:46:52] <SWPadnos_> anyway - if you have pulse width and spacing parameters, that makes the max freq thing easier - just make each one a minimum of 4
[00:47:06] <jmkasunich> min of 2 you mean
[00:47:33] <SWPadnos_> maybe
[00:47:55] <SWPadnos_> you have to output a minimum of 2 for the pulse width
[00:48:07] <jmkasunich> yes
[00:48:16] <SWPadnos_> but the total period must be at least 6 - 2 for the + and 4 for the -
[00:48:41] <SWPadnos_> I wonder what happens if you have the period = the pulse width??
[00:48:50] <jmkasunich> so write divisor = 2, + the 4 internal = 6
[00:49:04] <jmkasunich> I wonder what happend if you write divisor = 1 or 0
[00:49:17] <SWPadnos_> he specifically states that 0=BAD!
[00:49:31] <SWPadnos_> I'd be inclined to believe him
[00:49:37] <jmkasunich> tempted to hack the driver so I can write divisor as a u32 param and send that directly to the HW
[00:49:46] <SWPadnos_> I was thinking about that
[00:50:27] <SWPadnos_> actually - just output the freq directly (after conversion to U32)
[00:50:38] <jmkasunich> damn... I can't think of a good name for the min low time
[00:50:54] <jmkasunich> we have pulse-width
[00:50:59] <jmkasunich> maybe pulse-space-min?
[00:51:00] <SWPadnos_> pulse-space
[00:51:22] <SWPadnos_> or make it a min-pulse-space - yeah
[00:51:24] <jmkasunich> right, it doesn't really need the min
[00:51:45] <SWPadnos_> yes it does, because different freqs will make it larger
[00:51:53] <SWPadnos_> (you convinced me :) )
[00:51:56] <jmkasunich> heh
[00:52:04] <jmkasunich> you convinced me at the same time
[00:52:21] <jmkasunich> (also, width and space, without min, are used by stepgen and freqgen ;-)
[00:52:30] <SWPadnos_> I'd also make the defaults match the Geckodrives, just for the heck of it
[00:52:45] <jmkasunich> instead of 200nS each
[00:52:50] <SWPadnos_> yep
[00:53:01] <jmkasunich> actually, the min value for space will be 400nS
[00:53:35] <jmkasunich> aren't geckos active low?
[00:53:53] <jmkasunich> pull down to light the LED in the optocoupler
[00:53:53] <SWPadnos_> they're active-"opto-isolator LED on"
[00:54:11] <SWPadnos_> if they're set for common+, yes (on the later ones)
[00:54:37] <jmkasunich> I thought they were all that way... early ones had all 4 opto terminals brought out?
[00:54:47] <SWPadnos_> I note that the outputs here are positive pulses
[00:54:51] <jmkasunich> yes
[00:55:05] <jmkasunich> also coming direct from the fpga
[00:55:22] <jmkasunich> source and sink current specs.... on Jon's site, of course not
[00:55:25] <SWPadnos_> well - he does have a TVS on there, I think
[00:55:31] <jmkasunich> gotta look up the fpga data sheet
[00:55:34] <SWPadnos_> maybe from Xilinx
[00:55:41] <jmkasunich> he does?
[00:56:01] <jmkasunich> the schematic he sent me showed a whole lotta nuttin between FPGA and terminal block
[00:56:16] <jmkasunich> * jmkasunich better check that
[00:56:18] <SWPadnos_> I think the 20-pin SOIC U22 is a TVS - not positive though
[00:56:41] <SWPadnos_> nope - just a 75HC buffer
[00:56:44] <SWPadnos_> 74HC
[00:57:16] <SWPadnos_> ok - U25 may be some protection
[00:58:27] <SWPadnos_> yep - I think it's the same as U27 (near P9), which I looked up, and is a TVS
[00:58:47] <SWPadnos_> anyway -now you see why I may want to make my own FPGA based step generator ;)
[00:59:25] <jmkasunich> well neither U25 nor U27 are on the schematic he sent me (but they are on my board)
[00:59:36] <jmkasunich> fscking rediculous
[00:59:38] <SWPadnos_> glad to know you have the latest docs
[01:00:03] <SWPadnos_> it's like my old company (which is part of the reason I left)
[01:00:20] <jmkasunich> anyway, TVS's have nothing to do with available drive current
[01:00:34] <jmkasunich> gotta go to Xylinx to find out if it can actually drive Gecko LEDs
[01:00:34] <SWPadnos_> no - just a little (!) protection
[01:00:46] <SWPadnos_> I have had it work, so I know it's possible
[01:01:02] <jmkasunich> sure, but you dont know anything about margin
[01:01:04] <SWPadnos_> I don't know if it was driving on the high or low part of the pulse though
[01:01:10] <SWPadnos_> nope
[01:02:44] <SWPadnos_> 12mA or 24 mA output drive
[01:02:57] <jmkasunich> good, at least he got that right
[01:03:06] <SWPadnos_> hm - that's the spartan-XL - hold on a min
[01:03:15] <jmkasunich> heh
[01:09:52] <jmkasunich> didja find the specs for the FPGA he actually used yet?
[01:10:32] <SWPadnos_> sort of
[01:11:17] <SWPadnos_> the XL parts are 3.3-V capable
[01:11:38] <jmkasunich> this one says XCS30
[01:11:39] <SWPadnos_> the current may have been a selection of a *lower* setting (for power consumption)
[01:12:34] <jmkasunich> damn, these names are getting long
[01:12:43] <jmkasunich> 36 chars for pulse-space-min
[01:12:49] <SWPadnos_> yeah
[01:13:20] <SWPadnos_> there was a thought to make the names hierarchical - that would get around the problem of e.g. axis-... being part of motion
[01:13:29] <SWPadnos_> but makes naming less flexible
[01:13:50] <jmkasunich> naming conventions definitely need to be revisited
[01:14:00] <jmkasunich> in general, I like:
[01:14:01] <SWPadnos_> it wouldn't be a convention in that case
[01:14:09] <SWPadnos_> (sorry - go ahead)
[01:14:23] <jmkasunich> <blocktype>.<instancenumber>.<pinname>
[01:14:34] <jmkasunich> but when the block is part of a larger thing
[01:14:41] <jmkasunich> like stepgen or encoder part of ppmc
[01:14:45] <jmkasunich> that adds another level
[01:14:49] <jmkasunich> and it gets very messy
[01:15:49] <SWPadnos_> well - the name is only useful for rarely-executed code, right?
[01:16:01] <SWPadnos_> ie, userspace (halcmd)
[01:16:06] <jmkasunich> yeah
[01:16:17] <jmkasunich> its not the speed, its the typing
[01:16:29] <SWPadnos_> so it can be as complex as we want to build a name, as long as the data is there
[01:16:47] <SWPadnos_> and data compactness is probably more important than some execution speed
[01:16:58] <SWPadnos_> (for rarely executed code)
[01:17:34] <SWPadnos_> think of it as a tree - each module has several components, which have some pins and params, etc
[01:17:54] <jmkasunich> oh, you're actually talking about storing them hierarchly
[01:18:01] <jmkasunich> damn I can't spell that word
[01:18:03] <SWPadnos_> you can limit the name to 16 chars (or less) per item, and build the name by walking the tree
[01:18:14] <SWPadnos_> hierarchically
[01:18:32] <jmkasunich> show-off
[01:18:35] <SWPadnos_> that makes filtering easy
[01:18:37] <SWPadnos_> :)
[01:18:49] <SWPadnos_> (former spelling champion, all years)
[01:19:00] <jmkasunich> once a block is loaded, all the names are in one namespace (think symbol table)
[01:19:20] <SWPadnos_> actually - the component has a name, and pointers to its sub-parts
[01:19:24] <jmkasunich> I know I could create the names dynamically, but I don't want to ;-)
[01:19:25] <SWPadnos_> (among other things)
[01:19:44] <SWPadnos_> for halcmd (or hallib), that's probably the best way
[01:19:58] <jmkasunich> what is?
[01:20:16] <SWPadnos_> the way yon don't want - dynamically generating the names
[01:20:19] <SWPadnos_> you
[01:20:25] <jmkasunich> heh
[01:20:53] <SWPadnos_> (I can spell, but typing is a different matter)
[01:21:35] <SWPadnos_> anyway - for filtering on the beginning of a name, it gets really easy - search for the first '.', and look for that component
[01:21:51] <SWPadnos_> search for the next '.', and you get the name of the subcomponents
[01:22:21] <SWPadnos_> but they can only be in this component (unless there's no dot, which tells you that you need to search all related items at this level)
[01:23:49] <SWPadnos_> OK - XCS30 is 12mA per output
[01:24:33] <SWPadnos_> I'm not sure what the total chip current limit is, but I'd bet it's less than 16*12 + internal usage
[01:25:45] <jmkasunich> and I'm almost certain Gecko inputs are common +, pull low to light up
[01:25:54] <jmkasunich> so it wants inversion anyway
[01:26:48] <SWPadnos_> that's true of all older Geckos, and is the default for the ones with pulse multipliers
[01:27:32] <SWPadnos_> though the pulse width can be whatever you want, so it's OK to leave it as is (it'll just draw more power)
[01:28:18] <jmkasunich> well, I better stop talking and start coding
[01:28:26] <jmkasunich> I wanted to tackle the PWM version tonight too
[01:28:42] <jmkasunich> (wonder how many undocumented features are in that one)
[01:28:52] <SWPadnos_> ok - I'll leave you to that
[01:29:55] <SWPadnos_> I'll probably play around some more with the USC pulse widths
[01:30:12] <jmkasunich> ok, if you find anything I need to know about, holler!
[01:30:17] <SWPadnos_> will do
[01:32:40] <jmkasunich> I wonder if there is a relationship between setup time and pulse width?
[01:33:01] <jmkasunich> have to rapidly alternate between positive and negative frequency commands to find out
[01:33:31] <jmkasunich> perhaps send the squarewave output of siggen into a step generator?
[01:33:37] <jmkasunich> (hint, hint ;-)
[01:33:47] <SWPadnos_> heh
[01:34:02] <SWPadnos_> working on it...
[01:34:08] <jmkasunich> was wondering if the code should require setup to be > width or something...
[01:34:25] <SWPadnos_> no - I'd bet that's added transparently
[01:34:35] <SWPadnos_> aha!!
[01:34:46] <SWPadnos_> I just realized why I was getting following errors
[01:35:22] <SWPadnos_> I noticed this problem with HalScope - the slope of commanded vs feedback position were slightly different
[01:35:35] <jmkasunich> because of rounding
[01:35:39] <SWPadnos_> no
[01:35:41] <jmkasunich> you are using only FF1, right?
[01:35:57] <SWPadnos_> yes - that was the problem - no P
[01:36:06] <SWPadnos_> actually, I think P was 1
[01:36:15] <SWPadnos_> maybe it should have been -1
[01:36:23] <jmkasunich> right - if the stepgen did exactly what it was told, you would be ok with no P
[01:36:34] <jmkasunich> but stepgen divides by an integer
[01:36:43] <jmkasunich> its unlikely to generate exactly what you ask it for
[01:36:56] <jmkasunich> so you need to look at the error and correct
[01:37:12] <SWPadnos_> right - there would be real motor-related parameters anyway, which would far outweigh that (on a real machine)
[01:37:32] <jmkasunich> not with steppers
[01:37:34] <SWPadnos_> I'll look again, but I think the P was 1 as well as FF1
[01:37:39] <SWPadnos_> true
[01:37:50] <jmkasunich> 1 is far too low for P
[01:38:05] <jmkasunich> that means with a 1" error, you'll correct at 1" per second
[01:38:15] <SWPadnos_> oh - it helps to know the units :)
[01:38:23] <jmkasunich> you probably want several hundred for P
[01:38:55] <jmkasunich> one thing that I consider a huge feature of HAL is that signals can (and should) have meaninfull units
[01:39:11] <SWPadnos_> so the unit is error inches / correction velocity ?
[01:39:26] <jmkasunich> for the PID, P is unitless, just a gain
[01:39:43] <jmkasunich> but the units of pid command, feedback, and thus error are your machine length units
[01:39:47] <jmkasunich> inches for us
[01:39:50] <SWPadnos_> ok
[01:39:57] <SWPadnos_> (I was going to say - user units)
[01:39:58] <jmkasunich> and the units of PID output are velocity
[01:40:11] <jmkasunich> in the same units, per second
[01:40:17] <SWPadnos_> ok - and the time constant is inherent in the servo rate
[01:40:26] <jmkasunich> in only changes to pulses per second at the stepgen
[01:40:39] <jmkasunich> P doesn't care
[01:40:54] <jmkasunich> I and D are aware of the thread period, and are compensated
[01:41:30] <SWPadnos_> well - since error is a length, and P is unitless, and the output is length / time (velocity) - there's a time constatn in there somewhere
[01:41:34] <jmkasunich> an I of 1 means that after an error of 1 user unit has persisted for 1 second, the integrator will increase by 1
[01:41:45] <jmkasunich> I lied
[01:41:51] <SWPadnos_> he
[01:41:53] <SWPadnos_> heh
[01:42:19] <jmkasunich> hard to put into words
[01:42:32] <SWPadnos_> I know about PID, I'm just not a guru
[01:42:41] <jmkasunich> especialy since not all PIDs are position in velocity out
[01:42:47] <jmkasunich> some are position in torque out
[01:42:52] <SWPadnos_> and I don't know the HAL/emc specific gotchas
[01:43:03] <jmkasunich> the HAL PID is generic
[01:43:19] <SWPadnos_> anyway - back to the PWM - I'll look at direction reversals and what happens to the pulse stream
[01:43:25] <jmkasunich> output = error P + integral of error I + derivitave of error * D, etc, etc
[01:44:29] <jmkasunich> damn, ksirc messed with my formula!
[01:44:58] <jmkasunich> foo bar + baz barf
[01:44:59] <SWPadnos_> no problem - I've written PID code before (on a DSP, to control a big-ass power supply)
[01:45:01] <jmkasunich> heh
[01:45:24] <SWPadnos_> foo / bar + baz * barf
[01:45:39] <SWPadnos_> I got no / or * from you
[01:45:53] <jmkasunich> (asterisk) stuff (asterisk) is interpreted as "hide the asterisks and make stuff bold"
[01:46:19] <jmkasunich> I did foo (asterisk) bar + baz (asterisk) barf
[01:46:22] <SWPadnos_> ah - interesting - chatzilla still shows the asterisks (or slashes), but still bolds (or italicizes) them
[01:46:48] <SWPadnos_> and underscore something underscors _underlines_
[01:46:54] <jmkasunich> ain't computers fun
[01:47:00] <SWPadnos_> yep - they do be
[01:53:39] <jmkasunich> amazing how many compiler errors result from a single misplaced { ;-)
[01:53:47] <jmkasunich> about 10 screensful
[01:54:46] <SWPadnos_> eh
[01:54:48] <SWPadnos_> heh
[01:55:02] <SWPadnos_> "everything is unterminated error"
[01:55:49] <jmkasunich> there should be a counter, and when it hits 100, it should print "Hey doofus, you got either a {}. (). ". or ; messed up"
[01:56:05] <SWPadnos_> you can tell it to halt on the first error, I think
[01:56:28] <jmkasunich> thats ok, most times seeing several at once means I can fix several at once
[01:56:46] <SWPadnos_> unless they're multiple manifestations of the same one ;)
[01:57:25] <jmkasunich> yeah - recgonizing those and not wasting time on them is what separates the men from the boys
[01:57:48] <jmkasunich> basically, I find and fix the first one, and based on what it was I decide to look at the next one or not
[01:57:56] <SWPadnos_> hm - do you need to load the fastest thread first?
[01:58:00] <jmkasunich> yes
[01:58:09] <SWPadnos_> ok - time to fix my testppmc script
[01:58:13] <jmkasunich> because priorities are assigned fast thread highest
[01:58:18] <SWPadnos_> right
[01:58:48] <jmkasunich> someday I'd like to be able to specify priority too, but for 99% of cases, its just one more thing to confuse the user
[01:59:16] <jmkasunich> I think lots of people are gonna like the data side of HAL (routing things where they want) but most are gonna think that addf is a pain in the ass
[01:59:35] <SWPadnos_> yes indeed
[02:00:04] <jmkasunich> I still want to encode dependency info (aka, function foo reads pins a, b, and x, and writes pins c, d and z)
[02:00:20] <jmkasunich> and have code that automatically orders the functions
[02:00:23] <jmkasunich> (if possible)
[02:01:03] <jmkasunich> circular dependencies of course would screw that
[02:01:07] <SWPadnos_> you can put hints into the funct struct - like "desired position" and "read func, calc func, or write func"
[02:01:27] <SWPadnos_> desired position would be -2, -1, 0, 1, or 2
[02:01:42] <jmkasunich> you still have to think about it
[02:01:46] <SWPadnos_> -2 means "first of the write funcs"
[02:02:03] <SWPadnos_> sure - if you sopecify it, that overrides the devault
[02:02:05] <SWPadnos_> default
[02:02:19] <SWPadnos_> -1 means "last func"
[02:02:29] <jmkasunich> hints that get it wrong sometimes are worse than nothing at all
[02:02:29] <SWPadnos_> 0 means no preference
[02:02:42] <jmkasunich> dependencys are the way togo
[02:02:46] <SWPadnos_> well - all read funcs would be tagged as "first in thread"
[02:02:52] <jmkasunich> read functs will have no pins that they read
[02:03:00] <jmkasunich> so automatically would be executed first
[02:03:05] <SWPadnos_> all write funcs as "last in thread"
[02:03:22] <jmkasunich> the pins the write would become available, allowing subsequent functs to run, etc, etc
[02:03:43] <jmkasunich> imagine a complex circuit made of sums, muxes, comparators, integrators, etc
[02:03:49] <SWPadnos_> yes -you're inventing Labview now - better be careful ;)
[02:04:01] <jmkasunich> hints would be useless, ordering depends strictly on circuit topology
[02:04:07] <SWPadnos_> but the juggling only has to be done at addf or delf time
[02:04:14] <jmkasunich> right
[02:04:31] <SWPadnos_> you still need hints, but they only become helpers
[02:04:36] <jmkasunich> ideally you just say what thread you want it in, and it finds the right place in the thread
[02:04:56] <SWPadnos_> yep - or at least, a reasonable place
[02:05:06] <SWPadnos_> there should be some "bump" command
[02:05:18] <SWPadnos_> bump up / down in the list
[02:05:41] <jmkasunich> even if that would violate a dependency?
[02:05:48] <jmkasunich> need to at least warn in that case
[02:06:16] <SWPadnos_> not for that reason - for allowing you to change the order if you don't like it
[02:06:16] <jmkasunich> any given function might have a range of legal positions
[02:06:24] <SWPadnos_> remember that there is no single "correct" ordering
[02:06:28] <SWPadnos_> right
[02:06:50] <jmkasunich> after the last funct that writes any of its inputs, and before the first funct that uses any of its outputs
[02:07:19] <jmkasunich> feedback loops would raise hell
[02:07:53] <SWPadnos_> yes
[02:08:01] <jmkasunich> one possibility would be a "component" that looks like the Z^-1 (zero order hold) that control theory folks use
[02:08:31] <jmkasunich> the actual component would do nothing, but its output would be considered "valid" from the start of the thread
[02:08:32] <SWPadnos_> hence the hints - a feedback loop can hint that it should be last before the output functions
[02:09:16] <jmkasunich> are you talking about hints that are fixed based on the type of function, or hints specified by the user?
[02:09:24] <SWPadnos_> separate into 3 (or possibly more) groups - read, pre-calc, decisions, post-decisions, and write
[02:09:29] <SWPadnos_> hints in the component
[02:09:32] <SWPadnos_> not user
[02:09:45] <jmkasunich> not good enough
[02:09:53] <SWPadnos_> the user can still specify position 3 if they want, regardless of whether that's "correct"
[02:10:11] <jmkasunich> I wish I had a drawing of the mazak spindle control HAL blocks
[02:10:33] <jmkasunich> several muxes, gain blocks, and such
[02:10:46] <SWPadnos_> make sane default behavior, but let the user hang themselves if they want, it's the UNIX way
[02:10:48] <jmkasunich> hints would be useless
[02:11:12] <SWPadnos_> then put in '0' - no hint in the component
[02:11:26] <SWPadnos_> a gain block could be almost anything, but a PID can't
[02:11:47] <SWPadnos_> also, the hint would be "I'd like to be near the end of the calculations, if possible"
[02:12:02] <jmkasunich> I still might want a mux on the output of the PID (we did on the spindle, to switch from PID output in orient mode, to straight speed command in run mode)
[02:12:03] <SWPadnos_> it would still be before anything that uses its output
[02:12:22] <jmkasunich> or I might put a mux on the input of the PID (to select between one of two commands)
[02:12:43] <jmkasunich> by themselves, hints don't nearly solve the problem
[02:12:55] <SWPadnos_> not all blocks can reasonably use hints, but some certainly could
[02:12:55] <jmkasunich> and with a dependency based system, hints aren't needed
[02:13:44] <SWPadnos_> not strictly required, but still useful
[02:14:20] <SWPadnos_> hiya Pere
[02:14:22] <SWPadnos_> Pete
[02:14:26] <petev> hi steve
[02:14:28] <SWPadnos_> (damnfingers)
[02:14:32] <jmkasunich> hi pete
[02:14:35] <petev> hi john
[02:15:07] <jmkasunich> yay! 1MHz in, 1MHz out
[02:15:22] <SWPadnos_> cool!
[02:15:49] <jmkasunich> width and space-min work as intended
[02:16:08] <SWPadnos_> incidentally - the reverse time isn't really important, since it would be from (a very slow forward speed) to (a very slow backward speed)
[02:16:35] <SWPadnos_> the extra few cycles wouldn't make a significant difference
[02:18:23] <jmkasunich> max freq is 1.66667MHz (divide by 6)
[02:18:27] <SWPadnos_> yep
[02:18:52] <jmkasunich> I'm gonna try allowing space-min to go down to 2 and see what happens
[02:19:03] <SWPadnos_> right - the 4 phantom clocks + 2 pulse clocks
[02:19:42] <jmkasunich> that means writing 1 or zero to the HW
[02:20:14] <SWPadnos_> well - try writing 1 to both the period and pulse registers
[02:20:34] <SWPadnos_> didn't it just do a 2-clock pulse when you wrote 1?
[02:20:43] <jmkasunich> I know the pulse width can't be taken below 2 clocks
[02:20:53] <jmkasunich> actually, width is inverted, to get 2, you write 254
[02:21:04] <SWPadnos_> right
[02:21:11] <jmkasunich> i'm not messing with that, just with the actual period
[02:21:16] <SWPadnos_> and 255 is the same as 254, right?
[02:21:37] <jmkasunich> I think so
[02:22:04] <jmkasunich> hey! got 2MHz
[02:22:23] <jmkasunich> writing 1, +4 = 5
[02:22:30] <jmkasunich> gonna try writing zero
[02:22:52] <jmkasunich> nope, asked for 2.5MHz, got 1.25
[02:23:11] <SWPadnos_> zero is bad, according to the docs
[02:23:15] <SWPadnos_> not that that means mucj
[02:23:17] <SWPadnos_> much
[02:23:18] <jmkasunich> so pulse-width can be 2-255 * 100nS
[02:23:35] <jmkasunich> and min pulse space can be 3-255 * 100nS
[02:23:47] <jmkasunich> actually min-pulse-space can be 3-anything
[02:23:58] <jmkasunich> but I made it a u8 to match width
[02:25:41] <SWPadnos_> can you specify a signal / param for halmeter to look at on the command line?
[02:25:54] <jmkasunich> you want to see the value?
[02:26:31] <jmkasunich> you can do show <name>
[02:26:35] <SWPadnos_> I want to have a specific thing watched by halmeter - so I don't have to keep selecting it ;)
[02:26:42] <jmkasunich> oh, halmeter
[02:26:46] <jmkasunich> I thought you said halcmd
[02:26:49] <jmkasunich> yes
[02:26:51] <SWPadnos_> heh
[02:26:58] <SWPadnos_> ok - just halmeter <thing>
[02:27:05] <SWPadnos_> ?
[02:27:20] <jmkasunich> might need a pin/sig/param before thing
[02:27:26] <jmkasunich> probably do
[02:27:38] <SWPadnos_> ok - I'll look
[02:28:00] <jmkasunich> yes, I just tried it
[02:28:08] <jmkasunich> halmeter sig estop
[02:28:19] <SWPadnos_> ok - halmeter param ppmc.0.stepgen.00.divisor :)
[02:28:25] <jmkasunich> yep
[02:28:40] <jmkasunich> I assume divisor is a temporary thing, right?
[02:28:46] <SWPadnos_> yes ;)
[02:28:57] <jmkasunich> ok, I'm about to commit the repaired code
[02:29:11] <SWPadnos_> as is the direct output of the velocity input, and the reduction in pulse width minimum to 1 ;)
[02:29:42] <jmkasunich> final code has pw min 2, space min 3, and outputs divisor-4 to the HW
[02:30:40] <SWPadnos_> and divisor is limited to >5?
[02:31:06] <jmkasunich> yes, because pw+space are used to calc max freq
[02:31:24] <SWPadnos_> duh - I was thinking setup when I read space
[02:31:34] <jmkasunich> setup min is still 2
[02:31:48] <SWPadnos_> yep - unrelated to high freq though
[02:33:27] <SWPadnos_> OK - with 1 output to the divisor, and 1 or 2 for the pulse width, the frequency is 2 MHz (5 clock period)
[02:33:53] <jmkasunich> yeah
[02:34:01] <SWPadnos_> bonehead
[02:34:04] <SWPadnos_> (not you)
[02:34:08] <jmkasunich> 1 or 2 for pw makes absolutely no difference
[02:34:13] <SWPadnos_> right
[02:35:30] <jmkasunich> up to rev 15, can we make it 20?
[02:35:47] <SWPadnos_> let's see - there's still P8 to deal with
[02:35:52] <jmkasunich> correction, 16
[02:36:03] <jmkasunich> plus the PWM
[02:36:11] <jmkasunich> plus the original DIO and DAC cards
[02:36:16] <jmkasunich> heck, 25 at least!
[02:36:18] <SWPadnos_> oh yeah - we'll be at 20 in no time ;)
[02:36:55] <jmkasunich> and at $50/hr, Jon owes us.....
[02:37:02] <SWPadnos_> 2 G-rex each
[02:37:07] <jmkasunich> more than he can afford
[02:56:12] <SWPadnos_> there's more interesting stuff happening with the step pulse generators
[02:56:57] <jmkasunich> interesting in a "revise the driver again" kinda way?
[02:57:06] <SWPadnos_> possibly
[02:57:29] <SWPadnos_> once you go above 5 for the pulse width, the minimum valley wodth jumps from 3 to 5
[02:57:41] <SWPadnos_> and stays there (I went up to 100)
[02:57:43] <jmkasunich> WTF!
[02:58:02] <SWPadnos_> yeah - I'm looking for a software reason now
[02:58:23] <jmkasunich> you know, he also sent me schematics for the FPGA
[02:58:34] <SWPadnos_> yep
[02:58:38] <jmkasunich> you know how much I want to go digging into those
[02:58:43] <jmkasunich> this much:
[02:58:54] <SWPadnos_> this much ><?
[02:58:54] <jmkasunich> * jmkasunich holds his fingers 0.0001 inch apart
[02:59:14] <SWPadnos_> ah - 4 steps apart
[02:59:18] <petev> I warned you about his HW
[02:59:37] <petev> I would make him fix it
[02:59:43] <petev> you have the foundation there
[02:59:49] <petev> he should be able to handle it
[03:00:11] <SWPadnos_> hopefully, he'll send out a fixed config prom
[03:00:27] <jmkasunich> won't help people with old proms
[03:00:36] <SWPadnos_> it's field replaceable
[03:00:40] <jmkasunich> of course none of them are ever gonna try to make 1MHz steps
[03:00:42] <SWPadnos_> at least on my board
[03:00:59] <jmkasunich> mine too, but he's not gonna replace them, not for something like this
[03:01:16] <SWPadnos_> I would, even if I charged a few bucks for it
[03:01:16] <jmkasunich> hell, he's not even gonna fix it
[03:01:21] <SWPadnos_> I would, even if I charged a few bucks for it
[03:01:23] <SWPadnos_> :)
[03:02:52] <jmkasunich> so if you set pw to 5 or greater, do you get the wrong frequency for divisors over 10 (5 pw + 5 min space)
[03:03:10] <jmkasunich> or just for divisors of 8 and 9?
[03:03:21] <SWPadnos_> I don't know - I'm running test code - you probably should try it
[03:03:25] <jmkasunich> I guess I can test
[03:03:30] <SWPadnos_> I have my divisor set to 1
[03:03:49] <SWPadnos_> let me check with it higher
[03:06:01] <jmkasunich> looks like if desired freq is less than 1 MHz, you get what you ask for
[03:06:25] <SWPadnos_> ok
[03:06:39] <jmkasunich> even 1.11111MHz works
[03:06:50] <jmkasunich> but 1.25MHz or higher, and you get 625KHz
[03:07:14] <SWPadnos_> hmmm - sometimes Bad Things happen if you set the pulse wdth to 1 (register = 255)
[03:07:36] <jmkasunich> how Bad?
[03:07:41] <SWPadnos_> no pulses
[03:07:58] <jmkasunich> that's not Bad, thats just bad
[03:08:03] <SWPadnos_> ok
[03:08:11] <jmkasunich> Bad would have to involve smoke
[03:08:21] <jmkasunich> BAD involves actual flames
[03:08:31] <SWPadnos_> I set the divisor to 10, and am experimenting with setup and pulse times
[03:08:52] <SWPadnos_> bad = oops, Bad = reboot, BAD = repairs
[03:08:59] <jmkasunich> yeah
[03:10:09] <petev> ok, how do I make something right associative in a LL grammar? this is killing me
[03:10:21] <jmkasunich> bad = repairs, Bad = ambulance, BAD = hearse
[03:10:41] <SWPadnos_> damfino
[03:10:58] <petev> that's no help
[03:11:01] <SWPadnos_> I'm not sure I even know what you asked
[03:11:03] <jmkasunich> don't ask me about grammer, I don't even know the difference between affect and effect ;-)
[03:11:17] <SWPadnos_> that has no effect here, so it won't affect us
[03:11:20] <petev> and it's grammar
[03:11:29] <SWPadnos_> heh
[03:11:36] <jmkasunich> pthbbbt
[03:11:47] <SWPadnos_> grammer = one who grams
[03:12:00] <jmkasunich> this is bad
[03:12:03] <SWPadnos_> (not that gramming is a verb)
[03:12:08] <jmkasunich> coding = 1/IRC
[03:12:15] <SWPadnos_> ye
[03:12:17] <SWPadnos_> p
[03:12:31] <SWPadnos_> IRC * CODE == k
[03:13:12] <SWPadnos_> have you noticed how nice and bouncy the direction signal is?
[03:13:35] <jmkasunich> direction? I don't think I've ever given it a negative command...
[03:13:41] <jmkasunich> I suppose I should...
[03:13:46] <jmkasunich> or do you mean ground bounce?
[03:13:56] <SWPadnos_> it may be my connections
[03:14:26] <SWPadnos_> but the signals definitely move around - depending on step output and the like
[03:14:39] <SWPadnos_> possibly coupling on the board (or in the FPGA)
[03:14:47] <jmkasunich> ground bounce, crosstalk
[03:14:54] <jmkasunich> there is no ground plane on the board
[03:15:13] <SWPadnos_> heh - I noticed that
[03:15:20] <petev> I had loads of noise problems
[03:15:37] <SWPadnos_> I feel like I'm not getting my money's worth if I let them take all the copper off
[03:15:46] <jmkasunich> lol
[03:15:49] <SWPadnos_> so I always have huge grond planes
[03:16:00] <SWPadnos_> the boards end up nice and heavy also
[03:16:02] <jmkasunich> we have some boards with 4oz copper on all four layers
[03:16:25] <SWPadnos_> d00d - them's some heavy boards
[03:17:04] <jmkasunich> drives up thru 50A or more these days have all power circuitry on PCB
[03:17:22] <SWPadnos_> ah - need a thick cross-section there
[03:17:43] <SWPadnos_> ok - here's what I get
[03:17:51] <SWPadnos_> the divisor is set to 1
[03:17:51] <jmkasunich> we did one drive rated at 100A that was all PCB except for two 0.050 x 0.500 x 4" long bus bar jumpers where we simply couldn't get enough trace width
[03:18:19] <SWPadnos_> that's pretty thick
[03:18:36] <SWPadnos_> though the bus bars on 60000A supplies are a lot larger ;)
[03:18:42] <SWPadnos_> (and water-cooled)
[03:18:46] <jmkasunich> of course the ones I work on have 3" x 3/8 bus
[03:18:51] <jmkasunich> you win!
[03:18:59] <SWPadnos_> heh - not my designs though
[03:19:26] <SWPadnos_> the test load was a stack of 6" wide, 1/2" thick copper plates bolted across the bus
[03:19:52] <SWPadnos_> anyway - this is what I get from the step generator:
[03:19:59] <SWPadnos_> with divisor set to 1
[03:20:10] <SWPadnos_> pulse width=1, no output
[03:20:35] <SWPadnos_> pulse width = 2, 200ns up, 300ns down
[03:20:48] <SWPadnos_> pulse width = 2, 300ns up, 200ns down
[03:20:56] <jmkasunich> ?
[03:21:00] <SWPadnos_> pulse width = 3, 300ns up, 200ns down (oops)
[03:21:19] <SWPadnos_> pulse width = 4, 400ns up, 600ns down
[03:21:37] <SWPadnos_> pulse width = 5, 500ns up, 500ns down
[03:21:58] <SWPadnos_> pulse width = 6, 600ns up, 400ns down
[03:22:12] <SWPadnos_> pulse width = 7, 700ns up, 300ns down
[03:22:22] <jmkasunich> bit of a pattern here
[03:22:30] <SWPadnos_> pulse width = 8, 800ns up, 200ns down
[03:22:36] <SWPadnos_> yes - hold on
[03:22:46] <jmkasunich> * jmkasunich holds breath
[03:22:53] <SWPadnos_> pulse width = 9, 900ns up, 600ns down
[03:22:58] <jmkasunich> heh
[03:23:41] <jmkasunich> so the divider is still dividing by 5 the whole time
[03:23:41] <SWPadnos_> it looks like he's taking the top 5 bits of the pulse width, and insuring that the overall period is at least 2x that
[03:23:50] <SWPadnos_> divider is set to 1
[03:24:10] <SWPadnos_> I only changed pulse width
[03:24:16] <jmkasunich> but if the pulse+recovery isn't done when the divider rolls over, it misses that pulse and outputs 500nS later the next time the divider rolls over
[03:24:37] <SWPadnos_> that's possible
[03:25:36] <jmkasunich> fits the data, without requiring any weird logic between the divider and the pulse timer
[03:26:26] <SWPadnos_> sort of, but the divider is set to 1 the whole time, so it's rolling over every cycle
[03:26:48] <jmkasunich> no, we know the actual divider divides by the value you wrote + 4
[03:26:59] <jmkasunich> that holds true no matter what
[03:27:13] <SWPadnos_> no - I think there's a 4-cycle overhead in toggling the pin and loading the two timers
[03:27:22] <jmkasunich> you set to 1, it does 5, you set to 2, it does 6
[03:27:58] <jmkasunich> set the divider to 3 and repeat your increasing pw valiues
[03:28:06] <SWPadnos_> ok - more data:
[03:28:07] <jmkasunich> I bet I can predict the on and off times
[03:28:18] <SWPadnos_> the period remains constant up through PW=13
[03:28:38] <SWPadnos_> at PW=14, the period changes to 20 clocks
[03:28:42] <jmkasunich> right
[03:29:12] <jmkasunich> the divider is always dividing by 5, and generates a 1 clock long pulse every 500nS...
[03:29:17] <jmkasunich> that triggers off the pw counter
[03:29:44] <jmkasunich> which times out and takes 2 clocks to recover before it will recognize a trigger again
[03:30:11] <jmkasunich> so with pw=13, it recovers in time to recognize the divider output at 15
[03:30:32] <jmkasunich> but with pw=14, it doesn't recover until 16, and triggers on the next divider output pulse at 20
[03:30:58] <SWPadnos_> ok - any time it gets to (5n)-1, the period gets extended another 5
[03:31:05] <jmkasunich> right
[03:31:23] <jmkasunich> and if the divider value was 3, then the actual divide would be 3+4 = 7
[03:31:36] <jmkasunich> and the formula (7n)-1
[03:31:45] <jmkasunich> gets extended another 7
[03:32:21] <SWPadnos_> hm - close, but not quite correct
[03:32:31] <SWPadnos_> I set the divider to 2
[03:32:44] <SWPadnos_> so the values should be (6n)-1
[03:32:55] <SWPadnos_> but the transition happens at 10, not 11
[03:33:04] <jmkasunich> pw 2 = 200nS on, 400 off
[03:33:15] <jmkasunich> 3 -> 300nS on 300 off
[03:33:24] <jmkasunich> 4 -> 400/200?
[03:33:40] <jmkasunich> 5 -> misses, 500, 700
[03:33:47] <jmkasunich> 6 -> 600 600
[03:33:52] <jmkasunich> 7 -> 700 500
[03:33:58] <jmkasunich> 8 -> 800 400
[03:34:03] <jmkasunich> 9 -> 900 300
[03:34:08] <jmkasunich> 10 -> 1000 200
[03:34:24] <jmkasunich> or do you see 10 -> 1000 800?
[03:34:45] <SWPadnos_> ok - that may have been my mistake
[03:34:56] <jmkasunich> 11 -> 1100, 700
[03:35:31] <SWPadnos_> yep
[03:36:09] <SWPadnos_> well - that answers one question I had - the period counter does run in tandem with the pulse timer
[03:36:33] <SWPadnos_> which is nice for calculating the actual frequency, since it's independent of pulse width
[03:36:44] <jmkasunich> yeah
[03:37:11] <SWPadnos_> unless you're being pathological (like me) and trying output rates that aren't useful :)
[03:37:47] <jmkasunich> the driver prohibits most of the ones that result in errors
[03:38:09] <jmkasunich> because we don't allow the off time param to go below 3
[03:38:20] <SWPadnos_> yep - as long as the maxfreq is calculated from period = pw + 4, you should be OK
[03:38:33] <jmkasunich> and we don't allow a frequency higher than 10M/(pw+min)
[03:38:48] <jmkasunich> but there is still one case where it breaks
[03:38:57] <jmkasunich> gotta repeat my test to get it straight
[03:40:35] <SWPadnos_> hmm - it looks like the actual divider value needs to be pw+2 for things to stay correct
[03:40:41] <SWPadnos_> (needs a little more testing)
[03:41:29] <jmkasunich> duh
[03:41:33] <SWPadnos_> sorry - pw-2
[03:41:42] <jmkasunich> I was testing with code that limited min-space to 2
[03:41:50] <jmkasunich> even tho I had changed the source to limit it to 3
[03:41:54] <jmkasunich> (didn't make)
[03:41:56] <SWPadnos_> heh - that's why I just hardwired those
[03:42:02] <SWPadnos_> heh
[03:42:09] <SWPadnos_> actually, the min space is 2
[03:42:17] <jmkasunich> with min set to 3, I think the driver won't let you ask for anything illegal
[03:43:19] <SWPadnos_> right - easier to set min space to 3 than to check for divisor <= pw+space and divisor >=5
[03:43:39] <SWPadnos_> the 5 will be implicit in the pw + space check
[03:43:53] <jmkasunich> yep
[03:44:02] <SWPadnos_> (though pw + space is valid everywhere except at full speed)
[03:44:20] <jmkasunich> ok, max freq is now 1.428MHz (10M/7)
[03:44:41] <jmkasunich> sorry
[03:44:45] <SWPadnos_> should be 2 MHz - 2+3 period
[03:44:51] <jmkasunich> yes
[03:45:02] <jmkasunich> I only asked for 1.5, it gave me the closest
[03:45:13] <SWPadnos_> ah
[03:45:15] <jmkasunich> 2+3 is the max
[03:45:30] <SWPadnos_> thereby showing the problem with divide-based pulse generation
[03:45:36] <jmkasunich> then 3+3
[03:45:42] <jmkasunich> 4+3
[03:45:44] <jmkasunich> etc
[03:46:09] <SWPadnos_> cool - I'll try that out, along with a more sane P value ;)
[03:46:24] <jmkasunich> the HW is capable of doing 3+2, 4+2, etc... but we don't allow those to avoid weird cases
[03:46:45] <SWPadnos_> there's only one weird case actually - that's "5"
[03:46:45] <jmkasunich> seems a fair tradeoff to me
[03:47:04] <jmkasunich> 5+2?
[03:47:12] <SWPadnos_> no - 5 cycle total period
[03:47:29] <jmkasunich> well you can only get that by doing 2+3 or 3+2
[03:47:41] <jmkasunich> you're saying 3+2 doesn't work, right?
[03:47:52] <SWPadnos_> 3+2 does work, I think - hold on a sec
[03:48:28] <cradek> does anyone know how to write the equivalent of lisp's (apply '+ tuple) in python?
[03:48:31] <SWPadnos_> yep - that's fine
[03:48:41] <SWPadnos_> the actual constraints are:
[03:48:44] <SWPadnos_> 1) divisor can't be 0
[03:49:06] <SWPadnos_> 2) pw must be <= divisor + 2
[03:49:18] <SWPadnos_> 3) space must be >= 2
[03:49:46] <cradek> reduce(lambda x,y: x+y, tuple)
[03:49:51] <cradek> * cradek pukes a little bit
[03:50:04] <SWPadnos_> reduce(puke)
[03:50:19] <jmkasunich> you're asking a couple guys who have scopes hooked up to HW about lisp?!?
[03:50:27] <cradek> no, python
[03:50:33] <jmkasunich> lol
[03:50:34] <cradek> assuming you all know lisp
[03:50:39] <cradek> let's just forget I said anything
[03:50:43] <SWPadnos_> yeth - I know lithp
[03:50:54] <SWPadnos_> you thaid nothing
[03:51:08] <jmkasunich> 2+2 doesn't work, thats the case that was sneaking thru when I allowed space to be 2
[03:51:44] <SWPadnos_> right - I forgot that total = divisor+4, so since divisor must be at least 1, the total has to be at least 5
[03:52:11] <jmkasunich> strange, I could have sworn that 3+2 worked, but its not
[03:52:22] <jmkasunich> 3+2 is doing 10 instead of 5
[03:52:28] <SWPadnos_> it does here
[03:52:35] <SWPadnos_> but I'm directly setting the divisor
[03:52:48] <SWPadnos_> divisor=1, pw=3 gives 3+2
[03:53:01] <jmkasunich> ok, this is screwy
[03:53:10] <SWPadnos_> that's the special case if you allow space to be 2
[03:53:49] <SWPadnos_> I don't think there are any others - it seemed to snap to the correct waveform as soon as divisor got up to pw-2
[03:53:59] <jmkasunich> width = 2, space = 3, ask for 5MHz, the driver says I can give you 2MHz, and I get it
[03:54:12] <SWPadnos_> correct
[03:54:45] <SWPadnos_> there are two possible configurations that work for 2 MHz - 2+3 and 3+2
[03:54:50] <jmkasunich> width = 3, space = 2, ask for 5MHz, the driver says I can give you 2, but you get 1MHz
[03:55:18] <SWPadnos_> that should result in width=3, and divisor=1
[03:55:26] <jmkasunich> yes
[03:55:40] <jmkasunich> I'm almost certain that is what is going to the HW
[03:55:56] <jmkasunich> well, width = 256-3
[03:56:01] <SWPadnos_> I get 3+2 when I force pw=3 and divisor=1
[03:56:16] <jmkasunich> I get 3+7 here
[03:56:38] <SWPadnos_> but you're running that through a calc - I'm directly driving it
[03:57:34] <jmkasunich> I'm looking at the freq parameter, which is calced from 10000000.0/divisor (true)
[03:57:43] <jmkasunich> then I write divisor(true)-4 to the HW
[03:58:01] <jmkasunich> so if the freq param is 2Meg, then divisor(true) is 5, and the HW gets 1
[03:58:50] <SWPadnos_> and you get a total period of 7, or 3+7=10?
[03:58:57] <jmkasunich> 3+7=10
[03:59:16] <jmkasunich> so the true divider is 5, and its dropping every other one
[03:59:20] <SWPadnos_> do you add the space after the freq calc?
[03:59:33] <jmkasunich> space doesnt go to the HW at all
[03:59:49] <jmkasunich> I use space + width to limit treg
[03:59:52] <jmkasunich> freq
[03:59:59] <SWPadnos_> ok
[04:00:00] <jmkasunich> I'm always asking for 5MHz
[04:00:10] <jmkasunich> space+width limits it to 2MHz
[04:00:20] <jmkasunich> (3+2, 2+3, same effect)
[04:00:39] <SWPadnos_> if I set the the pulse width to 4, it pops to 4+6
[04:00:41] <jmkasunich> but I only get 2MHz if width is 2, not if width is 3
[04:00:43] <SWPadnos_> with divisor 1
[04:00:47] <jmkasunich> expected
[04:00:56] <SWPadnos_> but with pw 3, I get 3+2
[04:00:57] <jmkasunich> it can't do 4+1, so it misses one
[04:01:15] <SWPadnos_> yep
[04:01:22] <jmkasunich> looks like your recovery time might be 1 clock shorter than mine
[04:01:32] <jmkasunich> (more recent FPGA design?)
[04:02:26] <SWPadnos_> well - you should try the tests I did
[04:02:32] <jmkasunich> when I try 4+2, I get 4+8
[04:02:53] <jmkasunich> but 4+3 gives me 4+3
[04:03:53] <jmkasunich> 10+2 gives me 10+14 (24)
[04:04:16] <SWPadnos_> did you get that dcc request?
[04:04:16] <jmkasunich> 10+3 gives me 10+3 (13)
[04:04:30] <jmkasunich> yeah, but I said no ;-)
[04:04:48] <SWPadnos_> heh - try the direct route, see if your hardware is the same as mine
[04:05:04] <jmkasunich> 9+3 gives me 9+3 (12)
[04:05:14] <jmkasunich> I'm convinced that this HW needs at least 3 space
[04:05:36] <jmkasunich> so that's what I'm putting in the driver
[04:05:42] <SWPadnos_> are you running the code that enforces min space of 3?
[04:05:53] <jmkasunich> no, I hacked to allow 2
[04:06:13] <SWPadnos_> so if oyu ask for 5 MHz, it should tell you that you'll get 2.5, not 2
[04:06:16] <jmkasunich> but anytime I set it to 2 and ask for the highest frequency it thinks it can give me, it gets it wrong
[04:06:31] <jmkasunich> if I set both to 2, yes
[04:06:41] <SWPadnos_> ok
[04:06:52] <jmkasunich> but I only get 1.25Mhz
[04:06:57] <SWPadnos_> whichever - you could probably set them both to 5 min, and it wouldn't matter
[04:07:06] <SWPadnos_> 1MHz is plenty
[04:07:20] <jmkasunich> yeah
[04:07:36] <jmkasunich> especially since the encoders can't count past 300K or so
[04:07:42] <SWPadnos_> at least we're reducing the code output, by IRCing a lot :)
[04:08:47] <jmkasunich> ok, min space is 3 (which is what I already committed)
[04:08:50] <jmkasunich> on to PWM!!!
[04:09:15] <SWPadnos_> ok - I'll stop bothering you now (I've done my job ;) )
[04:10:24] <jmkasunich> you found the original off-by-4 thing, and the other limits
[04:10:55] <jmkasunich> ok, on the PWM, somethings been bothering me
[04:10:56] <SWPadnos_> yep - my part is done :)
[04:11:02] <SWPadnos_> what?
[04:11:14] <SWPadnos_> the fact that you can't test it?
[04:11:20] <jmkasunich> I'm gonn have a frequency param that affects (effects) all four channels
[04:11:31] <jmkasunich> because the hardware works that way
[04:11:41] <SWPadnos_> yep
[04:11:47] <jmkasunich> then I'm gonna have a duty-cycle pin, one per chan
[04:11:57] <jmkasunich> that can swing from +1.0 to -1,0
[04:12:14] <jmkasunich> outside that range will output 1.0
[04:12:24] <jmkasunich> maybe with a scale, maybe not (thats one question)
[04:12:31] <SWPadnos_> yI was just about to say
[04:12:53] <SWPadnos_> a scale would make sense - actually, a range
[04:13:08] <jmkasunich> I'm also gonna have min-dc and max-dc params, so you can say "don't go below 4%, don't go above 95%"
[04:13:22] <SWPadnos_> but yuu have a scale component in blocks, so it's not as necessary
[04:13:24] <SWPadnos_> ok
[04:13:27] <jmkasunich> for things like charge pumped FET drivers that don't do 100%
[04:13:52] <jmkasunich> question: do I put min-dc and max-dc for every channel (more HAL params) or for all four like the frequency?
[04:14:10] <SWPadnos_> separate - the drivers may be different
[04:14:11] <jmkasunich> the HW lets me do per-channel
[04:14:38] <jmkasunich> yeah, thats probably the right thing to do
[04:14:58] <jmkasunich> I just needed to hear somebody else say it, because I was leaning toward the copout of shareing them
[04:15:08] <SWPadnos_> shared, obviously :)
[04:15:23] <jmkasunich> you're a big help
[04:15:36] <SWPadnos_> :)
[04:15:55] <SWPadnos_> I guess I'll test estop stuff now
[04:15:57] <jmkasunich> seriously, which do you favor
[04:16:06] <SWPadnos_> separate is probably better
[04:16:10] <jmkasunich> yeah
[04:16:25] <jmkasunich> common freq because the HW corces it
[04:16:30] <SWPadnos_> right
[04:16:50] <SWPadnos_> the code is almost the same - it's just a matter of putting some code inside the loop rather than outside it
[04:16:58] <SWPadnos_> (the loops)
[04:17:13] <jmkasunich> and declaring 6 extra HAL params
[04:17:23] <jmkasunich> and making the user set them all, 90% of the time to the same value
[04:17:41] <SWPadnos_> like I said - code inside a loop rather than outside it (the creat param loop and the evaluate loop)
[04:17:52] <SWPadnos_> one signal connected to all the pins does that
[04:18:00] <jmkasunich> I'm not concerned about the code
[04:18:25] <jmkasunich> more about the user, sorting thru nine-fsckin-hundred HAL parameters ;-)
[04:18:54] <jmkasunich> I guess thats the price you pay for flexibility
[04:19:04] <SWPadnos_> hm - it's probably a pain, but you could make it so that the pwm.0 params apply to any of the others if their params aren't set
[04:19:11] <SWPadnos_> you sound like Paul ;)
[04:19:27] <jmkasunich> * jmkasunich washed his mouth out with soap
[04:19:30] <SWPadnos_> heh
[04:19:47] <jmkasunich> nah, I'll do it right
[04:20:13] <SWPadnos_> I had thought of having different modes for some hal modules - advanced and basic
[04:20:21] <jmkasunich> param not set = "no limit on duty cycle", not "use channel zero"
[04:20:39] <SWPadnos_> if you don't pass the advanced parameter, then some ins / params aren't created, and they apply in multiple places
[04:20:46] <jmkasunich> the pid module does have a cmd line arg that exports some additional parameters
[04:20:58] <jmkasunich> internal ones, for scoping if you want
[04:21:04] <SWPadnos_> as does blocks ;)
[04:21:06] <jmkasunich> like the integrator value
[04:21:48] <SWPadnos_> so - make the code depend on that as well, and get some values from shared settings in basic mode
[04:22:00] <SWPadnos_> but that's probably a discussion for later
[04:22:31] <jmkasunich> yeah
[04:22:35] <jmkasunich> much later
[04:22:50] <jmkasunich> like never - once this works I'm on to other things
[04:23:14] <SWPadnos_> I was thinking of hal in general - reduce the number of pins that need to be connected for simple setups
[04:23:52] <SWPadnos_> but it's OK if it waits for the 2nd Tuesday of next week ;)
[04:24:18] <jmkasunich> 2nd Tuesday of never
[04:24:42] <SWPadnos_> well - if you find a week with 2 Tuesdays, let me know
[04:25:05] <jmkasunich> it's getting late, went right over my head
[04:25:12] <SWPadnos_> heh
[04:25:16] <SWPadnos_> sorry
[04:25:33] <jmkasunich> not your fault
[04:25:50] <SWPadnos_> did you do two commits or one this evening?
[04:25:51] <jmkasunich> (well, partly is.... damn talkin ;-)
[04:25:54] <SWPadnos_> heh
[04:26:21] <jmkasunich> one I think
[04:26:41] <jmkasunich> yeah
[04:26:54] <SWPadnos_> ok - I thought you had said that there was a bug in that one
[04:27:01] <SWPadnos_> a miscalc or something
[04:27:16] <jmkasunich> that one uses 3 for min-space (which is correct)
[04:27:23] <SWPadnos_> ok - cool
[04:27:34] <jmkasunich> but I stupidly was still testing with the one that used 2
[04:28:16] <SWPadnos_> one day, I would like it if you used the direct-to-output version that I have, justto see if the hardware is actually different
[04:28:44] <jmkasunich> why don't you try the non-direct one?
[04:28:51] <jmkasunich> change the lim on space-min to 2
[04:28:56] <jmkasunich> ask for 5MHz
[04:28:57] <SWPadnos_> I will, and I'm sure it will work
[04:29:22] <jmkasunich> make width 5 and space 2, and see if you get 7 or 14 total
[04:29:35] <SWPadnos_> yep - will do
[04:29:43] <jmkasunich> I get 14, if you get 7 that confirms different HW
[04:30:36] <SWPadnos_> were you just looking at the freq param?
[04:30:51] <jmkasunich> no, scope
[04:31:07] <jmkasunich> the parm will promise you 7 regardless, the issue is what you actually get
[04:31:10] <SWPadnos_> I mean - what was the name of the param you were looking at?
[04:31:15] <jmkasunich> freq
[04:31:35] <SWPadnos_> ok (I'm changing the test csript to point to that one)
[04:31:41] <jmkasunich> that is the freq the driver (thinks it) is making at any given instant
[04:31:51] <jmkasunich> after limiting and rounding
[04:33:56] <SWPadnos_> interesting - I get 2.5 MHz, 200+200, when I ask for 5 MHz
[04:34:23] <jmkasunich> so its actually writing zero to the HW, and it works
[04:34:30] <jmkasunich> sortof
[04:34:44] <jmkasunich> scratch that, it does work
[04:34:47] <SWPadnos_> it can't be - that didn't work for me - pulsing stopped
[04:34:57] <jmkasunich> (the freq param says 2.5MHz, right)
[04:35:16] <jmkasunich> did you have width set to 2 when you did it>
[04:35:18] <jmkasunich> ?
[04:35:19] <SWPadnos_> hold on
[04:36:00] <SWPadnos_> with width and space set to 2, I get 2.5 MHz on the scope, and freq says 2.5 MHz
[04:36:32] <jmkasunich> something that would be interesting... hack it to print the board version code when it is doing the init scan
[04:36:57] <SWPadnos_> the 0x4x number?
[04:37:03] <jmkasunich> we may have different versions (well, we almost certainly do have differnet versions, but Jon might actually be reporting that)
[04:37:26] <jmkasunich> line 443
[04:37:38] <jmkasunich> uh, yes
[04:37:53] <jmkasunich> the 4 part is the voard id, the x part is the version
[04:38:08] <jmkasunich> mine is 41
[04:38:40] <jmkasunich> line 441 prints it, it should be in dmesg
[04:38:44] <SWPadnos_> PPMC: slot 0: ID code: 41 Univ. Stepper Controller
[04:38:54] <jmkasunich> ok, they're reporting the same version
[04:38:56] <jmkasunich> bummer
[04:39:07] <SWPadnos_> yep - not enough bits in the low nibble ;)
[04:39:10] <jmkasunich> if the version was different, the driver could set the limit to 2 or 3 base on the board
[04:39:41] <SWPadnos_> ok - I know the problem
[04:40:01] <SWPadnos_> pulsing stopped because I hadn't commented out the code to set to off if speed=0
[04:40:36] <SWPadnos_> so that was valid, even though he says it's not
[04:41:05] <jmkasunich> what else is new
[04:41:35] <jmkasunich> hmm, should I specify the min and max duty cycle as duty cycle in a float
[04:41:44] <jmkasunich> or as min and max on-time, in 100nS increments?
[04:41:44] <SWPadnos_> yes
[04:41:58] <jmkasunich> in a u16
[04:42:06] <SWPadnos_> no - the input is a float, the limits should be floats as well
[04:42:31] <jmkasunich> yeah, I guess so
[04:42:50] <SWPadnos_> and scale would of course be a float - you'd be able to connect scale to limit as well, to give "full scale"
[04:43:17] <jmkasunich> actually, except for the input itself, the rest are parameters
[04:43:28] <SWPadnos_> incidentally - the pulse width should be a float in the usc driver - specified in microseconds or something
[04:43:31] <jmkasunich> you can't connect params to anything, just set their values
[04:43:43] <SWPadnos_> makes the setting independent of the hardware, so more portable
[04:43:46] <jmkasunich> pthpppppt
[04:43:56] <jmkasunich> you're right of course :-/
[04:44:08] <SWPadnos_> hey - it's supposed to be the hardware ABSTRACTION layer ;)
[04:44:15] <jmkasunich> you suggested it, you fix it
[04:44:18] <SWPadnos_> ok
[04:44:23] <jmkasunich> ;-)
[04:45:09] <jmkasunich> you realize what a job that is.... if they specify a pulse width of 3 weeks you need to handle that
[04:45:22] <jmkasunich> likewise if they specify 150nS
[04:45:36] <SWPadnos_> incidentally, there should be a way to connect params together, like pins (just as a shortcut for making multiple settings simultaneously)
[04:45:45] <jmkasunich> they write 150nS, you immediately re-write at 100nS
[04:45:46] <SWPadnos_> well - there are hardware-imposed limits
[04:45:59] <SWPadnos_> right - just like the frequency
[04:45:59] <jmkasunich> right, you impose the limits
[04:46:12] <jmkasunich> but not invisibly - re-write the paramater value, so they know what is in effect
[04:46:27] <jmkasunich> (if they care to look)
[04:46:46] <SWPadnos_> yep - like it is now, only floating
[04:46:58] <jmkasunich> more than now
[04:47:23] <jmkasunich> now the parameter can do 0-255, we rule out 0 and 1
[04:47:41] <jmkasunich> with float, the range is much wider, but still only 254 legal values
[04:47:48] <SWPadnos_> it'll be limited from 0.2 to 2.55 then
[04:48:04] <jmkasunich> 25.5
[04:48:13] <SWPadnos_> right - rwim
[04:48:18] <SWPadnos_> (read what I mean ;) )
[04:48:19] <jmkasunich> heh
[04:48:53] <jmkasunich> I dunno, I think that is a lot of work for not much benefit
[04:48:54] <SWPadnos_> do you want the quantized value written back, or should that be transparent?
[04:49:12] <jmkasunich> write back the quantized value
[04:49:14] <SWPadnos_> ok
[04:50:16] <jmkasunich> you're gonna have to check in the RT code, because they can change it any time they want
[04:50:32] <SWPadnos_> do you thing that microseconds are a good unit for those params (not just for this hardware)?
[04:50:46] <SWPadnos_> yep
[04:50:49] <jmkasunich> if ( param != some_legal_value) { calculate some_legal_value }
[04:50:50] <SWPadnos_> think
[04:50:57] <jmkasunich> yes, uS are good
[04:51:00] <SWPadnos_> ok
[04:51:09] <jmkasunich> hmm
[04:51:15] <jmkasunich> nanosecs might be better
[04:51:20] <SWPadnos_> ok
[04:51:31] <jmkasunich> first, nanosecs are what HAL uses for thread periods and such
[04:51:36] <jmkasunich> second, you can use ints
[04:51:42] <jmkasunich> and the checking becomes somewhat easier
[04:51:51] <jmkasunich> not much, but a little
[04:52:06] <jmkasunich> foo = 10 * ( foo / 10 );
[04:52:08] <SWPadnos_> sure - I can do that - you're right, it is a bit easier, and should be faster as well
[04:52:11] <jmkasunich> correction
[04:52:17] <jmkasunich> foo = 100 * ( foo / 100 );
[04:52:30] <SWPadnos_> right
[04:52:39] <SWPadnos_> output 256 - foo/100
[04:52:43] <jmkasunich> I wonder if the compiler will try to optimize that away
[04:52:55] <SWPadnos_> shouldn't, but we'll see in a bit ;)
[04:53:12] <jmkasunich> don't divide just for output
[04:53:18] <jmkasunich> divide and write back to param
[04:53:32] <SWPadnos_> yep
[04:53:45] <SWPadnos_> actually - have you tried writing 0 to the pulse width reg?
[04:53:48] <jmkasunich> so they don't come back later and whine "I set the pulse width to 254nS, how come its 200"
[04:54:07] <jmkasunich> no, I haven't
[04:54:10] <jmkasunich> the code never will
[04:54:30] <SWPadnos_> ok - is the limit 254 or 255 clocks?
[04:54:38] <jmkasunich> before it ever gets to that 256-value, the value has been checked to be >= 2
[04:54:50] <jmkasunich> don't know, don't care
[04:55:03] <SWPadnos_> I mean zero to the hardware - 255 or 254 input value
[04:55:05] <jmkasunich> somebody who needs 25+ uS isn't gonna quibble about 100nS
[04:55:19] <jmkasunich> 255 input will write 1 to the HW
[04:55:23] <SWPadnos_> yeah - I'm just wondering what the hardware will do
[04:55:34] <jmkasunich> 256 input is illegal for u8
[04:55:42] <SWPadnos_> but not for u32
[04:55:43] <jmkasunich> dunno, not interested in finding out
[04:55:51] <SWPadnos_> OK - I will :)
[04:56:07] <jmkasunich> again, the diff between 254 and 255 is 100nS out of 25uS
[04:56:10] <jmkasunich> nobody will care
[04:56:33] <jmkasunich> have fun!
[04:56:36] <SWPadnos_> it's a matter of limiting the value to something the hardware won't choke on
[04:57:00] <jmkasunich> 256-2 thru 256-255 are known safe
[04:57:24] <jmkasunich> 256-1 doesn't do what you expect (100nS) so we forbid that
[04:57:51] <jmkasunich> I suppose if 256-256 gives you 25.6uS, might as well allow it
[04:58:11] <SWPadnos_> yeah - that's what I'm wondering
[04:58:57] <jmkasunich> this is another case where I wonder about saving the precomputed value, and only recomputing it if the param value changes
[04:59:39] <SWPadnos_> 39 cycles for a divide, vs several memory accesses, a compare, and a possible pipeline stall
[04:59:39] <jmkasunich> you have a divide, a multiply, a subtract, and two limit checks
[04:59:52] <jmkasunich> only one extra access
[05:00:12] <SWPadnos_> yeah - it's really the stall vs the divide
[05:00:19] <jmkasunich> one way: read param, do math on it, do two compares on it, write it back
[05:00:34] <jmkasunich> other way: read param, read private old param, compare, done
[05:00:58] <jmkasunich> avoiding the write is good too, prevents dirty cache lines
[05:01:11] <SWPadnos_> tre
[05:01:14] <SWPadnos_> true
[05:01:34] <SWPadnos_> that may be an optimization I want to test another fay ;)
[05:01:37] <SWPadnos_> day
[05:01:48] <jmkasunich> yeah
[05:01:59] <SWPadnos_> in fact, it's already another day, and may be bedtime
[05:02:25] <jmkasunich> getting there
[05:08:45] <jmkasunich> damn, this driver is over 1200 lines,
[05:09:22] <SWPadnos_> well - it supports a lot of hardware
[05:09:30] <jmkasunich> yeah
[05:09:32] <SWPadnos_> and most of that is exporting pins ;)
[05:09:43] <jmkasunich> Jon's really luck he isn't paying by the line
[05:09:48] <jmkasunich> not true I don't think
[05:10:43] <jmkasunich> 330 or so in the export_blah functions (including 2 copies of stepgen, one to be converted to pwmgen)
[05:11:24] <jmkasunich> 300 or so in the realtime (not counting SelRead and friends at the end)
[05:11:41] <SWPadnos_> there ought to be a macro for the hal_malloc / check for null / error if null / return construct
[05:11:45] <SWPadnos_> there are a lot of those
[05:11:52] <jmkasunich> about 300 of init, bus scan, shutdown
[05:12:32] <SWPadnos_> and the first 300 are typedefs and prototypes
[05:12:36] <jmkasunich> yeah
[05:13:31] <SWPadnos_> and a try_to_create_pin macro - that tries, then returns if the create fails
[05:14:31] <jmkasunich> the linecount could be considerably reduced just by changing:
[05:14:43] <jmkasunich> if ( retval != 0 ) {
[05:14:53] <jmkasunich> return retval;
[05:14:54] <jmkasunich> }
[05:14:55] <jmkasunich> to
[05:15:08] <jmkasunich> if ( retval != 0 ) { return retval }
[05:15:17] <jmkasunich> could also do
[05:15:25] <jmkasunich> if ( retval ) return retval;
[05:15:38] <jmkasunich> but I like to keep the {} even with a one line block
[05:15:50] <jmkasunich> less likly to screw yourself later if you add another line
[05:15:51] <SWPadnos_> or even if ((retval = hal_pin_new()) !=0) return retval;
[05:16:05] <SWPadnos_> but that's ugly
[05:16:37] <jmkasunich> esp when the actual call is long to start with
[05:16:42] <SWPadnos_> yep
[05:17:19] <jmkasunich> I want to revisit the whole export thing later
[05:17:21] <SWPadnos_> anyway - it works, and 1200 lines is only slightly longer than the nml_format switch statement ;)
[05:17:57] <SWPadnos_> yeah - we should get to that some day
[05:18:13] <jmkasunich> the sprintf aren't pretty
[05:18:36] <SWPadnos_> no - that's another good reason for hierarchical naming
[05:18:52] <jmkasunich> would be nice to have a funct that takes (char *blockname, int instance, char *pinname)
[05:19:35] <jmkasunich> dammit! I keep getting distracted
[05:19:38] <SWPadnos_> (char *basename, int instance, char *pinname) - if instance is <0, then don't use it
[05:19:47] <jmkasunich> focus John, focus
[05:19:52] <SWPadnos_> bye ;)
[05:20:00] <jmkasunich> * jmkasunich goes back to coding
[05:28:08] <SWPadnos_> it does go to 25.6 uS
[05:28:16] <jmkasunich> heh
[06:13:29] <SWPadnos_> ok - time for bed. I've got the nanoseconds working for pulse width - I'll do the other two tomorrow
[06:13:53] <SWPadnos_> good night
[06:13:58] <SWPadnos_> SWPadnos_ is now known as SWP_Away
[14:18:41] <SWP_Away> SWP_Away is now known as SWPadnos_
[23:05:09] <SWPadnos_> logger_devel: bookmark
[23:05:09] <SWPadnos_> See http://solaris.cs.utt.ro/irc/irc.freenode.net:6667/emcdevel/2005-11-30#T23-05-09