help understanding spin and assembler memory access
Cncjerry
Posts: 64
I am having a problem understanding how sharing memory between spin and ASM works, maybe someone can point me in the right direction.
The reason I am trying the prop chip is that LCD writes, encoder reads and switch reads (with debounce) are inherently slow. I don't care if my LCD lags the UI that consists of a set of switches, encoders and joysticks as long as the LCD catches up, I am fine. This is for a radio frequency generator that ran on a large PIC chip, was converted to arduino and now to the prop. The chip, a DDS, is really only a special function DAC.
So if I have this application architected correctly, I'll have a main routine and I assume it has to be written in Spin. I would like the main routine to do initialization, housekeeping and kick-off the other cogs. I would put multiple assembler programs in DAT sections and then cognew or coginit to get them running with most of them running all the time. This I imderstand.
But is there a way to share more memory other than through the PAR register? So if I have a number of variables as defined in the main spin program, or just a user defined block of memory, can I easily modify them from assembler (running in different cogs) on the fly? Ideally, the PAR register would just point to the beginning of a shared memory space and the cogs would go from there. Is that possible?
I have about 10 variables that need to be modified across 6 or more cogs.
The main loop example:
0) The first cog is the main initialization cog. It will initialize the LCD, DDS chip, switches, etc. then kick-off the other cogs.
1) cog one is running an optical rotary encoder for fine tuning. I want it to add/subtract (modify) the base frequency depending on a tuning rate from memory. So this cog needs acess to one 48 bit word for the frequency and one byte for the freq change increments.
2) As the base frequency is changing, a tuning word of 64 bits is generated with only the low order 48bits being modified. So I was thinking about a cog that looks at the frequency set in (1) and does the calculation from a 48 bit frequency word to a 64 bit tuning word. So it needs access to the 48 bit word from (1) above and a 64 bit word for output. The output can be 48 bits.
3) Another cog is looking at the tuning word and writing it to the DDS chip over 5 wires not unlike SPI. I am considering locking the tuning word, if possible, when it is read. If the tuning word changes, this cog writes the new tuning word to the DDS chip. The DDS chip can be clocked very fast so that the frequency changes can be made at more than 100,000 changes per second. So this cog just needs access to the tuning word calc'ed in (2).
4) another cog will look at buttons for the menu system. It will signal the main cog to save/restore memory, vary the phase and amplitude of the output, etc.
5) cog to ADC the joystick L/R functions.
6) cog to ADC the joystick U/D functions.
If I write it all in Spin, then I am pretty sure this all will work across the cogs and I have tested most of the shared memory functions. But I think the interpreter running from memory is a little weak and I really want this to be responsive.
So if you see problems with sharing as above, or can point me at models, I would appreciate it.
Sorry for the long post. I would hate to go down this road if I can't get the performance boost I want. The alternative is to just take all the old PIC code, rework it for the 32bit pics, crank the PIC clock up and go from there. I love the concept of the prop chip and this app lends itself to parallel processing since the 48 bit math based on the frequency word and write to the DDS chip can all be somewhat asynchronous. I'll gladly trade-off some CNC work if someone wants to jump in here to help me architect this code.
Thanks.
Jerry
The reason I am trying the prop chip is that LCD writes, encoder reads and switch reads (with debounce) are inherently slow. I don't care if my LCD lags the UI that consists of a set of switches, encoders and joysticks as long as the LCD catches up, I am fine. This is for a radio frequency generator that ran on a large PIC chip, was converted to arduino and now to the prop. The chip, a DDS, is really only a special function DAC.
So if I have this application architected correctly, I'll have a main routine and I assume it has to be written in Spin. I would like the main routine to do initialization, housekeeping and kick-off the other cogs. I would put multiple assembler programs in DAT sections and then cognew or coginit to get them running with most of them running all the time. This I imderstand.
But is there a way to share more memory other than through the PAR register? So if I have a number of variables as defined in the main spin program, or just a user defined block of memory, can I easily modify them from assembler (running in different cogs) on the fly? Ideally, the PAR register would just point to the beginning of a shared memory space and the cogs would go from there. Is that possible?
I have about 10 variables that need to be modified across 6 or more cogs.
The main loop example:
0) The first cog is the main initialization cog. It will initialize the LCD, DDS chip, switches, etc. then kick-off the other cogs.
1) cog one is running an optical rotary encoder for fine tuning. I want it to add/subtract (modify) the base frequency depending on a tuning rate from memory. So this cog needs acess to one 48 bit word for the frequency and one byte for the freq change increments.
2) As the base frequency is changing, a tuning word of 64 bits is generated with only the low order 48bits being modified. So I was thinking about a cog that looks at the frequency set in (1) and does the calculation from a 48 bit frequency word to a 64 bit tuning word. So it needs access to the 48 bit word from (1) above and a 64 bit word for output. The output can be 48 bits.
3) Another cog is looking at the tuning word and writing it to the DDS chip over 5 wires not unlike SPI. I am considering locking the tuning word, if possible, when it is read. If the tuning word changes, this cog writes the new tuning word to the DDS chip. The DDS chip can be clocked very fast so that the frequency changes can be made at more than 100,000 changes per second. So this cog just needs access to the tuning word calc'ed in (2).
4) another cog will look at buttons for the menu system. It will signal the main cog to save/restore memory, vary the phase and amplitude of the output, etc.
5) cog to ADC the joystick L/R functions.
6) cog to ADC the joystick U/D functions.
If I write it all in Spin, then I am pretty sure this all will work across the cogs and I have tested most of the shared memory functions. But I think the interpreter running from memory is a little weak and I really want this to be responsive.
So if you see problems with sharing as above, or can point me at models, I would appreciate it.
Sorry for the long post. I would hate to go down this road if I can't get the performance boost I want. The alternative is to just take all the old PIC code, rework it for the 32bit pics, crank the PIC clock up and go from there. I love the concept of the prop chip and this app lends itself to parallel processing since the 48 bit math based on the frequency word and write to the DDS chip can all be somewhat asynchronous. I'll gladly trade-off some CNC work if someone wants to jump in here to help me architect this code.
Thanks.
Jerry
Comments
Pay attention to the VAR section, and the GetValues in the DAT section
Most of the serial objects use rx and tx buffers in hub RAM while the bit bashing driver is running in PASM in it's own cog. It's very common to have PASM cogs reading and writing to hub RAM. There are lots of examples of this (Average Joe's code being one).
I think your being very conservative with your cog allocations. You'll be able to have a single cog to multiple tasks that you presently assign to their own cog.