Shop OBEX P1 Docs P2 Docs Learn Events
Spin > Assembly translation needed — Parallax Forums

Spin > Assembly translation needed

T ChapT Chap Posts: 4,223
edited 2009-08-16 05:15 in Propeller 1
I am looking for someone to convert this to assembly. Spin isn't as fast as the need and there is no time to learn Pasm at the moment. I will advance a reasonable fee through western union tomorrow if someone can do this for me. The block to convert is Pub Motorr, I included a few other snippets to show the basics. I need to be able to modify external of the cog (3 cogs are running the pub motorr, x, y, z) the accel, decel, arate, drate value, so these will need to have parameters added to the list. They may need to be update-able while running, so the loop will needs to accommodate. I made a note in the loop.

If interested and can do this sooner than later, please PM me.


Thanks!





    long width
    long Pulsewidth
    long Disable
    LONG X, Xcurrent, EnaX        ' same as newpos, pos
    LONG Y, Ycurrent, EnaY
    LONG Z, Zcurrent, EnaZ
    Long R
    Long Xdone, Ydone, Zdone
    Long GotMessage






Pub start
 cognew(moveX, @stack1)     
 cognew(moveY, @stack2) 
 cognew(moveZ, @stack3)       
  







PUB motorr(pinstart, radr, forward, reverse, ID) | mstep, mdir, pos, for, rvrs, accel, decel, arate, drate, run
 x := 0
 y := 0
 z := 0

 xcurrent := 0
 ycurrent := 0
 zcurrent := 0
 Long[noparse][[/noparse]ID] := 1
 width := -1500

  Mstep := pinstart
  Mdir := pinstart + 1
  For :=  Reverse     'these switched to avoid changes elsewhere up the line.  
  Rvrs := Forward



  dira[noparse][[/noparse]MStep] := 1  
  outa[noparse][[/noparse]MStep] := 0
  dira[noparse][[/noparse]MDir] := 1
  outa[noparse][[/noparse]MDir] := for

  
  FRQA := 0
  CTRA := %00100 << 26 + Mstep 
  repeat
    accel := 90000    'getting updated in the loop
    aRate := 200       'getting updated in the loop
    decel := 10000     'getting updated in the loop
    dRate := 20          'getting updated in the loop
    frqa := 0 



    if LONG[noparse][[/noparse]radr] > LONG[noparse][[/noparse]radr + 4]       
      accel := newParameter1
      dedel : = newParameter2
      arate := newParameter3
      drate := newParameter4
      
      Long[noparse][[/noparse]ID] := 0     'set Xdone, Ydone, Zdone as 0, still moving
      frqa := 1
      run :=  LONG[noparse][[/noparse]radr] - LONG[noparse][[/noparse]radr + 4]
      outa[noparse][[/noparse]MDir] := For  
      repeat  run
        run :=  LONG[noparse][[/noparse]radr] - LONG[noparse][[/noparse]radr + 4]
        PHSA := width  
        if   accel => 400              
           waitcnt(accel + cnt)                 
        LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  + 1               
        accel   := (accel - aRate)  #> 400   'min 400
        If LONG[noparse][[/noparse]radr] < LONG[noparse][[/noparse]radr + 4]              'interrupt and decel  if new position in opposite dir 
            repeat  1000                  'Decel 10% of pos
              PHSA := width
              if decel => 400         
                waitcnt(Decel + cnt)       
              LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  + 1
              Decel := Decel + dRate    
            quit
        If LONG[noparse][[/noparse]radr] - LONG[noparse][[/noparse]radr + 4] == 1000             'DECEL 1000    Decel 10%  approx of move
            repeat  LONG[noparse][[/noparse]radr] - LONG[noparse][[/noparse]radr + 4]                 
              PHSA := width
              if decel => 400          
                waitcnt(decel + cnt)       
              LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  + 1
              Decel := Decel + dRate
            quit
      Long[noparse][[/noparse]ID] := 1     ''move done if 1


    'REVERSE========================================

    accel := newParameter1
    dedel : = newParameter2
    arate := newParameter3
    drate := newParameter4
    frqa := 1
    if LONG[noparse][[/noparse]radr] < LONG[noparse][[/noparse]radr + 4]
      Long[noparse][[/noparse]ID] := 0    'set Xdone as 0, not complete, still moving
      run :=  LONG[noparse][[/noparse]radr + 4] - LONG[noparse][[/noparse]radr]                              
      outa[noparse][[/noparse]MDir] := Rvrs   
      repeat  run
        run :=  LONG[noparse][[/noparse]radr + 4] - LONG[noparse][[/noparse]radr]
        PHSA := width
        if   accel => 400                   
          waitcnt(accel + cnt)                   
        LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  - 1               
        accel   := accel - aRate  #> 400
        If LONG[noparse][[/noparse]radr] > LONG[noparse][[/noparse]radr + 4]          'interrupt and decel if new position in opposite dir rec'd
            repeat 1000
              PHSA := width
              if decel => 400                         
                waitcnt(decel + cnt)                       
              LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  - 1
              Decel := Decel + dRate             
            quit  
        If LONG[noparse][[/noparse]radr + 4] - LONG[noparse][[/noparse]radr]  == 1000        'decel last 1000 pulses of move
            repeat LONG[noparse][[/noparse]radr + 4] - LONG[noparse][[/noparse]radr]                     
              PHSA := width
              if decel => 400                      
                 waitcnt(decel + cnt)                       
              LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  - 1
              Decel := Decel + dRate

            quit

      Long[noparse][[/noparse]ID] := 1     ''move done if 1        feedback for gui   




