Shop OBEX P1 Docs P2 Docs Learn Events
Translate SPIN to PASM (Using phsa) — Parallax Forums

Translate SPIN to PASM (Using phsa)

jmspaggijmspaggi Posts: 629
edited 2011-04-29 14:35 in Propeller 1
Hi there,

I'm trying to translate that:
PUB PulseTheStepPin(StepPin, TotalSteps) | RampingSteps, RunningSteps, Counter, CycleOffset

  if TotalSteps > RAMPING_RANGE
    RampingSteps := SPEED_RANGE
    RunningSteps := TotalSteps - RAMPING_RANGE
  else
    RampingSteps := TotalSteps / 2
    RunningSteps := TotalSteps // 2    
  
  CycleOffset := MIN_SPEED

  ctra[30..26] := %00100 ' Configure Counter A to NCO
  ctra[5..0] := StepPin
  frqa := 1
  dira[StepPin]~~

  Counter := cnt
  
  repeat RampingSteps
    phsa := -HIGH_PULSE_WIDTH
    waitcnt(Counter += CycleOffset--)
    StepCount++

  repeat RunningSteps 
    phsa := -HIGH_PULSE_WIDTH
    waitcnt(Counter += CycleOffset)
    StepCount++

  repeat RampingSteps
    phsa := -HIGH_PULSE_WIDTH
    waitcnt(Counter += CycleOffset++)
    StepCount++

Into PASM.

So I tried to translate one loop and applied that to all.

So far, here is what I did:
CON
  ....  
  HIGH_PULSE_WIDTH = CLK_FREQ / 500_000 'This is the setting for the minimal step pulse width.
  MIN_SPEED = 7_000 'Adjust this setting to overcome any moments of inertia you may have in your mechanical system.
  MAX_SPEED = 11_000 'Settings above 11,000 will result in step count inaccuracies for a 2000 uStep drive and settings
  'above 12,000 will cause the G251 to falter.
  
  'Do not alter
  SPEED_RANGE = MAX_SPEED - MIN_SPEED
  RAMPING_RANGE = SPEED_RANGE * 2

PUB PulseTheStepPinWithCog(StepPin, TotalSteps) | RampingSteps, RunningSteps, Counter, CycleOffset

  if TotalSteps > RAMPING_RANGE
    RampingSteps := SPEED_RANGE
    RunningSteps := TotalSteps - RAMPING_RANGE
  else
    RampingSteps := TotalSteps / 2
    RunningSteps := TotalSteps // 2    
  
  CycleOffset := MIN_SPEED

  ctra[30..26] := %00100 ' Configure Counter A to NCO
  ctra[5..0] := StepPin
  frqa := 1
  dira[StepPin]~~

  Counter := cnt
  LONG[_RampingSteps] := RampingSteps
  LONG[_RunningSteps] := RunningSteps
  LONG[_CycleOffset]  := CycleOffset
  LONG[_Counter]      := Counter

  COGNEW(@cogstart, @cogstart)
  

DAT
                        ORG     0
cogstart                
                        MOV     _index, _RampingSteps
loop1                   MOV     phsa, _HIGH_PULSE_WIDTH
                        WAITCNT _Counter, _CycleOffset      
                        SUB    _CycleOffset, #1
                        SUB    _Index, #1
                        TJNZ   _Index, loop1

                        MOV     _index, _RunningSteps
loop2                   MOV     phsa, _HIGH_PULSE_WIDTH
                        WAITCNT _Counter, _CycleOffset
                        SUB    _Index, #1
                        TJNZ   _Index, loop2

                        MOV     _index, _RampingSteps
loop3                   MOV     phsa, _HIGH_PULSE_WIDTH
                        WAITCNT _Counter, _CycleOffset      
                        ADD    _CycleOffset, #1
                        SUB    _Index, #1
                        TJNZ   _Index, loop3
end                     JMP end                            


_index                  LONG    $00000000                             
_RampingSteps           LONG    $00000000 
_RunningSteps           LONG    $00000000  
_CycleOffset            LONG    $00000000
_Counter                LONG    $00000000
_HIGH_PULSE_WIDTH       LONG    $FFFFFFF6

But of course, it's not working.

