Shop OBEX P1 Docs P2 Docs Learn Events
Assembly code problem — Parallax Forums

Assembly code problem

OwenOwen Posts: 100
edited 2007-07-02 01:34 in Propeller 1
can anyone help me with my first assembly code program? it drives step direction and enable for a stepper motor project? I can get the motors to move and change direction when this code is omitted:
test _stoped, #1 wz
if_z jmp #:reload

but with the previouse two lines the program waits untill the clock rolls back over before the program will resume every time stoped is equal to 0. I'm stumped
Thank's for any help


var
long stepPin, enablePin, dirPin
long Spd
long Dir
long coordinate
long movingindicator
long stoped

long Cog

long previouseActual_speed
long joyspeed
long requested_speed
long raw_temp
long joyTemp
Long JoystickRaw
long joystick_temp

OBJ

psx                  : "psx_v1.5"


pub Start(pulsPin, goPin, directionPin, coordAddress, movingAddress) | coordAdress

stepPin    := |< pulsPin
enablePin  := |< goPin
dirPin     := |< directionPin
movingindicator:= |< movingAddress
stoped:=1
spd:=255000 
'Stop
Cog := cognew(@entry, @stepPin)+1 

PUB ChangeSpeed(joy_stick, stp)  |  smooth, joystick_scaled  
   smooth := 90
  
       if stp == 0                                   
         stoped := 1 
         byte[noparse][[/noparse]movingindicator]:=0
         return
      
      stoped:=0
      byte[noparse][[/noparse]movingindicator]:=1

                                                             
     joystick_scaled := 1000 * (joy_stick + 1)                                                                        

     joystick_temp:= (joystick_temp * smooth + joystick_scaled  * (100 - smooth))/100

     if joystick_temp < 127000
         spd:= 255000 - ||((joystick_temp - 128000) * 2)   
         dir:= 1
                                                                           
     else
         spd:= 255000 - ((joystick_temp - 129000) * 2)         
         dir:= 0

    
                                 
    raw_temp := joystick_temp
    joyTemp := joystick_scaled
    JoystickRaw := joy_stick
PUB Stop
{{Stop toggling process, if any.}}

  if Cog
    cogstop(Cog~ -1)
   

DAT

entry
                      
                      
                      mov     p,par                ' load parameter pointer into p (points to global variables)
                                                         ' p is just a copy and keeps par unchanged for later. 
                      rdlong  _stepPin,p         ' load first parameter into _steppin (cog ram)
                      add     p,#4                  ' Increment address to next global variable
                      rdlong  _enablePin,p      ' Load second parameter   _enablepin
                      add     p,#4            

                      rdlong  _dirPin,p          
                      add     p,#4

                      rdlong  _Spd,p        
                      add     p,#4

                      rdlong  _Dir,p         
                      add     p,#4

                      rdlong  _coordinate,p     
                      add     p,#4           

                      rdlong  _movingindicator,p     
                      add     p,#4

                      rdlong  _stoped, p     

          
                     
                      mov     _pinmask,_stepPin
                      or      _pinmask,_enablePin
                      or      _pinmask,_dirPin
                     
                      or     dira, _pinmask           ' Set the pins as outputs
                       'Make pins high
                      
                      'or     outa, _pinmask

                      mov    time,cnt                 ' find the current time
                      add    time,on_time           ' create target time

:loop                 

                      test    _stoped, #1  wz    'if variable is set to stop loop reloading variables untill stoped is cleared
               if_z   jmp    #:reload

                      waitcnt time,_Spd        ' wait for delay to pass    
                      test    _dir,#1  wz
                      muxz    outa, _dirPin
                      xor     outa ,_steppin     ' toggle the pins
                      waitcnt time,on_time     ' wait for delay to pass
                      xor     outa,_steppin      ' toggle
                      
                                                      ' reload the variables from hub ram as they may have been changed
:reload               mov     p,par
                      add     p,#12            ' we add 8 to skip the first two variables (pin1 and pin2)                                     
                      rdlong  _Spd,p           ' and off time
                      add     p,#4
                      rdlong  _Dir,p
                      add     p,#12
                      rdlong  _stoped,p
                      jmp    #:loop           ' and loop away
                                                

                                      


