Shop OBEX P1 Docs P2 Docs Learn Events
ASM SUB help needed — Parallax Forums

ASM SUB help needed

T ChapT Chap Posts: 4,223
edited 2009-08-17 05:00 in Propeller 1
Could use some help understanding this. In the code below, if the commented out MOV is in, nothing happens. If it is commented out, the loop runs the motor at a fixed speed set by accel. I want the accel to decrease by aRate each time around to speed up the loop. I have tried lots of combinations, using tmp1, using accel, Caccel, Carate, and other ways to move the values over so it can be updated and used the next pass. I set the initial values 5500, 100 shown below.

Thanks for any tips.



repeat2       

                RDLONG  PHSA, pwidth        'set PHSA := width for pulse size
                MOV     ctmp1, accel            'set ctmp1 to accel
                ADD     ctmp1, CNT             'add cnt to accel value
                WAITCNT ctmp1, #0            'waitcnt for ctmp1  waitcnt(accel + CNT)
                MOV     ctmp1, accel            'set ctm1 to accel from previous accel val
                SUB    ctmp1, arate             'subtract arate from accel to shorten waitcnt next time 
                'MOV     accel, ctmp1           'copy result back to accel        <<<<<<<<<<<<<<<    won't run with this in
                JMP     #repeat2                  'loop



Caccel          LONG    5500     'accel
Carate          LONG    100

accel           RES     1
arate           RES     1





Post Edited (TChapman) : 8/16/2009 9:11:05 PM GMT