Post Edited (TChapman) : 8/14/2009 3:49:17 AM GMT

Comments

  • T ChapT Chap Posts: 4,223
    edited 2009-08-16 05:15
    Some gracious gent sent over a pretty close rendition to my Spin code that needs better speed. I learned a bit tweaking a few minor things to get it almost there, but am stuck on a few last issues.

    To create acceleration on a stepper, the motor starts out at a rate decided by waitcnt(accel+ cnt). Accel is predefined before the move. On each iteration, Accel should get reduced by aRate, or accel rate. So that the time gets shorter each iteration, the steps to the stepper get closer together, faster RPM. In spin the code works great. In the ASM rendition, the Accel does not change, the speed stays set by Accel. If someone could take a look and see if there is an obvious reason why Accel is not being reduced by aRate that would be great. This code is in the same file as the caller. The decel is working as it should.

    Thanks for any suggestions.

    There are 3 calls moveX, moveY and moveZ which look like:
    PUB  moveX
         motorr(0, @X, 1, 0, @Xdone)  'was 2 on mps,  Step, record address, direction forward(=1), direction reverse(=1)
    
    PUB  moveY     
         motorr(2, @Y, 0, 1, @Ydone)    'was 0 on mps
    
    PUB  moveZ
         motorr(4, @Z, 1, 0, @Zdone)   
    
    





    PUB motorr( ipinstart, iradr, iforward, ireverse, iID )
      x := 0
      y := 0
      z := 0
    
      xcurrent := 0
      ycurrent := 0
      zcurrent := 0
      width := -1500
    
      pwidth := @width
      pinstart := ipinstart
      radr := iradr
      forward := iforward
      reverse := ireverse
      ID := iID
      return COGNEW( @cogstart, @cogstart )
    DAT
                    ORG     0
    cogstart
                    JMP     #cogstart0
    pinstart        LONG    0               ' input parameters
    radr            LONG    0
    forward         LONG    0
    reverse         LONG    0
    ID              LONG    0
    cogstart0
    
    
                    'setup Forward move
                    WRLONG  Cone, ID                ' LONG[noparse][[/noparse]ID] := 1
                    MOV     mstep, pinstart         ' mstep := pinstart
                    MOV     mdir, pinstart          ' mdir := pinstart + 1
                    ADD     mdir, #1
                    MOV     for, reverse    WZ      ' for := reverse
                    MOV     rvrs, forward           ' rvrs := forward
                    MOV     ctmp1, #1               ' DIRA[noparse][[/noparse]mstep] := 1
                    SHL     ctmp1, mstep
                    OR      DIRA, ctmp1
                    ANDN    OUTA, ctmp1             ' OUTA[noparse][[/noparse]mstep] := 0
                    MOV     ctmp1, #1               ' DIRA[noparse][[/noparse]mdir] := 1
                    SHL     ctmp1, mdir
                    OR      DIRA, ctmp1
            IF_Z    ANDN    OUTA, ctmp1             ' OUTA[noparse][[/noparse]mdir] := for
            IF_NZ   OR      OUTA, ctmp1
                    MOV     FRQA, #0                ' FRQA := 0
                    MOV     CTRA, C8SHL26           ' CTRA := %00100 << 26 + mstep
                    ADD     CTRA, mstep
    repeat1                                         ' repeat
    
    
                    'in future, these 4 must update from main method via USB accel, arate, decel, drate
                    MOV     accel, Caccel           'reset accel
                    MOV     arate, Carate           'reset accel rate
                    MOV     decel, Cdecel           'reset decel
                    MOV     drate, Cdrate           'reset decel rate
    
                    MOV     FRQA, #0                ' FRQA := 0
    
                    '************************************
                    RDLONG  ctmp1, radr             '001    if LONG[noparse][[/noparse]radr] > LONG[noparse][[/noparse]radr+4]
                    MOV     ctmp2, radr             '002
                    ADD     ctmp2, #4               '003
                    RDLONG  ctmp2, ctmp2            '004
                    CMPS    ctmp2, ctmp1    WC      '005
            IF_NC   JMP     #endif1                 '006
                    WRLONG  CZero, ID               '007    LONG[noparse][[/noparse]ID] := 0
                    MOV     FRQA, #1                '008    FRQA := 1
    
    
                    RDLONG  run, radr               'ODD   run :=  LONG[noparse][[/noparse]radr] - LONG[noparse][[/noparse]radr + 4]
    
                    MOV     ctmp1, radr             '009
                    ADD     ctmp1, #4               '010
                    RDLONG  ctmp1, ctmp1            '011
                    SUB     run, ctmp1              '012
                    MOV     ctmp1, #1               '013   OUTA[noparse][[/noparse]mdir] := for
                    SHL     ctmp1, mdir             '014
                    MOV     for, for        WZ      '015
            IF_Z    ANDN    OUTA, ctmp1             '016
            IF_NZ   OR      OUTA, ctmp1             '017
                    MOV     rep2cnt, run            '018   repeat run
    repeat2
    
                    'START FORWARD motion  here if new position > current position
    
                    RDLONG  run, radr               'ODD   run :=  LONG[noparse][[/noparse]radr] - LONG[noparse][[/noparse]radr + 4]
                    MOV     ctmp1, radr             '019
                    ADD     ctmp1, #4               '020
                    RDLONG  ctmp1, ctmp1            '021
                    SUB     run, ctmp1              '022
                    RDLONG  PHSA, pwidth            '023   PHSA := width
                    CMPS    accel, #400     WC      '024   if accel => 400
                    MOV     ctmp1, accel            '025   waitcnt(accel + cnt)
                    ADD     ctmp1, CNT              '026
            IF_NC   WAITCNT ctmp1, #0               '027
                    MOV     ctmp1, radr             '028   LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  + 1
                    ADD     ctmp1, #4               '029
                    RDLONG  ctmp2, ctmp1            '030
                    ADD     ctmp2, #1               '031
                    WRLONG  ctmp2, ctmp1            '032
                    MOV     ctmp1, accel            '033   accel := (accel - aRate)  #> 400
                    SUBS    ctmp1, arate            '034
                    CMPS    ctmp1, #400     WC      '035
            IF_C    MOV     accel, #400             '036
            IF_NC   MOV     accel, ctmp1            '037
                    RDLONG  ctmp1, radr             '038   if  LONG[noparse][[/noparse]radr] < LONG[noparse][[/noparse]radr + 4]
                    MOV     ctmp2, radr             '039
                    ADD     ctmp2, #4               '040
                    RDLONG  ctmp2, ctmp2            '041
                    CMPS    ctmp1, ctmp2    WC      '042
            IF_NC   JMP     #endif2                 '043
                    MOV     rep3cnt, C1000          '044   repeat  1000
    repeat3
                    RDLONG  PHSA, pwidth            '045   PHSA := width
                    CMPS    decel, #400     WC      '046   if decel => 400
                    MOV     ctmp1, decel            '047   waitcnt(Decel + cnt)
                    ADD     ctmp1, CNT              '048
            IF_NC   WAITCNT ctmp1, #0               '049
                    MOV     ctmp1, radr             '050   LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  + 1
                    ADD     ctmp1, #4               '051
                    RDLONG  ctmp2, ctmp1            '052
                    ADD     ctmp2, #1               'ODD
                    WRLONG  ctmp2, ctmp1            '054
                    ADD     decel, drate            '055   Decel := Decel + dRate
                    DJNZ    rep3cnt, #repeat3       '056
                    JMP     #endrep2                '057   quit
    endif2
                    RDLONG  ctmp1, radr             '058   If LONG[noparse][[/noparse]radr] - LONG[noparse][[/noparse]radr + 4] == 1000
                    MOV     ctmp2, radr             '059
                    ADD     ctmp2, #4               '060
                    RDLONG  ctmp2, ctmp2            '061
                    SUBS    ctmp1, ctmp2            '062
                    CMPS    ctmp1, C1000    WZ      '063
            IF_NZ   JMP     #endif3                 '064
                    MOV     rep4cnt, ctmp1          '065  repeat  LONG[noparse][[/noparse]radr] - LONG[noparse][[/noparse]radr + 4]
    repeat4
                    RDLONG  PHSA, pwidth            '066  PHSA := width
                    CMPS    decel, #400     WC      '067  if decel => 400
                    MOV     ctmp1, decel            '068  waitcnt(decel + cnt)
                    ADD     ctmp1, CNT              '069
            IF_NC   WAITCNT ctmp1, #0               '070
                    MOV     ctmp1, radr             '071  LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  + 1
                    ADD     ctmp1, #4               '072
                    RDLONG  ctmp2, ctmp1            '073
                    ADD     ctmp2, #1               '074
                    WRLONG  ctmp2, ctmp1            '075
                    ADD     decel, drate            '076  Decel := Decel + dRate
                    DJNZ    rep4cnt, #repeat4       '077
    endrep4
                    JMP     #endrep2                '078  quit
    endif3
                    'DJNZ    rep2cnt, #repeat2       '079  ODD    doesn't run  with this line in
    endrep2
                    WRLONG  Cone, ID                '080 Long[noparse][[/noparse]ID] := 1
    endif1
    
    '////////////////////////////REVERSE LOOP''/////////////////////////////////////////
    
    
                    'set up Reverse Move here
                    MOV     accel, Caccel           'reset accel
                    MOV     arate, Carate           'reset accel rate
                    MOV     decel, Cdecel           'reset decel
                    MOV     drate, Cdrate           'reset decel rate
    
                    '************************************
                    'if the new position is < position current, go REVERSE
                    RDLONG  ctmp1, radr             '001   if LONG[noparse][[/noparse]radr] < LONG[noparse][[/noparse]radr + 4]
                    MOV     ctmp2, radr             '002
                    ADD     ctmp2, #4               '003
                    RDLONG  ctmp2, ctmp2            '004
                    CMPS    ctmp1, ctmp2    WC      '005
            IF_NC   JMP     #endif4                 '006
                    WRLONG  CZero, ID               '007   Long[noparse][[/noparse]ID] := 0
                    MOV     FRQA, #1                '008
    
    
                    MOV     ctmp1, radr             '009   run :=  LONG[noparse][[/noparse]radr + 4] - LONG[noparse][[/noparse]radr]
                    ADD     ctmp1, #4               '010
                    RDLONG  run, ctmp1              '011
                    RDLONG  ctmp1, radr             'ODD
                    SUBS    run, ctmp1              '012
                    MOV     ctmp1, #1               '013   outa[noparse][[/noparse]MDir] := Rvrs
                    SHL     ctmp1, mdir             '014
                    MOV     rvrs, rvrs      WZ      '015
            IF_Z    ANDN    OUTA, ctmp1             '016
            IF_NZ   OR      OUTA, ctmp1             '017
                    MOV     rep5cnt, run            '018   repeat run
    repeat5
    
                    ''START REVERSE motion  here if new position < current position
                    MOV     ctmp1, radr             '019   run :=  LONG[noparse][[/noparse]radr + 4] - LONG[noparse][[/noparse]radr]
                    ADD     ctmp1, #4               '020
                    RDLONG  run, ctmp1              '021
                    RDLONG  ctmp1, radr             'ODD
                    SUBS    run, ctmp1              '022
                    RDLONG  PHSA, pwidth            '023   PHSA := width
                    CMPS    accel, #400     WC      '024   if accel => 400
                    MOV     ctmp1, accel            '025   waitcnt(accel + cnt)
                    ADD     ctmp1, CNT              '026
            IF_NC   WAITCNT ctmp1, #0               '027
                    MOV     ctmp1, radr             '028   LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  - 1
                    ADD     ctmp1, #4               '029
                    RDLONG  ctmp2, ctmp1            '030
                    SUBS    ctmp2, #1               '031
                    WRLONG  ctmp2, ctmp1            '032
                    MOV     ctmp1, accel            '033   accel := (accel - aRate)  #> 400
                    SUBS    ctmp1, arate            '034
                    CMPS    ctmp1, #400     WC      '035
            IF_C    MOV     accel, #400             '036
            IF_NC   MOV     accel, ctmp1            '037
                    RDLONG  ctmp1, radr             '038   If LONG[noparse][[/noparse]radr] > LONG[noparse][[/noparse]radr + 4]
                    MOV     ctmp2, radr             '039
                    ADD     ctmp2, #4               '040
                    RDLONG  ctmp2, ctmp2            '041
                    CMPS    ctmp2, ctmp1    WC      '042
            IF_NC   JMP     #endif5                 '043
                    MOV     rep6cnt, C1000          '044   repeat 1000
    repeat6
                    RDLONG  PHSA, pwidth            '045   PHSA := width
                    CMPS    decel, #400     WC      '046   if decel => 400
                    MOV     ctmp1, decel            '047   waitcnt(decel + cnt)
                    ADD     ctmp1, CNT              '048
            IF_NC   WAITCNT ctmp1, #0               '049
                    MOV     ctmp1, radr             '050   LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  - 1
                    MOV     ctmp1, #4               'ODD
                    RDLONG  ctmp2, ctmp1            '052
                    SUBS    ctmp2, #1               '053
                    WRLONG  ctmp2, ctmp1            '054
                    ADD     decel, drate            '055   Decel := Decel + dRate
                    DJNZ    rep6cnt, #repeat6       '056
    endrep6
                    JMP     #endrep5                '057   quit
    endif5
                    RDLONG  ctmp2, radr             '058   If LONG[noparse][[/noparse]radr + 4] - LONG[noparse][[/noparse]radr]  == 1000
                    MOV     ctmp1, radr             '059
                    ADD     ctmp1, #4               '060
                    RDLONG  ctmp1, ctmp1            '061
                    SUBS    ctmp1, ctmp2            '062
                    CMPS    ctmp1, C1000    WZ      '063
            IF_NZ   JMP     #endif6                 '064
                    MOV     rep7cnt, ctmp1          '065   repeat LONG[noparse][[/noparse]radr + 4] - LONG[noparse][[/noparse]radr]
    repeat7
                    RDLONG  PHSA, pwidth            '066   PHSA := width
                    CMPS    decel, #400     WC      '067   if decel => 400
                    MOV     ctmp1, decel            '068   waitcnt(decel + cnt)
                    ADD     ctmp1, CNT              '069
            IF_NC   WAITCNT ctmp1, #0               '070
                    MOV     ctmp1, radr             '071   LONG[noparse][[/noparse]radr + 4] := LONG[noparse][[/noparse]radr + 4]  - 1
                    ADD     ctmp1, #4               '072
                    RDLONG  ctmp2, ctmp1            '073
                    SUBS    ctmp2, #1               '074
                    WRLONG  ctmp2, ctmp1            '075
                    ADD     decel, drate            '076   Decel := Decel + dRate
                    DJNZ    rep7cnt, #repeat7       '077
    endrep7
                    JMP     #endrep5                '078   quit
    endif6
    endrep5
                    WRLONG  Cone, ID                '080   Long[noparse][[/noparse]ID] := 1
    endif4
                    JMP     #repeat1
    
    Czero           LONG    0               ' constants
    Cone            LONG    1
    C8SHL26         LONG    %00100 << 26
    
    
    Caccel          LONG    6000     'accel
    Carate          LONG    100
    Cdecel          LONG    10000     'decel
    Cdrate          LONG    100
    
    C1000           LONG    1000
    pwidth          LONG    0               ' global variable pointers
    mstep           RES     1               ' local variables
    mdir            RES     1
    pos             RES     1
    for             RES     1
    rvrs            RES     1
    accel           RES     1
    decel           RES     1
    arate           RES     1
    drate           RES     1
    run             RES     1
    ctmp1           RES     1               ' PASM variables
    ctmp2           RES     1
    rep2cnt         RES     1
    rep3cnt         RES     1
    rep4cnt         RES     1
    rep5cnt         RES     1
    rep6cnt         RES     1
    rep7cnt         RES     1         
    
    
Sign In or Register to comment.