Spin > Assembly translation needed
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!
Post Edited (TChapman) : 8/14/2009 3:49:17 AM GMT
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
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