Pass_Parameters model - handling arrays
bob_g4bby
Posts: 473
The Pass_Parameters model in the OBEX seems to be a neat way of providing access for SPIN and PASM based cogs to a common block of global variables. But the example shows only longs being shared - what if arrays etc. need to be shared? The answer was simple, even to a SPIN newby like me, use a pointer to the array, which being a long in size, fits into the parameter list nicely. Here's the code I used to test it out. The SPIN code defines the array and initialises the array pointer, waits a short while and then displays the first element in the array. Meanwhile, a cog is started with PASM code, which reads the array pointer and sets that first sample with two constants. Here's the code:-
'' =================================================================================================
''
'' File....... Pass_Parameters - Array of Structures example.spin2
'' Purpose.... Demonstrate passing an array, from SPIN2 to PASM2
'' Author..... Bob Edwards, based on Michael Mulholland's model
'' Updated.... 5 Dec 2025
''
'' =================================================================================================
''
'' Instructions
''
'' Connect a P2 Propeller Board to your computer
'' Load this code into Spin Tools IDE, then press CTRL+F10 to load into RAM with DEBUG mode enabled
'' Observe the debug output!
''
'' Summary of demonstration
''
'' The SPIN2 code runs in Cog0, and is contained within the "Main()" routine.
'' The PASM2 code runs in Cog1, and is contained within the DAT block
''
'' Both Cogs share access to the same global variables, "PARAM"
'' The address in memory for the PARAM variables is passed to the PASM2 Cog when it is loaded
''
'' SPIN2 accesses the PARAM values directly: PARAM[bufferptr], etc..
'' PASM2 accesses the PARAM values with a pointer called PTRA: PTRA[bufferptr], etc..
{Spin2_v50}
CON { timing }
_xinfreq = 20_000_000
_clkfreq = 180_000_000
CON { data structures }
sigbuffsize = 1024
STRUCT sample (real, imag) ' one signal sample
STRUCT sigbuff( sample iqsample [sigbuffsize] ) ' array of samples
VAR { global variable definitions }
long PARAM[PARAM_COUNT]
sigbuff BUFFER ' an actual array of samples
CON { index constants } ' this index can contain any amount of global variables - just the one in this example, though
#0, BUFFERPTR, PARAM_COUNT ' the bufferptr will point to BUFFER, once initalised by SPIN code
''' ------------------------------------------------------------------------------------------------------
PUB Main() | cog_id { SPIN2 code }
''' Set some default values
PARAM[BUFFERPTR] := @BUFFER ' bufferptr now points to BUFFER
''' Launch and run PASM2 code in new cog (processor core)
cog_id := coginit(COGEXEC_NEW, @ENTRY, @PARAM)
''' Display confirmation of new cog number in debug console
debug("Parameter test cog launched, ", udec(cog_id))
waitms(100) ' wait for the PASM in COG1 to launch fully
debug(udec(BUFFER[0].iqsample.real, BUFFER[0].iqsample.imag)) ' show that PASM code has written to the first sample in BUFFER and SPIN code can read it
repeat
waitms(500) ' and loop stop
''' ------------------------------------------------------------------------------------------------------
DAT { PASM2 code }
org
ENTRY
rdlong ptrb, ptra[BUFFERPTR] ' set ptrb to point to BUFFER
wrlong ##1234, ptrb++
wrlong ##5678, ptrb ' write two constants to the first sample
loop
waitx ##clkfreq_/2
jmp #loop ' and loop stop
''' Uninitialized data
''' ------------------------------------------------------------------------------------------------------
