Feedback Servo (example of setting up PASM2 cog)
tomcrawford
Posts: 1,126
Here is a sample program with a spin program starting a pasm2 program in a separate cog.
I am posting this for two reasons: First, I'm pretty sure there are others with an ES board that might profit from a simple example that includes intra-cog communication. Secondly, I am hoping the experts will dismantle the program and tell me how to do it correctly, that I may profit.
AdThanksVance
I am posting this for two reasons: First, I'm pretty sure there are others with an ES board that might profit from a simple example that includes intra-cog communication. Secondly, I am hoping the experts will dismantle the program and tell me how to do it correctly, that I may profit.
AdThanksVance
CON oscmode = $010c3f04 'standard stuff freq = 160_000_000 baud = 115200 'must configure RUN command to match this OBJ ser: "PrintfSerial" 'access to Propellor output (output only) var long param 'PASM cog will write results here byte cog pub main clkset(oscmode, freq) ser.start(baud) 'start up serial terminal ser.str(string("hello, world")) ser.nl cog := cognew(@entry, @param) 'send ADDRESS of param ser.str(string("cog started: ")) ser.dec(cog) ser.nl repeat 'forever 10 times a second ser.str(string("Returned Value is: ")) ser.dec(Param) ser.nl waitcnt(clkfreq/10+cnt) DAT entry ORG 0 mov hubAdrs, ptra 'boss cog passed an address: save it 'Monitor feedback pin of 360 Feedback servo and calculate angle in degrees 'have to do double precision to avoid overflow top nop L1 test ina, FBPinMask wcz if_NZ jmp #L1 'wait for a low L2 test ina, FBPinMask wcz if_Z jmp #L2 'wait for beginning of high getct stime 'save count at very beginning of high pulse L3 test ina, FBPinMask wcz if_NZ jmp #L3 'wait for end of high (beginning of low getct ltime 'save count at beginning of low pulse L4 test ina, FBPinMask wcz if_Z jmp #L4 'wait for end of low getct etime 'save count at end of low pulse mov ttime, etime sub ttime, stime 'compute total time in clock tics mov htime, ltime sub htime, stime 'compute high time Qmul htime, ##360 'multiply htime by 360 getqx work 'lower part of product getqy work1 'upper part of product setq work1 'upper part QDiv work, ttime 'divide product*360 by total time getqx work 'ratio in degrees wrlong work, hubAdrs 'save it for display jmp #top 'forever FBPinMask long 2 'feedback pin connected to I/O 1 hubAdrs res 1 'hub address of "param" work res 1 work1 res 1 stime res 1 'CNT at beginning of high time ltime res 1 'CNT at beginning of low time etime res 1 'CNT at end of low time ttime res 1 'total period in clock tics htime res 1 'high time in clock tics
Comments
%10011 = For X periods, count time
%10100 = For X periods, count states
FWIR, you can config 2 Smart pins to one mode each, to capture Period and HI-Time in SysCLKs.
Chip said those can start at the same time, and those have finer granularity that a SW polling loop, and do not use a COG to poll for edges.
starting the cog. Then the cog doesn't have to waste any instructions getting the address, as its copied into
cog memory/register as the cog starts.
However that isn't thread-safe, so if several Spin cogs try to do it simultaneously they can clash
over the address and corrupt each others setup, so its not the best method for a utility cog/library
that several things might all want to use (such as a comms cog, SPI driver etc) - the PTRA parameter
passing is a safe way, and can be done by PASM cog starting another PASM cog, where a SETQ before
a COGINIT can be used to set the initial PTRA value in the new cog.
PTRA is the Prop2 replacement for the PAR register in Prop1 code.