Accessing Cog memory...
Someone, please enlighten me!
I can't figure out why this program stops after one iteration...
It is a small test program, just to venture a little bit into the world of PWM... I'll post the program (it is a bit cluttered with amongst other things the "add dummy,#1" etc. It's there only to make the loop sort of equally long...)
Now, it loops just fine as long as i put a value between 1 and 3 where i marked it in red, so it has to do with:
But why can't i read more than three longs from sampleSet?
I'm probably missing something obvious, but i have read the manual a couple of times today, and i can't still find out what i'm doing wrong...
In hope for a helpful answer,
Micke
I can't figure out why this program stops after one iteration...
It is a small test program, just to venture a little bit into the world of PWM... I'll post the program (it is a bit cluttered with amongst other things the "add dummy,#1" etc. It's there only to make the loop sort of equally long...)
CON
_CLKMODE = RCSLOW
' _CLKMODE = XTAL1 + PLL1X
' _XINFREQ = 6_000_000
PUB Main
cognew(@entry, 0)
DAT
org 0
entry
mov dira,DACpin
mov r2,#1
mov sampleCtr,#0
:LoopWaveform
mov dutyCtr, #0
shl r2,#23
mov outa, r2 'put one on pin 23
mov r1,#sampleSet
add r1,sampleCtr 'load sample
mov sample,r1
:PinHigh
add dutyCtr, #1
add dummy,#1
sub dummy,#1
add dummy,#1
cmp dutyCtr, sample WZ 'loop high part of duty cycle
if_NZ jmp #:PinHigh
mov r2,#0
shl r2,#23
mov outa, r2 ' put zero on pin 23
add sampleCtr,#1
cmp sampleCtr,[COLOR="red"]#32[/COLOR] WZ 'shift into next sample
if_Z mov sampleCtr,#0
mov r2,#1
:PinLow
add dutyCtr, #1
sub dummy,#1
add dummy,#1
sub dummy,#1
cmp dutyCtr, dutyLen WZ 'loop low part of duty cycle
if_NZ jmp #:PinLow
jmp #:LoopWaveform
sampleSet
long 1,2,3,4
long 5,6,7,8
long 9,10,11,12
long 13,14,15,16
long 15,14,13,12
long 11,10,9,8
long 7,6,5,4
long 3,2,1,0 'a basic triangle waveform
r1 long 0
r2 long 0
sample long 15
dutyCtr long 0
dutyLen long 32
sampleCtr long 0
dummy long 0
DACpin long %00000000100000000000000000000000
fit 496
Now, it loops just fine as long as i put a value between 1 and 3 where i marked it in red, so it has to do with:
mov r1,#sampleSet
add r1,sampleCtr 'load sample
mov sample,r1
But why can't i read more than three longs from sampleSet?
I'm probably missing something obvious, but i have read the manual a couple of times today, and i can't still find out what i'm doing wrong...
In hope for a helpful answer,
Micke
Comments
DAT org 0 entry mov dira,DACpin ' OK mov r2,#1 ' remove -> I think r2 is only used to set/clear the pin / ther's a better way to do that mov sampleCtr,#0 ' remove -> sampleCtr is already zero when starting, afterwards it's cleared in the loop :LoopWaveform mov dutyCtr, #0 shl r2,#23 ' remove mov outa, r2 'put one on pin 23 ' remove or outa, DACpin ' add -> this will set the bit mov r1,#sampleSet add r1,sampleCtr 'load sample mov sample,r1 ' replace -> this code is wrong. My guess is that you want to access the sample data below ' To do that you have to use self modifying code. Currently the value of sample is ' the COG-RAM address of sampleSet plus actual value of sampleCtr but not its ' content. mov r1,#sampleSet ' use this instead -> add r1, sampleCtr ' this calculates the address movs samplRd, r1 ' and moves it to the source part of the mov sample,0-0 instruction nop ' this instruction is already in the pipeline, that's why self-modifying code never changes the ' next instruction samplRd mov sample, 0-0 ' 0-0 is replaced by the movs :PinHigh add dutyCtr, #1 add dummy,#1 ' I don't know what this is good for?! If it's for slowing down, use NOP instead sub dummy,#1 add dummy,#1 cmp dutyCtr, sample WZ 'loop high part of duty cycle if_NZ jmp #:PinHigh mov r2,#0 ' remove -> better way to clear bit shl r2,#23 mov outa, r2 ' put zero on pin 23 andn outa, DACpin ' add this instead add sampleCtr,#1 cmp sampleCtr,#32 WZ if_Z mov sampleCtr,#0 mov r2,#1 ' remove -> set/clear no longer needs r2 :PinLow add dutyCtr, #1 sub dummy,#1 add dummy,#1 sub dummy,#1 cmp dutyCtr, dutyLen WZ 'loop low part of duty cycle if_NZ jmp #:PinLow jmp #:LoopWaveform sampleSet long 1,2,3,4 long 5,6,7,8 long 9,10,11,12 long 13,14,15,16 long 15,14,13,12 long 11,10,9,8 long 7,6,5,4 long 3,2,1,0 'a basic triangle waveform r1 long 0 ' does not need a value, so move to the end of this DAT and use RES instead. This safes HUB-RAM. r2 long 0 ' remove sample long 15 dutyCtr long 0 ' does not need a value, move as RES to the end dutyLen long 32 sampleCtr long 0 ' does not need ..... ;o) dummy long 0 ' does no..... DACpin long %00000000100000000000000000000000 fit 496
I am reading it now, just had to let you know right away how thankful i am for your help!
Much to my girlfriends regret, i'm going to look it through thoroughly until i understand it all!
Thanks again!
Most of the things I wrote are not a real problem, but give you cleaner code. The main point is that the propeller does not have indirect addressing like other mikrocontrollers. R1 and R2 let me think that you used AVRs before?! So you have to get used to self modifying code (even call and ret are self-modifying because the prop does not have a stack). There is a good description of PASM specialities - as far as I remember from Oldbitcollector? - which is a must-read. Is it mentioned in the sticky? ....
Here we go;
nop... you'd guess that for a guy like me who started out with assembler on a Commodore would know about No OPeration... ;( I'm embarrased...
or/and... It's about time i learn the truth tables of the various xor's and and's. I tend to avoid using them because i can't bother with the extra brain effort. I will never do this kind of programming again! (Note to self, stop cutting corners!)
RES... I don't know why i keep doing all this double initialization of the variables... It's like i don't trust that the value really is what i want it to be, so i have to do it twice. I'll stop that immediately!
I'll do my homework, and repost the correct code!
I could put color tags around text inside code tags, but the button for it only shows up in advanced reply...
mov [COLOR="red"]red[/COLOR], [COLOR="green"]green[/COLOR]
I'm not sure which text you are referring to. I have read the manual, deSilva's tutorial and Propeller trix and traps, but they are all very brief on every topic...
But i'll learn as i go along!
http://forums.parallax.com/showthread.php?96594-Machine-Language-Tutorial!
This is what it looks like now:
DAT org 0 entry mov dira,DACpin mov dutyCtr,#0 mov sampleCtr,#0 mov waveLen,#32 LoopWave or outa, DACpin 'put one on pin 23 mov r1,#sampleSet add r1,sampleCtr 'load sample movs samplRd, r1 ' and moves it to the source part of the mov sample,0-0 instruction nop samplRd mov sample,0-0 PinHigh add dutyCtr, #1 cmp dutyCtr, sample WZ 'loop high part of duty cycle if_NZ jmp #PinHigh andn outa,DACpin ' put zero on pin 23 add sampleCtr,#1 cmp sampleCtr,#32 WZ 'shift into next sample if_Z mov sampleCtr,#0 PinLow add dutyCtr, #1 cmp dutyCtr, waveLen WZ 'loop low part of duty cycle if_NZ jmp #PinLow jmp #LoopWave sampleSet long 1,2,3,4 long 5,6,7,8 long 9,10,11,12 long 13,14,15,16 long 15,14,13,12 long 11,10,9,8 long 7,6,5,4 long 3,2,1,0 'a basic triangle waveform DACpin long %00000000100000000000000000000000 r1 res 1 sample res 1 sampleCtr res 1 dutyCtr res 1 waveLen res 1 fit 496
It sounds like two pops, meaning it halts after one time through the program, without looping.
By the way, all of a sudden the compiler complains about:
jmp #:LoopWaveform
saying that it's an "Undefined symbol". I'm quite sure it is not, since it worked perfectly fine an hour ago...How looks Yours Propeller platform ---> Maybe it is hardware problems
There is another global label (a label without : at begin) between the point where :LoopWaveform is defined and the point where the jmp #:loopWaveform is written. So these are not the same local labels. The first can be seen as entry:loopWaveform and at the jump the label will be samplRd:loopWaveform.
Andy
I didn't realize the colon( : ) made it somehow special, i thought it was merely a choice of preference. In what way do these labels differ?
You moved the mov dutyCounter,#0 outside of the loop ... that was a bad idea
With you current code 0 will still give you a peak and waveLen will still give you a gap. (BTW waveLen is not the right name for this variable, right?)
If you change the pinHigh and pinLow as follows, you can have 0 without peak and waveLen without gap:
PinHigh cmp dutyCtr, sample WZ 'loop high part of duty cycle if_NZ add dutyCtr, #1 if_NZ or outa, DACpin 'put one on pin 23 if_NZ jmp #PinHigh
PinLow cmp dutyCtr, waveLen WZ 'loop low part of duty cycle if_NZ add dutyCtr, #1 if_NZ andn outa,DACpin ' put zero on pin 23 if_NZ jmp #PinLow
My excuse is that it was done quite late in the evening here in Sweden... Not really an excuse... Also i only had the one cup of coffea... No excuse either? Ok... Well then i'm all outta excuses...
Changing that into pulseLen, or maybe cycleLen?
More questions:
I have 32 samples, and in my loop i try to read 33, which isn't what i intended, so i changed it into #31. Fine, now it works. But why doesen't it work when i read 32 samples? I mean, shouldn't it just play one possibly weird sample, and then start over from the top of sampleSet?
You've officially become my mentor. I'll follow your advice to the point, blindly and promptly! I will change the code immediately!
Yet again, big thanks!
Here is my version:
con _CLKMODE = RCFAST '_clkmode = xtal1 + pll8x '_xinfreq = 10_000_000 PUB Main cognew(@entry, 0) DAT org 0 entry mov dira,DACpin ' or dira,WAVEpin ' for scope trigger mov sampleCtr,#0 mov cycleLen,#32 mov sampleLen,#17 LoopWave mov dutyCtr,#0 mov r1,#sampleSet add r1,sampleCtr 'load sample movs samplRd, r1 ' and moves it to the source part of the mov sample,0-0 instruction nop samplRd mov sample,0-0 PinHigh cmp dutyCtr, sample WZ 'loop high part of duty cycle if_NZ add dutyCtr, #1 if_NZ or outa, DACpin 'put one on pin 23 if_NZ jmp #PinHigh add sampleCtr,#1 cmp sampleCtr,sampleLen WZ 'shift into next sample if_Z mov sampleCtr,#0 ' if_Z xor outa, WAVEpin ' this gives me a nice signal for the scope. ' shortly before the cycle is done the output ' is inverted PinLow cmp dutyCtr, cycleLen WZ 'loop low part of duty cycle if_NZ add dutyCtr, #1 if_NZ andn outa,DACpin ' put zero on pin 23 if_NZ jmp #PinLow jmp #LoopWave sampleSet long 0,16,16,16 long 16,16,16,16 long 16,16,16,16 long 16,16,16,32 long 16,16,16,16 long 16,16,16,16 long 16,16,16,16 long 16,16,16,32 long 16 DACpin long %00000000_00000000_00000100_00000000 'WAVEpin long %00000000_00000000_00001000_00000000 ' output for scope r1 res 1 sample res 1 sampleCtr res 1 sampleLen res 1 cycleLen res 1 dutyCtr res 1 waveLen res 1 fit 496
I only added another output (commented out currently) to measure the output with a scope.
I changed it into your suggestion... Now it all works! Big big thanks!