on_time                long    100                  ' delay in clock cycles 
' Uninitialized data
_stepPin                res     1  
_enablePin             res     1  
_dirPin                  res     1  
_Spd                     res     1  
_Dir                      res     1  
_coordinate           res     1  
_movingindicator   res     1
_stoped                res     1


time                     res     1
_pinmask             res     1
p                         res     1

Comments

  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-07-01 16:53
    Owen said...

    test _stoped, #1 wz
    if_z jmp #:reload

    This code skips to :reload if _stoped is zero. I suspect you want to skip if _stoped is equal to one.

    You need to look up the way that TEST works in the manual. It works like AND.

    (You might want to spell it "stopped" too wink.gif
  • OwenOwen Posts: 100
    edited 2007-07-01 17:47
    but nothing happens if I change the 2 lines to:
            test _stoped, #0 wz
    if_z   jmp #:reload
    
    



    Am I missing how "test" works? is there another way to do this?
  • GennadyGennady Posts: 34
    edited 2007-07-01 18:00
    Owen said...
    but nothing happens if I change the 2 lines to:
            test _stoped, #0 wz
    if_z   jmp #:reload
    
    



    Am I missing how "test" works? is there another way to do this?
    Hi Owen,
    I believe now it will always jump confused.gif (test_stopped AND 0 is always 0, so Z is always 1).
    I think the following may work:
    ········test_stopped, #1 wc
    if_c·· jump· #:reload··
    c is set when result contains an odd number of high bits (that is waht will happen when test_stopped is 1).
    Gennady
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-07-01 18:29
    Owen said...
    but nothing happens if I change the 2 lines to:
            test _stoped, #0 wz
    if_z   jmp #:reload
    
    


    Am I missing how "test" works? is there another way to do this?

    What you had originally:
    if (_stoped AND 1) = false then jump.

    What you have now:
    if (_stoped AND 0) = false then jump.

    I'd suggest this conveys your meaning best:
    CMP _stoped,#0 wz
    if_ne JMP :reload
    
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-07-01 18:43
    if in doubt rtfm

    Graham
  • OwenOwen Posts: 100
    edited 2007-07-01 23:25
    I did read the manual but because it still wasn't working I thought I would ask. anyway I tried

    CMP _stoped,#0 wz
    if_ne JMP :reload

    and

    test _stopped, #1 wc
    if_c jump #:reload

    both with no luck but if I use:

    test _stopped, #1 wc
    if_c jump #:reload

    the motors wait a minute or so and then they move until stoped becomes 0 then they wait for another minute before they move again. Makes me think there is a problem with waitcnt somewhere but I don't see it.
  • codemonkeycodemonkey Posts: 38
    edited 2007-07-01 23:57
    Owen,
    Not a prop assembler programmer, but if i were thinking how i were to do it in spin, i would notice that on_time is 100, and

    ·mov time,cnt ' find the current time
    ·add time,on_time ' create target time

    then some instructions, then

    ·waitcnt time,_Spd ' wait for delay to pass
    ·test····_dir,#1··wz
    ·muxz····outa,·_dirPin
    ·xor·····outa·,_steppin·····'·toggle·the·pins
    ·waitcnt·time,on_time

    I couldn't see where you set your clock speed, but is there any chance that when a waitcnt is finally executed that enough cycles have passed so that cnt is already past what the value of "time" is? I've seen it said that it takes about a minute for cnt to cycle through at highest clock speed which seems to match your symptoms for "...then they wait for another minute or so before they move again." Just a thought.

    Post Edited (codemonkey) : 7/2/2007 12:11:47 AM GMT
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-07-02 00:31
    my appologies, I thought the problem had been solved through a change in the test usage.

    Your problem I think is your use of waitcnt. If the program is looping reloading the variables then the target for the waitcnt:

    waitcnt time,_Spd        ' wait for delay to pass
    



    Will have already passed when it comes to that line hence the long delay as the target comes around again.

    So just do

    mov  cnt, time
    add   time,_Spd
    waitcnt  time
    
    



    There may be other issues but I'm sure this is one.

    Graham
  • OwenOwen Posts: 100
    edited 2007-07-02 01:34
    thank you! this completely solved my problem, I thought it may have had something to do with waitcnt. Well I'm on my way to a better understanding of assembly code little by little.
    Thanks for all the help,

    Owen
Sign In or Register to comment.