Comments

  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2009-08-16 21:01
    Oops - Where are you using Caccel and Carate? You've got them defined, but the code shown doesn't use them. - H

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • T ChapT Chap Posts: 4,223
    edited 2009-08-16 21:08
    Caccel and Carate are vars to load the initial values into the loop. Other parts chopped to keep things tidy in the forum.


    cogstart0
                    MOV     accel, Caccel           'reset accel
                    MOV     arate, Carate           'reset accel rate
                    MOV     decel, Cdecel           'reset decel
                    MOV     drate, Cdrate           'reset decel rate
                    MOV     FRQA, #1                '008    FRQA := 1
    
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-08-16 21:15
    It always helps to list the entire program. If we're forced to make assumptions, they can easily be the wrong ones.

    -Phil
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2009-08-16 21:20
    OK, extracting the essense, it seems like your setting the vars to each other - unintended on the loop back, (not on the way down the loop) because it's not changing anything - so when it's commented out, it functions, but when commented back in, nothing changes?
    repeat2
             MOV ctmp1, accel 
    [noparse][[/noparse]...]
             MOV accel, ctmp1 ' <-
             JMP #repeat2 
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • T ChapT Chap Posts: 4,223
    edited 2009-08-16 21:21
    Yes I agree, I posted the full program days ago and got no response to the same question.

    But this is the short version that cuts to the chase about the sub and mov problem:




    
    PUB MoveX
         motorr(0, @X, 1, 0, @Xdone)
    
    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           'test version only for brevity
                    ORG     0
    cogstart
                    JMP     #cogstart0
    pinstart        LONG    0               ' input parameters
    radr            LONG    0
    forward         LONG    0
    reverse         LONG    0
    ID              LONG    0
    cogstart0
                    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
                    MOV     accel, Caccel           'reset accel
                    MOV     arate, Carate           'reset accel rate
                    MOV     decel, Cdecel           'reset decel
                    MOV     drate, Cdrate           'reset decel rate
                    MOV     FRQA, #1                '008    FRQA := 1
    
    
    repeat1         '-----------------SET UP------------------
                    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     ctmp2, accel
    repeat2         '-----------------M A I N    L O O P-----------------------
    
                    RDLONG  PHSA, pwidth            '023   set PHSA := width for pulse size
                    MOV     ctmp1, accel            '025   set ctmp1 to accel
                    ADD     ctmp1, CNT
                    WAITCNT ctmp1, #0               '027   waitcnt for ctmp1  waitcnt(accel + CNT)
                    MOV     ctmp1, accel
                    SUBS    ctmp1, arate
                    'MOV     accel, ctmp1
                    JMP     #repeat2                'restart at loop
    
    
    
    Czero           LONG    0               ' constants
    Cone            LONG    1
    C8SHL26         LONG    %00100 << 26
    
    
    Caccel          LONG    5500     'accel
    Carate          LONG    100
    Cdecel          LONG    400     '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
    
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2009-08-16 21:23
    I think our posts crossed in the mail... please see immediately above your code list - H

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • T ChapT Chap Posts: 4,223
    edited 2009-08-16 21:26
    CounterRotatingProps said...
    [noparse][[/noparse]/code]OK, extracting the essense, it seems like your setting the vars to each other - unintended on the loop back, (not on the way down the loop) because it's not changing anything - so when it's commented out, it functions, but when commented back in, nothing changes?


    
    repeat2
             MOV ctmp1, accel 
    [noparse][[/noparse]...]
             MOV accel, ctmp1 ' <- 
    
             JMP #repeat2  
    
    



    The motor runs at a fixed speed based on accel + CNT in the waitcnt. Any combintation I have tried to reduce accel on each iteration does nothing. Either the speed is still fixed, or in the code initially posted on the thread, the motor doesn't move at all. I simply want to subtract aRate from accel on each pass, thereby speeding up the waitcnt and motor speed as in acceleration mode until it hits a fixed number. In SPIN, the result of accel - arate ended up as 0, but even at that speed, the motors were still too slow. So I am sorting out the ASM version and studying the conversion. In ASM I will have to put a limit on how low the value can go (accel - arate) so that it doesn't go too fast. The ASM is already extremely fast compared to the SPIN, so a limiter will be required, similar to SPIN limit min #> . Using an externally loaded(USB to Serial) variable to set the speed limit remotely will be the goal. But first I need to solve the basic loop with accel.

    Post Edited (TChapman) : 8/16/2009 9:41:50 PM GMT
  • T ChapT Chap Posts: 4,223
    edited 2009-08-16 22:50
    OK in fact the loop I posted at the top was working as it should. The problem was that the value of accel = 5500 and the amount subtracted from it arate = 100 was going by so fast that there was nothing taking place on the motor, it was going so fast that the pins never even had time to reset or toggle. This new experience with ASM is an eye opener to the radical difference in speeds and how you have to think things through differently to deal with those speeds.
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2009-08-16 22:58
    Good job hunting that down!

    > This new experience with ASM is an eye opener to the radical difference in speeds and how you have to think things through differently to deal with those speeds.

    Yeah, the first time I saw the number of clock cycles in a second, my eyes crossed as I tried to imagine it.
    And then, since most pasm instructions take only 4 clock cycles, how many of them can you pack into one second? WOW!
    Yes, the prop's not the fastest micro on the planet, but with 7 other cogs, it's certainly acceptable, eh?

    cheers
    - H

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • T ChapT Chap Posts: 4,223
    edited 2009-08-16 23:49
    Now trying to find a way to limit the speeds. CMPS or CMP I think is the way, setting a number to not exceed. I need a limit minimum like in spin.
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2009-08-16 23:53
    What actual numbers do you think you'll need?

    (Your OP caught my attention because I'm learning pasm too and am looking at doing a similar control mechanism).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • kuronekokuroneko Posts: 3,623
    edited 2009-08-17 00:17
    TChapman said...
    I need a limit minimum like in spin.
    Something like min[noparse][[/noparse] s]/max[noparse][[/noparse] s] (propeller manual starting at p.307)?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-08-17 00:23
    The assembler has min and max instructions, both signed and unsigned. Also, check out cmpsub.

    -Phil
  • T ChapT Chap Posts: 4,223
    edited 2009-08-17 00:27
    With spin I ran the loop as fast as possible. Accel dictates the speed. When you reduce accel by arate, eventually
  • T ChapT Chap Posts: 4,223
    edited 2009-08-17 01:02
    Oh I missed some posts while using the cell. The min and max is the solution. Slowly printing out useful ASM pages.

    This makes me want to put together an app that translates SPIN instructions to ASM.

    Input #> 400 on the SPIN side and output mins value, value2 on the other. Copy and paste to your code. I see lots of little chunks that could be translated rather easily.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-08-17 01:19
    You're on your way to writing a compiler! smile.gif

    -Phil
  • T ChapT Chap Posts: 4,223
    edited 2009-08-17 01:42
    Once you mess with ASM, you don't want to go back.

    How many hours spent trying to get speed out of Spin, could have already learned the 6 to 8 basic ASM instructions and been up and running.

    It appears that if you want to use an actual number for the value2 of each instruction, you havr to keep the number under 8 bits, else refer to a register/long.
  • SRLMSRLM Posts: 5,045
    edited 2009-08-17 05:00
    TChapman said...
    It appears that if you want to use an actual number for the value2 of each instruction, you havr to keep the number under 8 bits, else refer to a register/long.

    The source field can have 9 bits for immediate addressing (indicated by #).
Sign In or Register to comment.