You can have the DIRL-WRPIN-WXPIN-DIRH along with filling out initial parameters in a setup routine before the servo loop actions, and then simply adjust WYPIN in the servo loop. The new Y value takes effect on the next frame period.
You can have the DIRL-WRPIN-WXPIN-DIRH along with filling out initial parameters in a setup routine before the servo loop actions, and then simply adjust WYPIN in the servo loop. The new Y value takes effect on the next frame period.
Yep, I did see that behavior -- was looking to avoid a second method. The nice thing is that there's no "servo loop" now unless I want to do ramping. If that's case, I'd know the servo is setup and can use wypin.
JonnyMac,
It's reasonably safe to assume a pin is configured as you last left it. If someone were to use your code in a system, it would generally be a bug to have more than one piece of code messing with the same pin.
So, just do wypin's to move the servo.
Or, is this somehow cleared when long repository mode is selected?
A little oddly, repository smartpin modes retain the Z value, and can be read out with RDPIN, even while unconfigured - WRPIN #0, pin. And another oddity is DIR must be raised for WXPIN to work. Presumably to action the Z change.
I'm not much of an Arduino user, but I do appreciate the millis() function as it's very useful for differential timing. In many of my P1 projects I create "maintenance" cog that runs a 1ms loop so that I can update a global variable called millis. With the 64-bit counter in the P2, we can duplicate the Arduino's millis() function very easily.
pub millis() : ms | lo, hi, tixms
'' Return milliseconds since reset.
org
getct hi wc ' get cnt (now)
getct lo
rdlong tixms, #$44 ' get clkfreq
qdiv tixms, ##1000 ' get ticks/ms
getqx tixms
setq hi ' divide cnt by ticks/ms
qdiv lo, tixms
getqx ms
end
If I did the math correctly the 64-bit counter running on my 200MHz system will not roll-over for about 2900 years.
If @cgracey finds room in the Spin2 interpreter engine I think this would be a worthy addition.
Another approach for event timing. Use mark() to capture the system counter at the beginning of the event, and delta_ms() to return the elapsed time in milliseconds.
pub mark() : lo, hi
'' Return 64-bit system counter.
org
getct hi wc ' get cnt (now)
getct lo
end
pub delta_ms(mlo, mhi) : ms | dlo, dhi, tixms
'' Return delta milliseconds between mark point and system counter.
org
getct dhi wc ' get cnt (now)
getct dlo
sub dlo, mlo wc ' delta := now - mark
subx dhi, mhi
rdlong tixms, #$44 ' get clkfreq
qdiv tixms, ##1000 ' get ticks/ms
getqx tixms
setq dhi ' divide delta by ticks/ms
qdiv dlo, tixms
getqx ms
end
Please, check last silicon's instruction spreadsheet.
To ensure you can grab a full 64-bit CT properly, you'll need to change the operations order, as follows:
org
getct hi wc ' get 64-bit cnt
getct lo
rdlong tixms, #$44 ' get clkfreq
qdiv tixms, ##1000 ' get ticks/ms
getqx tixms
setq hi ' divide cnt by ticks/ms
qdiv lo, tixms
getqx ms
end
The first getct (with wc) would retrieve the upper long, and shields the next getct (without wc) against any possible interrupts that could, eventually, occur in between them.
Otherwise, if an interrupt event occurs right in the middle of the sequence, the 64-bit value integrity could be lost.
Thank you, Herique -- that's a detail I missed (so used to P1 I don't think about interrupts). I originally had it as you suggest, but thought it best to grab the low part first as it's changing the fastest. Will update my code. Again, thanks.
I've been following your code examples with real interest, as some kind of a "shot" of insight.
ATM, while I wait for some very important changes in my day-by-day life, I prefere to read, understand and try to edit other people's work, as a thought exercise.
Keeps my mind fresh, and my back muscles firmly attached to that chair, while, perhaps, Corona just passes by, next street or in front of my actual residence.
Well, I'm very late to the P2, and considering how many cool new features there are, find that one could become overwhelmed. To that end I am tackling little things, one chunk at a time, and, hopefully, some of my little experiments will prove useful to others. Thank you for the feedback as it helps me to improve my own code. I've written dozens of commercial programs for the P1, and one client is asking about the P2. I want to be ready to port that code to the P2 when they're actually ready start a new project. It's an exciting device.
Another reason to order them as high then low - It's undocumented but I think Chip has implied that GETCT WC has a hidden +2 to the 64-bit count so that it's then count aligned to the partnering subsequent regular GETCT.
Another reason to order them as high then low - It's undocumented but I think Chip has implied that GETCT WC has a hidden +2 to the 64-bit count so that it's then count aligned to the partnering subsequent regular GETCT.
That's right. I need to review the documentation to make sure that's covered.
That verilog bamboozles me. I don't understand things like 32'h2. EDIT: And I thought regscan() was to be ignored too, but that snippet is basically all regscans.
There's a menagerie of symbols and operators inside the regscan brackets. How does that all work? Is that Chip just being concise where it would be clearer done as lots of individual lines per regscan?
Give the timespan between posts (macro definition versus CT use-case) I really don't know if he has edited, or even completelly overhauled it, in order to get the last code the way he wanted, in order to complete the actual P2 incarnation.
JIT: IMHO, and under the light of the comments appended to the ctlx and cthx-defining macro-expansions, 'h2, 'h1 and 'h0 were simply three moments in time (sysclk-wise), being 'h2 the "now" (or "last"), and 'h1/'h0 just the two preceeding/previous states, thus suggesting the use of registers, if not to hold the whole CTh/l state, at least some important/valuable results, produced at each stage of the logic.
Based on the above premises, and, sure, from a layman' POV (myself), they are barely/mostly readable/understandable, mainly because the comments were explaining what he had been coding.
`define regscan(regname, reginit, regcond, regval) \
always @(posedge clk or negedge resn) \
if (!resn) \
regname <= reginit; \
else if (regcond) \
regname <= regval;
The terms are as follows:
1st: The name of the register (group)
2nd: The initialization value on chip-wide reset
3rd: The condition on which it is loaded
4th: The value with which it is loaded
Having all registers receive the same chip-wide reset allows the synthesis tools to generate the scan chain, where all the registers (flipflops) on the chip get chained together in a serial fashion for writing and reading. I think Wendy broke all this into five scan chains which work over sets of pins when the TEST pin is high.
There is a gotcha to be aware of with the pulse modes. These modes cycle their pulse "base period" from the moment DIR is raised. This means that any WYPIN pulses/steps to be produced at the pin will only begin at the start of the following base period after WYPIN was executed. There is an exception: If in transition mode (M=%00101) and the base period = 1 (WXPIN #1), then there is no gotcha.
It only shows up as a complication when trying to phase align the timing of two components like with SPI clock and data for example.
Comments
My pins for the encoder: I created a constant that sets the B pin as the next up from A. To initialize the encoder: Finally, a little test loop. In this case pressing the button on the encoder zeros the count. The encoder I have has detents and gives four counts per click. I use sar 2 as it's slightly faster than / 4.
It's reasonably safe to assume a pin is configured as you last left it. If someone were to use your code in a system, it would generally be a bug to have more than one piece of code messing with the same pin.
So, just do wypin's to move the servo.
No. The count is cleared to zero.
Or, is this somehow cleared when long repository mode is selected?
1) You can preset the encoder to any value in its defined range
2) You can range limit the value of the encoder
It's a cold, rainy day in SoCal, so I'm going to put on some more coffee and figure it out with a couple of offset variables in my P2 object.
If @cgracey finds room in the Spin2 interpreter engine I think this would be a worthy addition.
Edit: Corrected capture of system counter.
Edit: Corrected capture of system counter.
Please, check last silicon's instruction spreadsheet.
To ensure you can grab a full 64-bit CT properly, you'll need to change the operations order, as follows:
The first getct (with wc) would retrieve the upper long, and shields the next getct (without wc) against any possible interrupts that could, eventually, occur in between them.
Otherwise, if an interrupt event occurs right in the middle of the sequence, the 64-bit value integrity could be lost.
Hope it helps
Henrique
I've been following your code examples with real interest, as some kind of a "shot" of insight.
ATM, while I wait for some very important changes in my day-by-day life, I prefere to read, understand and try to edit other people's work, as a thought exercise.
Keeps my mind fresh, and my back muscles firmly attached to that chair, while, perhaps, Corona just passes by, next street or in front of my actual residence.
That's right. I need to review the documentation to make sure that's covered.
https://forums.parallax.com/discussion/comment/1453465/#Comment_1453465
'regscan is a macro and includes the always @() if I remember correct. But that Verilog is not really understandable without seeing the macro.
Andy
forums.parallax.com/discussion/comment/1379869/#Comment_1379869
Give the timespan between posts (macro definition versus CT use-case) I really don't know if he has edited, or even completelly overhauled it, in order to get the last code the way he wanted, in order to complete the actual P2 incarnation.
JIT: IMHO, and under the light of the comments appended to the ctlx and cthx-defining macro-expansions, 'h2, 'h1 and 'h0 were simply three moments in time (sysclk-wise), being 'h2 the "now" (or "last"), and 'h1/'h0 just the two preceeding/previous states, thus suggesting the use of registers, if not to hold the whole CTh/l state, at least some important/valuable results, produced at each stage of the logic.
Based on the above premises, and, sure, from a layman' POV (myself), they are barely/mostly readable/understandable, mainly because the comments were explaining what he had been coding.
The terms are as follows:
1st: The name of the register (group)
2nd: The initialization value on chip-wide reset
3rd: The condition on which it is loaded
4th: The value with which it is loaded
Having all registers receive the same chip-wide reset allows the synthesis tools to generate the scan chain, where all the registers (flipflops) on the chip get chained together in a serial fashion for writing and reading. I think Wendy broke all this into five scan chains which work over sets of pins when the TEST pin is high.
It only shows up as a complication when trying to phase align the timing of two components like with SPI clock and data for example.