Everything is pretty simple, but I'm still not able to find the issue :( I'm suspecting some issues on the MOV with the address being assigned instead of the values, or the opposite.

So all the suggestions are welcome. I would like to understand what I'm doing wrong.

Thanks,

JM

Comments

  • homosapienhomosapien Posts: 147
    edited 2011-01-20 13:28
    When doing a jmp in PASM you need a # sign in front of the label, as you want to jump to where the label is, not jump to the address contained in the long AT the label (well, at least in all the jumps you have in this code).

    Example:

    end jmp #end

    will create an endless loop.

    Some advice that I hope you will not take in the wrong way: Start REALLY simple and small. You will be glad you did.

    -h
  • jmspaggijmspaggi Posts: 629
    edited 2011-01-20 13:31
    thanks for the #.

    I changed the 4 jumps I have.

    I have also added some checkpoints. OUT1 to OUT3 are connected to LEDs so I know when the application reach a certain point.

    So far, look like the WAITCNT is waiting way longer than what it's supposed. So I will try to dig there.

    JM
    PUB PulseTheStepPinWithCog(StepPin, TotalSteps) | RampingSteps, RunningSteps, Counter, CycleOffset
    
      if TotalSteps > RAMPING_RANGE
        RampingSteps := SPEED_RANGE
        RunningSteps := TotalSteps - RAMPING_RANGE
      else
        RampingSteps := TotalSteps / 2
        RunningSteps := TotalSteps // 2    
      
      CycleOffset := MIN_SPEED
    
      ctra[30..26] := %00100 ' Configure Counter A to NCO
      ctra[5..0] := StepPin
      frqa := 1
      dira[StepPin]~~
    
      Counter := cnt
    
      
      _RampingSteps := RampingSteps
      _RunningSteps := RunningSteps
      _CycleOffset  := CycleOffset
      _HIGH_PULSE_WIDTH := -HIGH_PULSE_WIDTH
    
      COGNEW(@cogstart, @table)
      
    
    DAT
                            ORG     0
    cogstart
    
    {{
      repeat RampingSteps
        phsa := -HIGH_PULSE_WIDTH
        waitcnt(Counter += CycleOffset--)
        StepCount++
    
    }}
                            MOV     dira, #%0000_0000_0000_1111
                            MOV     _index, _RampingSteps
                            MOV     outa, #%0000_0000_0000_1000
                            MOV     _Counter, CNT                                       
    loop1                   MOV     phsa, _HIGH_PULSE_WIDTH
                            ADD     _Counter, _CycleOffset
                            WAITCNT _Counter, #0      
                            SUB    _CycleOffset, #1
                            SUB    _Index, #1
                            TJNZ   _Index, #loop1
                            MOV     outa, #%0000_0000_0000_0100                                       
    
                            MOV     _index, _RunningSteps
    loop2                   MOV     phsa, _HIGH_PULSE_WIDTH
                            WAITCNT _Counter, _CycleOffset
                            SUB    _Index, #1
                            TJNZ   _Index, #loop2
                            MOV     outa, #%0000_0000_0000_0010                                       
    
    
                            MOV     _index, _RampingSteps
    loop3                   MOV     phsa, _HIGH_PULSE_WIDTH
                            WAITCNT _Counter, _CycleOffset      
                            ADD    _CycleOffset, #1
                            SUB    _Index, #1
                            TJNZ   _Index, #loop3
    end                     JMP end                            
    
    
    _index                  LONG    $00000000                             
    _RampingSteps           LONG    $00000000 
    _RunningSteps           LONG    $00000000  
    _CycleOffset            LONG    $00000000
    _Counter                LONG    $00000000
    _HIGH_PULSE_WIDTH       LONG    $FFFFFFF6
    
  • homosapienhomosapien Posts: 147
    edited 2011-01-20 13:47
    JM,

    You are starting a process in another COG - you need to get the data you need from the first COG (running SPIN) to the second COG (running PASM).

    I would try some exercises using just one process self-contained in one COG to get familiar with PASM before trying moving to a process like this. The Propeller Education Kit Labs have some really great examples to learn from.

    -h
  • jmspaggijmspaggi Posts: 629
    edited 2011-01-20 13:52
    Is not the DAT section shared between all the cogs? That's why I moved the data there (_RampingSteps, _RunningSteps, etc.) in order to access them from the COG.

    Do you have any link for the kit labs? I already did some few PASM methods, like to play OGG files, but look like I forgot too many things in the meantime ;)

    JM
  • jmspaggijmspaggi Posts: 629
    edited 2011-01-20 14:09
    Here is a VERY simplified version ;)

    I moved everything in the DAT section with the right values instead of calculating them at the runtime. I removed all the spin code, but I don't know how to remove the remaining one. Now there is no need to transfert data between the 2 methods.

    But it's still not working :(

    JM
    CON
      _CLKMODE = XTAL1 + PLL16X
      _XINFREQ = 5_000_000  
      CLK_FREQ = ((_CLKMODE - XTAL1) >> 6) * _XINFREQ  
    
    PUB Main
      cognew (@cogstart, 0)
      
    DAT
                            ORG     0
    cogstart
    
    
                            OR     dira, #%0000_0000_0000_1111
                            OR     outa, #%0000_0000_0000_1000
                            MOV    frqa, 1
                            MOV    ctra, CtrCfg 
                            
                            MOV     _index, _RampingSteps
                            MOV     _Counter, CNT
                            ADD     _Counter, _CycleOffset
                            SUB    _CycleOffset, #1                                  
    loop1                   MOV     phsa, _HIGH_PULSE_WIDTH                        
                            WAITCNT _Counter, 0
                            ADD     _Counter, #500    
                            SUB    _CycleOffset, #1
                            SUB    _Index, #1
                            TJNZ   _Index, #loop1
    
                            OR     outa, #%0000_0000_0000_0100                                       
    
                            MOV     _index, _RunningSteps
    loop2                   MOV     phsa, _HIGH_PULSE_WIDTH
                            WAITCNT _Counter, _CycleOffset
                            SUB    _Index, #1
                            TJNZ   _Index, #loop2
    
                            OR     outa, #%0000_0000_0000_0010                                       
    
    
                            MOV     _index, _RampingSteps
    loop3                   MOV     phsa, _HIGH_PULSE_WIDTH
                            WAITCNT _Counter, _CycleOffset      
                            ADD    _CycleOffset, #1
                            SUB    _Index, #1
                            TJNZ   _Index, #loop3
    end                     JMP end                            
    
    
    _index                  LONG    $00000000                             
    _Counter                LONG    $00000000
    _RampingSteps           LONG    $00001B58 
    _RunningSteps           LONG    $00014FF0  
    _CycleOffset            LONG    3000
    _HIGH_PULSE_WIDTH       LONG    $FFFFFF60
    CtrCfg                  LONG    %0001_0000_0000_0000_0000_0000_0000_0001
    
  • homosapienhomosapien Posts: 147
    edited 2011-01-20 14:31
    I think you are getting closer to a method of learning PASM with less frustration (ie simpler with only really one COG; you will always need the SPIN cognew command...). I would continue in this vein by stripping the program down more to just setting the outputs and using the WAITCNT to flash the LED.

    The PEKL links are in the sticky at the top of the Prop forum, though I just looked at them again, and most examples are in SPIN :(

    But, if memory serves, there is a discussion of waitcnt and how you can get unexpected results if you do not 'load' it correctly.....

    Also, it appears that you have a lot of constants defined, but no variables..... see RES in the Prop manual.

    Sorry, got to run, dinner is on the table......
  • jmspaggijmspaggi Posts: 629
    edited 2011-01-20 14:45
    Yep, I'm aware of some of the WAITCNT challenges, like when you ask to wait for a value which just passed, you will have to wait for an entire cycle.

    This code is making the leds blinking perfectly:
                            MOV     _index, _RampingSteps
                            MOV     _Counter, CNT
                            ADD     _Counter, _CycleOffset
    loop0                   WAITCNT _Counter, _CycleOffset 
                            SUB    _Index, #1
                            XOR     outa, #%0000_0000_0000_1100                                       
                            TJNZ   _Index, #loop0                        
                            
    

    I had to adjust the speed. I will see if it can have an impact on the other loops.
  • idbruceidbruce Posts: 6,197
    edited 2011-04-29 14:35
    @jmspaggi

    Have you had any luck with the conversion?

    Bruce
Sign In or Register to comment.