P2 PASM %00100: Pulse/cycle output
pic18f2550
Posts: 400
in Propeller 2
If I understand the documentary correctly, this example makes exactly 1 positive pulse.
dat org 0 dirl #20 ''Setup Smart Pin at P20 wrpin PulseConfig, #20 ''Set config for pulse/cycle wxpin PulseTiming, #20 ' 'Set cycle time and logic-0' period dirh #20 ''Finished setup wypin Cycles, ''Pulse count to Y register nop ''Delay two clocks for IN to drop .myloop jmp #.myloop ''Program waits forever PulseConfig long %0000_0000_000_00000_00000000_11_00100_0 ''Pulse/cycle mode Cycles long $0010 ''Pulse count of 16 PulseTiming long $01F4_05DC ''60 usec pulse, 20 usec logic-0
According to the documentation I can also reverse the polarity.
To put out logic-0 pulses, replace the dirl instruction with dirh and change the PulseConfig Mode value P5 bit to a 1: %0000_0000_000_00000_00100000_11_00100_0
The code should then look like this.
dat org 0 dirl #20 ''Setup Smart Pin at P20 wrpin PulseConfig, #20 ''Set config for pulse/cycle wxpin PulseTiming, #20 ' 'Set cycle time and logic-0' period dirl #20 ''Finished setup +++++ wypin Cycles, ''Pulse count to Y register nop ''Delay two clocks for IN to drop .myloop jmp #.myloop ''Program waits forever PulseConfig long %0000_0000_000_00000_00100000_11_00100_0 ''Pulse/cycle mode +++++ Cycles long $0010 ''Pulse count of 16 PulseTiming long $01F4_05DC ''60 usec pulse, 20 usec logic-0
I want to start several smartpins %00100: pulse/cycle at the same time.
But the pins have different drvl/drvh .
Is there a way to do this with one command?I assume the command "wypin cycl, #20" triggers the period delayed by 2 clk.
How can I interrupt a single pulse generation during output.
Comments
Cycle is 16, therefore 16 pulses.
P6 - %0000_0000_000_0000001000000_00_00000_0 P_INVERT_OUTPUT
DIRH enables the smartpin, not DIRL
Then replace #20 with "pins".
Not quite, it's one sysclock tick plus the remainder of running pulse period. The smartpin starts its period cycle when DIR goes high. Therefore the DIRH is the reference point in time.
DIRL instruction will shutdown any smartpin cycle.
What I mean there is the second DIRL is wrong. There is no finish of setup. There is only smartpin enable/go - which is DIR going high.
Eg:
EDIT: Fixed syntax error.
Ok "dirl" resets logic for smartpinn.
Which level is now at the output, or is it set to input?
What happens if now a "dirh" comes without wrpin, wxpin and wypin?
I want to hold a single pin low from the group.
Is a "wrpin #0, #pin" enough?
Yep, that instantly changes the pin back to normal.
That smartpin mode overrides pin output. There is a number of such modes. OUT stops working for the duration of those modes.
IN is always fed by smartpin event status for all smartpin modes. IN returns to normal only when smartpin is off, ie: WRPIN #0, #pin.
Signal flow is shown here - https://forums.parallax.com/discussion/comment/1519371/#Comment_1519371 I've labelled the smartpin's output SmartOut. And when the smartpin is off then SmartA passes through to IN.
OK so if I issue "WRPIN #0, #pin" it goes back to its old state.
That is, if the pin was an input before, it now becomes one again.
Yup.
Although, it should be pointed out that an output is still an input at the same time. DIR controls output enable, it doesn't stop the pin being an input.
Oh, another small detail: Each pin is independent and indefinitely remembers its own WRPIN mode. So, for example, one cog can set it up and another cog can use it in that mode. A hard reset of the whole chip is the only wired mode reset to #0.
Hello,
If I have understood everything correctly, the code below should cyclically output two pulses.
One with pulse/pause deffinition and one with pause/pulse deffinition.
Repeated DIRHs do nothing without intervening DIRLs. Sometimes no need to control DIR for a smartpin adjustment, but if you do then use both DIRL and DIRH.
First event never occurs because Y is held at zero while DIR is low, ie: The WYPIN doesn't work. Nothing happens as a result!
You've also still got the mistake in the inverted pin mode that I pointed out earlier.
I've corrected the ASCII timing graph (w1 was wrong):
The lack of reference timing makes it really hard to see that timing on a scope.
Attached is a rewritten working version with extra reference timing pin for scope trigger.
EDIT: Small change made to attached program.
These are two pulse generators in cascade.
In the 1st pulse generator the Y value of the 2nd is not set, because it is not needed and only dirh of the 1st is set.
In the 2nd one it is the other way round.
Dirl is always set because later it is not known where the chain begins and where it ends.
It is about the triggering of different impulse pattern chains with different lengths.
Here I only want to clarify how I get that with the cascading hinn.
Small question about the addpins.
in the smartpin documentation it says "DRVH #10 ADDPINS 7 ''Drive P10..P17 high".
I read that as start with pin 10 and set the next 7 pins high.
Or do I understand this wrong?
Fixed your timing diagram:
Correct.
It encodes both parts in a single number. The base pin part goes in the lower 6 bits [5:0], and the ADDPIN part goes in the next higher 5 bits [10:6]. There is a group of prop2 instructions, and use that very encoding, that perform multi-pin operations in a single instruction time.
According to Doku, this should be true.
Yep.
And a small detail: With some testing, I've worked out it takes 8 sysclock ticks for the smallest latency WYPIN response to an IN rising. Other testing says it takes 1 extra tick above instruction execution (2 ticks) for a smartpin to act. Therefore the cog sees IN at something like 5 ticks after smartpin finish. Some of that will be cog pipeline effect but some must also be smartpin finish-to-IN latency too I think.
Here's a demo that avoids the tiny 8 ticks latency by staggering the start times of the two smartpins:
It works by alternating each smartpin WYPIN command and therefore skipping every other pulse period for both smartpins.
What happens when X[31:16] = 0? Does this correspond to $10000?
What happens if X[31:16] = X[15:0] or X=0?
X[31:16] = 0 makes output stay high 100%. That's documented.
X[15:0] = 0 isn't documented and seems to be $10000 effective.
Ok.
If X[31:16] = 0, we can say that X[15:0] contains the active pulse duration.
Too bad that there is no prescaler.
the P2 (256Mhz) must be downstacked to generate low frequency pulses (below 3.9kHz).
Or is there another solution?
Wow, how long? If you specify Y > 1 with X[31:16] = 0 then you'll get a longer single pulse. It should become Y * X[15:0] sysclock ticks.
Yeah, that works well. If X = 1 then pulse length is Y ticks.
Whoa! Y is a direct active register in that smartpin mode. Which means any programmed change to Y has instant effect.
In what context?
Does the new value immediately start the counting process?
Like a WATCHDOG mode?
I don't suppose that has any influence on the code structure.
The counter should still wait until dirh is set.
Oh, that's even a 48Bit timer now.
Caveat: X must equal 1 for it to always be instant. Otherwise the base period takes control.
You can update it during the countdown to lengthen or shorten. Even a value of 1 works.
Correct.
Yep. Although, when X > 1, the response time of changes to Y is no longer perfectly in sync with program.