Passing Parameters from Spin to PASM
doggiedoc
Posts: 2,245
Hi all - need a little help on this one. I've read all the examples and watched the webinar clips but I just can't get my code to work.
I'm trying to pass a variable to an assembly routine that toggles a pin (LED). I started with the example in the manual and trying to expand on it.
Ultimately I plan to have the SPIN code pass different pin values to new cogs. But I can't seem to get this one working.
Help in understanding is greatly appreciated.
Doc
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
There are 10 types of people in the world, those that understand binary and those that don't.
I'm trying to pass a variable to an assembly routine that toggles a pin (LED). I started with the example in the manual and trying to expand on it.
{{ AssemblyToggle.spin }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 VAR long thePin PUB Main {Launch cog to toggle pin in a loop cycle} thePin := 16 cognew(@Toggle, @thePin) 'Launch new cog DAT {Toggle thePin} org 0 'Begin at Cog RAM addr 0 Toggle mov VAddr, par rdlong pin, VAddr mov dira, Pin 'Set Pin to output mov Time, cnt 'Calculate delay time add Time, #9 'Set minimum delay here Increment waitcnt Time, Delay 'Wait add Delay, IncValue 'Increment Delay value max Delay, MaxDelay wc 'Set Maximum Delay xor outa, Pin 'Toggle Pin if_nc jmp #Decrement 'jump to Decrement loop jmp #Increment Decrement waitcnt Time, Delay 'Wait sub Delay, IncValue 'Increment Delay value min Delay, IncValue wc 'Set minimum Delay xor outa, Pin 'Toggle Pin if_c jmp #Increment 'jump to increment loop jmp #Decrement Pin long 0 'Pin number Delay long 1_000_000 'Clock cycles to delay IncValue long 50_000 'increment value MaxDelay long 10_000_000 'maximum delay VAddr long 0 Temp long 0 Time res 1 'System Counter Workspace
Ultimately I plan to have the SPIN code pass different pin values to new cogs. But I can't seem to get this one working.
Help in understanding is greatly appreciated.
Doc
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
There are 10 types of people in the world, those that understand binary and those that don't.
Comments
kuroneko is correct. You need the mov and shl instructions, then you need to change "pin" to "temp" in all the instructions that follow.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Propeller Wiki: Share the coolness!
Chat in real time with other Propellerheads on IRC #propeller @ freenode.net
Safety Tip: Life is as good as YOU think it is!
So I am passing the address of the "thePin" from spin to "VAddr" in asm and reading the value into "pin" in asm correctly, but need to set a mask on the direction ports. Is that correct?
I think I'm missing a concept. Sorry to be so dense but the pin mask seems to work. When I assign a different value to "thePin" in spin the correct LED eventully comes on but it takes a minute or more before it does and then it isn't flashing as it did when the value has hard coded in ASM. Is it a delay value issue I don't understand? I think I am missing something (conceptually) here.
Thank you all for your patience with my ignorance.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
There are 10 types of people in the world, those that understand binary and those that don't.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
There are 10 types of people in the world, those that understand binary and those that don't.
I don't see any different behaviour except that I can change the pin index easily. No delay, nothing. If you still have it, post the exact code which shows the 1min delay.
There's another way to do this, but it may not be the education you are looking for. You can declare variables in the DAT section only and populate them from spin before launching a cog and they will have the value assigned to them in spin. I'm sure Mike and kuroneko know why this works and maybe they will explain it to both of us.
Here's a modified version of your code which shows how that works.
I've found this useful on many occasions. Maybe someone can explain why this works.
Regards,
Peter
By the way, it takes about 100us to copy the 512 longs and the COGNEW doesn't wait. The new cog is still copying stuff when your main program continues. That's important if you're starting two cogs with the same assembly program and you use this technique to configure each cog's program. You have to wait for the 1st cog to finish loading before you can change the data needed for the 2nd cog.
Thanks for the prompt response and explanation. Especially about the time required to spin up a new cog and the fact that the parent cog doesn't wait. That could produce very strange results if not considered.
Regards,
Peter
kuroneko - Thank you. It works now, But I'm not quite clear on why? Can you help me understand? Is it the use of the reserved long "Time" instead of local asm variables? If so, can you (or somebody) help me understand why?
Thanks in advance!
Doc
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
There are 10 types of people in the world, those that understand binary and those that don't.
As for using Time [noparse][[/noparse] 1], at this point it is unused (it gets filled later with cnt). So I used it as a temporary register. I could have used (nearly) anything else.
[noparse][[/noparse] 1] The only difference between res and long is that the former isn't initialised.
Here's the old code that has the delay issues.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
There are 10 types of people in the world, those that understand binary and those that don't.
Thanks! I have learned something. (my goal all along!)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
There are 10 types of people in the world, those that understand binary and those that don't.
I'm still trying to figure out this PAR stuff.. Why would the 2 bits be forced to Zero.. wouldn't that affect what you are passing to ASM. This PAR stuff really confuses me. If you have time can you explain. Also what are the other ways to pass information from spin to ASM.
Have a look in the Propeller Manual (PASM coginit, around page 366). It explains this more detailed.
1) Pass the address in PAR of a small parameter table. This table contains longs (because of the limitation in PAR values), but can contain other data sizes just aligned to a long boundary.
2) Store the parameters directly into the assembly code before it's started by COGNEW as is shown in this thread with thePin.
Of course you can use a combination of these two methods as well. You can also pass a small amount of data (up to 14 bits) directly in PAR.
So assuming on a particular pass through the above spin loop thePin is assigned a value of 16 (%00000000_00010000). Then in the cognew call the address of thePin is passed into the new cog's par register. So now thePin and par both point to the same address.
Now rdlong copies the value from par to Time but because par is only 14 bits the value of Time is %000000_00000100 - correct? Then we shift the bits left by 1? but we still only have %0000000_00001000 shouldn't we shift left by 2?
I'm confused.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
There are 10 types of people in the world, those that understand binary and those that don't.
I think I understand now.
Actually - I don't think that's it now. My explanation falls apart when I try it with a value of 23 %010111 is %00101 is 5 so shifting %00000001 5 bits is not it. DOH!! I'm confused again.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
There are 10 types of people in the world, those that understand binary and those that don't.
Post Edited (doggiedoc) : 10/24/2009 2:56:47 AM GMT
By my understanding.....which please remember I am limited. SHL does exactly that. It shifts the digits "Pin" to the left by the amount of "Time". If time is 1 the starting number (Pin) %0000_0000_0000_0001 will end up %0000_0000_0000_0010
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Are you addicted to technology or Micro-controllers..... then checkout the forums at Savage Circuits. Learn to build your own Gizmos!
I'm only guessing as to what your problem here is. So I hope that clears it up [noparse]:)[/noparse]
Post Edited (kuroneko) : 10/24/2009 6:38:38 AM GMT
did you ever use PASD the Propeller Assembler-Debugger
to watch what is going on ?
best regards
Stefan
@kuroneko - thanks for the explanation
The code is performing as expected so no problem there. I just am trying to clarify what exactly is happening so I understand the code better.
Thanks again!
@Stefan - I have not tried PASD. I'll search for it. I have tried GEAR but can't get it to perform as expected.
@James- apparently I need someone to draw me some pictures! LOL
Thank you all,
Doc
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
There are 10 types of people in the world, those that understand binary and those that don't.
You download your code with the added debug-kernel and start the code
if you let it run your PASMcode is executed like always. The debug-kernel
uses the feature that you can write to every single RAM-adress (self-modifying code)
best regards
Stefan