Shop OBEX P1 Docs P2 Docs Learn Events
Accessing Cog memory... — Parallax Forums

Accessing Cog memory...

siljamickesiljamicke Posts: 66
edited 2011-01-08 08:54 in Propeller 1
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...)
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

  • MagIO2MagIO2 Posts: 2,243
    edited 2011-01-07 11:33
    Let's see ....
    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
    
  • siljamickesiljamicke Posts: 66
    edited 2011-01-07 11:51
    Wow, i'm overwhelmed by this response!
    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!
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-01-07 12:01
    I loved the old forum-software for the ability to highlight text (even in the code-block) with different colors. This would make the changes much more readable.

    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? ....
  • siljamickesiljamicke Posts: 66
    edited 2011-01-07 12:10
    Wow... I admire all you guys who put up with all us ignorant fools!

    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!
  • siljamickesiljamicke Posts: 66
    edited 2011-01-07 12:16
    MagIO2 wrote: »
    I loved the old forum-software for the ability to highlight text (even in the code-block) with different colors. This would make the changes much more readable.

    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!
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-01-07 12:16
    The must-read I meant is from DeSilva ... you can find it here:
    http://forums.parallax.com/showthread.php?96594-Machine-Language-Tutorial!
  • siljamickesiljamicke Posts: 66
    edited 2011-01-07 12:46
    Ok, so i revised the code to your notes, i think. It still doesn't work though. ;(

    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...
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-07 12:54
    Hi

    How looks Yours Propeller platform ---> Maybe it is hardware problems
  • Cluso99Cluso99 Posts: 18,069
    edited 2011-01-07 12:58
    Sorry I don't have time to examine your code. However, the jmp #:LoopWaveform problem is because the ":" function has become out of local range for the compiler. I don't quite understand where/why this happens, but if you remove the ":" local from the jmp and also the label it will work. Maybe its a bug in the compiler??? but I have learnt to live with it.
  • AribaAriba Posts: 2,690
    edited 2011-01-07 13:30
    Cluso99 wrote: »
    Sorry I don't have time to examine your code. However, the jmp #:LoopWaveform problem is because the ":" function has become out of local range for the compiler. I don't quite understand where/why this happens, but if you remove the ":" local from the jmp and also the label it will work. Maybe its a bug in the compiler??? but I have learnt to live with it.

    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
  • siljamickesiljamicke Posts: 66
    edited 2011-01-07 13:48
    Ah, that's why!
    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?
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-01-07 13:57
    Works for me ;o)

    You moved the mov dutyCounter,#0 outside of the loop ... that was a bad idea
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-01-07 14:12
    Let me suggest the following improvements:
    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                                                  
    
  • siljamickesiljamicke Posts: 66
    edited 2011-01-08 02:41
    MagIO2 wrote: »
    Works for me ;o)

    You moved the mov dutyCounter,#0 outside of the loop ... that was a bad idea

    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...
    MagIO2 wrote: »
    (BTW waveLen is not the right name for this variable, right?)
    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!
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-01-08 08:48
    I don't know what you mean?! My version reads exactly what it's supposed to read. And yes, it should start from the beginning when the sample is done ... and that's what it's doing.

    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.
  • siljamickesiljamicke Posts: 66
    edited 2011-01-08 08:54
    MagIO2 wrote: »
    Let me suggest the following improvements:
    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:

    I changed it into your suggestion... Now it all works! Big big thanks!
Sign In or Register to comment.