Problems starting cogs from spin&asm
ManAtWork
Posts: 2,176
I used cognew in spin for many times but now I need to start a cog from assembler for the first time. The following simple test program starts one cog from spin which executes assembler at label start1. This cog in turn starts a second cog which should execute assembler at label start2.
So I'd normally expect that the output is something like...
cog=2 (cog#0 and serial driver already running, cog#2 started by cognew)
result1=destination field for coginit
result2=3 (next free cog started by coginit)
result3=1 (test flag written by last cog)
However, this doesn't work. The output is
CON _clkmode = xinput + pll16x 'external oscillator, frequency = 5MHz * 16 = 80MHz _xinfreq = 5_000_000 baudRate = 115_200 OBJ com : "FullDuplexSerial" VAR byte cog PUB Start WaitMs (2000) com.Start(31, 30, 0, baudRate) cogInfo:= @result3 << 18 + @start2 << 4 com.str (string ("cogInfo=" ) ) com.hex (cogInfo, 8) com.str (string (" @result3=" ) ) com.hex (@result3, 8) com.str (string (" @start2=" ) ) com.hex (@start2, 8) com.tx (13) cog:= cognew (@start1, @result1) WaitMs (100) ' wait for cogs to startup... com.str (string ("cog=")) com.hex (cog, 8) com.str (string (" result1=")) com.hex (result1, 8) com.str (string (" result2=")) com.hex (result2, 8) com.str (string (" result3=")) com.hex (result3, 8) com.tx (13) repeat PRI WaitMs (Duration) waitcnt(((clkfreq / 1_000 * Duration - 3932)) + cnt) DAT ORG start1 mov adr,PAR add adr,#4 or cogNo,cogInfo ' or cogInfo + number wrlong cogNo,PAR ' write to result1 coginit cogNo wr ' remember ID of started cog wrlong cogNo,adr ' write ID to result2 stop1 jmp #stop1 adr long 0 cogInfo long 0 ' @result3<<18 + @start2<<4 set from spin cogNo long 1<<3 ' No 8 means next free cog result1 long 0 result2 long 0 DAT ORG start2 wrlong flag,PAR ' write #1 to result3 stop2 jmp #stop2 flag long 1 result3 long 0
So I'd normally expect that the output is something like...
cog=2 (cog#0 and serial driver already running, cog#2 started by cognew)
result1=destination field for coginit
result2=3 (next free cog started by coginit)
result3=1 (test flag written by last cog)
However, this doesn't work. The output is
cogInfo=01700500 @result3=0000005C @start2=00000050 cog=00000002 result1=01700508 result2=00000003 result3=00000000Result2 is written as 3 so it seems that coginit starts a cog. But the final flag is not written to result3. Depending on the length of code (inserting or commenting out some commands...) I sometimes get crashes so that the second line is not printed at all. So I guess that coginit does something but not the right thing, i.e. PAR or start adress point to something invalid. What have I done wrong?
Comments
The address bits of the coginit argument are the upper 14 bits only, you need to mask the lower two bits for each address (start and par) and adjust the bit shift.
Something like:
I haven't tested the code above so it is possible that I missed something, but that's the concept.
Thanks a lot. Now it works.