Need some PASM help with passing values from Spin
Painless
Posts: 69
I've haven't been able to play with my prop for quite some time, which is annoying as I was just starting to dig into PASM when I had to divert my free time elsewhere (*sigh* isn't that always the way?). I'm now working on a controllable PWM for another project (earth safe or green energy is my other hobby) but am having issues with getting data to the assembler from spin.
Here's the idea: The spin program (once I get the data passing right) will control a serial terminal through which the user can alter the PWM parameters (duty cycle, frequency etc), whenever the parameters change the spin program will stop the PWM PASM cog, supply the new parameters and start it again. The PWM PASM cog will start up, read its parameters into cog ram and then start a nice tight PWM loop. I figure with the instructions I have at the moment I should be able to get up to almost 4khz from the PWM. Naturally, I want to keep the PWM parameters in cog ram for speed.
My problem is I just cannot seem to get the parameter passing correct (just the on/off time at the moment) and it seems to be overwriting the other cog data such as the pin variable (I'm testing on a LED block atm). I'm sure that I'm just not understanding something very basic, I haven't programmed in assembler since I was 12 years old (I'm 39 now) and that was Z80.
Anyhow, here's my skeleton testing code at the moment, any help would be gratefully received:
Thanks again for any input.
Russ.
Here's the idea: The spin program (once I get the data passing right) will control a serial terminal through which the user can alter the PWM parameters (duty cycle, frequency etc), whenever the parameters change the spin program will stop the PWM PASM cog, supply the new parameters and start it again. The PWM PASM cog will start up, read its parameters into cog ram and then start a nice tight PWM loop. I figure with the instructions I have at the moment I should be able to get up to almost 4khz from the PWM. Naturally, I want to keep the PWM parameters in cog ram for speed.
My problem is I just cannot seem to get the parameter passing correct (just the on/off time at the moment) and it seems to be overwriting the other cog data such as the pin variable (I'm testing on a LED block atm). I'm sure that I'm just not understanding something very basic, I haven't programmed in assembler since I was 12 years old (I'm 39 now) and that was Z80.
Anyhow, here's my skeleton testing code at the moment, any help would be gratefully received:
CON _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 VAR byte cog long delaytime PUB Main StartPWM(10000000) PRI StartPWM (timep) delaytime := timep cog := cognew(@pwm, @delaytime) PRI StopPWM cogstop (cog) DAT org 0 pwm mov dira, pin 'Set pin to output for the PWM signal rdlong delay, par 'Get the delay time in clocks mov time, cnt 'Record the current clk add time, delay 'Add the required delay loop xor outa, pin 'Turn on pin waitcnt time, delay 'Wait until the end of the required delay xor outa, pin 'Turn off pin waitcnt time, delay 'Wait until the end of the required delay jmp #loop 'Lets go round again! time res 1 delay long 0 pin long |>16
Thanks again for any input.
Russ.
Comments
Repeat after me. "res goes after everything else". Now write it out 100 times!
It's a common beginners mistake. It bit me more than once when I was coming to grips with PASM.
Put your "time" variable after everything else and it should work nicely.
Here is the assembly listing of your code.
If you look at the bottom you will see that the way the hub loads the cog will put the contents of your "delay" where you think "time" should be... no biggie in your code,
but then it puts "pin" where "delay" should be. "pin" ends up being filled with the header of the SPIN object (which is not what you want at all and will cause odd behaviour)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lt's not particularly silly, is it?
Thank you! I knew it would be something silly. I also spotted another bug in my pin statement, I used |> instead of |<.
One more question, if I may, what is the difference between:
and
both use one long of storage, but other than that what is the difference? Both are in cog ram I believe? Is it simply the versatility with res of reserving X number of longs in one go?
Russ.
If you use "time long 0", a long of zero is compiled into your program and eventually copied into the cog memory.
If you use "time res 1", nothing is compiled into your program, but the compiler assigns the next cog memory location to the label "time". This works fine if the "res" statements are at the end of the cog's program, but doesn't work if you follow the "res" statements with something else (an instruction or "long" statement) and expect it to be in the proper place in hub memory so it can be copied to where you expect it in the cog's memory.
The main reason for having "res" is that hub memory is limited (32K bytes) and 512 longs are always copied to the cog. If you want to allocate variables in a cog program, but don't care about the initial value, you don't need to set aside hub memory as a placeholder. You can let the Spin compiler use the space for something else.
Post Edited (Mike Green) : 9/16/2009 2:15:28 PM GMT
What you're saying makes good sense. Would I be correct to assume then that if I created longs in my PASM DAT section and assigned them values via the initial spin code, when the PASM cog is started those values will be available in cog ram to the PASM program?
For example:
.... would this serve my purpose for passing my values to the assembler without it having to access hub ram?
Russ.
Post Edited (Painless) : 9/16/2009 2:33:55 PM GMT