Using a buffer in PSAM
BobbyV
Posts: 19
Hello All,
I'm trying to implement a buffer in cog ram using PSAM. What I want to do is take 128 samples using an ADC incrementally saving them into the buffer and after the sample process read each sample in the buffer for data processing. The reason for this is so I can quickly take a bunch of samples at a high sample rate, then post process each sample. The processing for each sample takes longer than the time period between each sample, which leaves me with the choice to either lower my sample rate (which would be no good) or use a buffer.
I found a method which I have seen others use, but I don't completely understand how it works. It uses the "movd" instruction which is used for "self modifying code" according to the propeller manual. Since I don't understand how the registers are being changed (and what happens when I try to loop back to a previous place), I see visions of catastrophic failures with code being unintentionally written over and loops going crazy!
I posted the code I would used based on forum wisdom using movd. I also added the approach that I first thought of, using a spin thought process which I'm not too sure would translate into PSAM.
Could someone please explain how this changing the destination field stuff works? or if my method would work?
I'm trying to implement a buffer in cog ram using PSAM. What I want to do is take 128 samples using an ADC incrementally saving them into the buffer and after the sample process read each sample in the buffer for data processing. The reason for this is so I can quickly take a bunch of samples at a high sample rate, then post process each sample. The processing for each sample takes longer than the time period between each sample, which leaves me with the choice to either lower my sample rate (which would be no good) or use a buffer.
I found a method which I have seen others use, but I don't completely understand how it works. It uses the "movd" instruction which is used for "self modifying code" according to the propeller manual. Since I don't understand how the registers are being changed (and what happens when I try to loop back to a previous place), I see visions of catastrophic failures with code being unintentionally written over and loops going crazy!
I posted the code I would used based on forum wisdom using movd. I also added the approach that I first thought of, using a spin thought process which I'm not too sure would translate into PSAM.
Could someone please explain how this changing the destination field stuff works? or if my method would work?
DAT '' A buffer method I have seen others use: '' Write 128 samples to a buffer in cog ram org 0 entry mov count, #128 movd :FILBUF, Buffer :SAMPLOOP '' ''ADC Sample code here '' :FILBUF mov 0-0, sample add :FILBUF, #$100 djnz count, #:SAMPLOOP '' Next, read a sample from the buffer, do something with the sample, increment and loop mov count, #128 movd :READBUF, Buffer :PRLOOP '' '' Process code here '' :READBUF mov temp,0-0 add :READBUF, #$100 '' '' Processing code here '' djnz count,#:PRLOOP '' The buffer method I thought of to write to buffer (reading would be similar), but not sure if it works mov count, #128 mov BUFADR, #Buffer :SAMPLOOP '' ''ADC Sample code here '' mov BUFADR, sample add BUFADR, #1 djnz count, #:SAMPLOOP '' variables count long 0 sample long 0 temp long 0 BUFADR long 0 Buffer res 128 fit
Comments
For the reading part though, it looks like you should modify the source and not the destination....
So you'd need:
movs :READBUF, Buffer
and
add :READBUF, #1
Also, I think the number you need to add to destination, 512, is bigger than you can have as an explicit number and so you need to use a register for this value, like:
d0 long 1 << 9
The source field is the lower 9 bits of the (32 bit) long, the destination field is the next 9 bits.
So in order to step the source field you need to add 1, not 256. To step the destination field you need to add 1<<9 (512) which is too large to be an immediate value.
So you could add a value for the later:
Also you must use immediate mode to pick up the addresses to load into the fields, so use (You don't want to read the contents of Buffer and put that into the instruction, you want the address of Buffer)
And then the increments become
Note that any write to cog ram will not be available as an instruction fetch till after the next instruction, so avoid doing
http://obex.parallax.com/objects/268/
James
So to make sure I understand correctly, from the following code:
"movd" moves the address at #Buffer into the destination field of the register located at :FILBUF
then, the '0-0' tells the 'mov' instruction located at register :FILBUF to move sample to the location already set in its the destination field by the previous "movd"?
The "0-0" is just a place-holder, you could have anything there -- that said, it's worth having something that will stick out to say, "this field is modified by something else" and "0-0" is what many use to do that. The movd instruction at the top of your code simply overwrites the destination field at :FILEBUF. This works because everything is sitting in the same RAM pool; you can modify anything, even instructions.
Thanks!