Quad Unipoler stepper driver, in progress.
About an hour ago I decided to redo my stepper driver, to use PASM and just worry about how to control one stepper, then implement simple Ping Pong Pang Pow multitasking to get it up to four.
This has not been tested yet, as I need to rewrite my simple command interpreter to put in values for use with the new layout, as was easiest from PASM.
For my use this will be tied to an RPi using a simple clocked bi-directional three wire serial implementation based on that used by the Game Boy. In my use there is a command interpreter to take commands from a program running on the RPi.
The unimplemented 5th task will end up updating the current position information in hub ram for access by spin, as well as sending back to whatever else may want to know about it.
Here is where it is, while untested, if you add code to put useful values into the variables used by the PASM driver it should work so long as I did not miss something obvious (this is a quickly thrown together this afternoon, as a better way).
It is in next post, this one turned out to be to long with the code
Also note that the comment at the beginning does mention the command language that I use for my command interpreter.
As long as I did not miss something obvious it should be useful. Do not have much time this afternoon.
This has not been tested yet, as I need to rewrite my simple command interpreter to put in values for use with the new layout, as was easiest from PASM.
For my use this will be tied to an RPi using a simple clocked bi-directional three wire serial implementation based on that used by the Game Boy. In my use there is a command interpreter to take commands from a program running on the RPi.
The unimplemented 5th task will end up updating the current position information in hub ram for access by spin, as well as sending back to whatever else may want to know about it.
Here is where it is, while untested, if you add code to put useful values into the variables used by the PASM driver it should work so long as I did not miss something obvious (this is a quickly thrown together this afternoon, as a better way).
It is in next post, this one turned out to be to long with the code
Also note that the comment at the beginning does mention the command language that I use for my command interpreter.
As long as I did not miss something obvious it should be useful. Do not have much time this afternoon.

Comments
'Concept of usage, for stepper controller. 'Uses a simple command sequence to control steppers. Current version ' recieves its commands custom data link, from a control program ' running on a Raspberry Pi under Raspbian Linux. 'All commands recieved are a long, where the high byte is the command ' and the lower 24-bits are the data for that command. 'Speed is given in steps per second, in the range of 0 to 2048. The ' direction flag indicates a reverse direction when set. Distance is ' measured in steps, and is always taken as a positive number. 'The supported commands are: ' $D0 Set the distance to move stepper A, distance is in bits 0..11, ' max speed is in bits 12..22, and direction in bit 23. ' $D1 Set the distance move for stepper B, same format as $10. ' $D2 Set the distance to move for stepper C, same format as $10. ' $D3 Set the distance to move for stepper D, same format as $10. ' $E0 Set the accelleration rate, for stepper B. ' $E1 Set the accelleration rate, for stepper C. ' $E2 Set the accelleration rate, for stepper D. ' $E3 Set the accelleration rate, for stepper A. ' $F0 Request status. 'Any other value in the high byte is just ignored. 'NOTICE: ACCELERATION NOT YET IMPLEMENTED, SORRY. CON _CLCKMODE XTAL1+PLL16 _XINFREQ 5_000_000 VAR long StpDrA 'Direction of movement for stepper A. long StpDlyA 'Time between steps for stepper A. long StpDstA 'Distance to move for Stepper A. long StpShftA 'Output Shift for stepper A. long StpDrB 'Direction of movement for stepper B. long StpDlyB 'Time between steps for stepper B. long StpDstB 'Distance to move for Stepper B. long StpShftB 'Output Shift for stepper B. long StpDrC 'Direction of movement for stepper C. long StpDlyC 'Time between steps for stepper C. long StpDstC 'Distance to move for Stepper C. long StpShftC 'Output Shift for stepper C. long StpDrD 'Direction of movement for stepper D. long StpDlyD 'Time between steps for stepper D. long StpDstD 'Distance to move for Stepper D. long StpShftD 'Output Shift for stepper D. long APos 'Current Position of Stepper A. long BPos 'Current Position of Stepper A. long CPos 'Current Position of Stepper A. long DPos 'Current Position of Stepper A. '*********************************************************** DAT ORG 0 Stepper '*** Initialize for task 1 ************* MOV dta,PAR 'Only need Shift val once. ADD dta,#8 RDLONG StpShft1,dta ROL Msk1,StpShft1 'Set up some masks. ROL NMsk1,StpShft1 SUB dta, #4 RDLONG StpDly1,dta MOV wt1,StpDly1 'need an initial time. ADD wt1,CNT '*** Initialize for task 2 ************* MOV TASK2,#FtchLp2 ADD dta,#24 RDLONG StpShft2,dta ROL Msk2,StpShft2 'Set up some masks. ROL NMsk2,StpShft2 SUB dta, #4 RDLONG StpDly2,dta MOV wt2,StpDly2 'need an initial time. ADD wt2,CNT '*** Initialize for task 3 ************* MOV TASK3,#FtchLp3 ADD dta,#40 RDLONG StpShft3,dta ROL Msk3,StpShft3 'Set up some masks. ROL NMsk3,StpShft3 SUB dta, #4 RDLONG StpDly3,dta MOV wt3,StpDly3 'need an initial time. ADD wt3,CNT '*** Initialize for task 4 ************* MOV TASK4,#FtchLp4 ADD dta,#56 RDLONG StpShft4,dta ROL Msk4,StpShft4 'Set up some masks. ROL NMsk4,StpShft4 SUB dta, #4 RDLONG StpDly4,dta MOV wt4,StpDly4 'need an initial time. ADD wt4,CNT '*********************************************************** '**** Task 1 Code ****************************************** '*********************************************************** FtchLp1 JUMPRET TASK1,TASK2 MOV dta,PAR 'Grabbing parameters from the HUB. RDLONG StpDr1,dta ADD dta,#4 RDLONG StpDly1,dta ADD dta,#4 RDLONG StpDst1,dta StpLp1 MOV scrt1,Step 'Get the value of the step. ROR scrt1,cstp ROL scrt1,StpShft1 'Line up for the output pins. AND scrt1,NMsk1 'Be clean ADD cstp1,StpDr1 'Get read for next step, AND cstp1,#3 ' remember to keep bound 0, 3 'WAITCNT wt1,StpDly1 'Time it correctly. MOV tmp1,wt1 'And be able to ping pong pang pow. Wlp1 JUMPRET TASK1,TASK2 SUB tmp1,CNT CMP tmp1,CVal WC 'Maximum time to get back here is IF_C JMP #Wlp1 ' 716 clocks, we use 1024. MOV wt1,CNT ADD wt1,StpDly1 AND OUTA,Msk1 OR OUTA,scrt1 'Change only our pins. SUB StpDst1,1 WZ 'Are we done with this move? IF_Z JMP #StpLp1 ' if not keep on, JMP #FtchLp1 ' if we are, get next movement. dta1 long 0 'Index into hub RAM, to get parameters. wt1 long 0 'How long to wait till next step. cstp1 long 0 'Current step index. scrt1 long 0 'Working scratch pad. Msk1 long $FFFFFFF0 'Pin mask. NMsk1 long $0000000F 'Inverted Pin mask. StpDr1 long 0 StpDly1 long 0 StpDst1 long 0 StpShft1 long 0 '*********************************************************** '**** Task 2 Code ****************************************** '*********************************************************** FtchLp2 JMPRET TASK2,TASK3 MOV dta,PAR 'Grabbing parameters from the HUB. ADD dta,#16 RDLONG StpDr2,dta ADD dta,#4 RDLONG StpDly2,dta ADD dta,#4 RDLONG StpDst2,dta JMPRET TASK2,TASK3 StpLp2 MOV scrt2,Step 'Get the value of the step. ROR scrt2,cstp ROL scrt2,StpShft2 'Line up for the output pins. AND scrt2,NMsk2 'Be clean ADD cstp2,StpDr2 'Get read for next step, AND cstp2,#3 ' remember to keep bound 0, 3 'WAITCNT wt2,StpDly2 'Time it correctly. MOV tmp2,wt2 'And be able to ping pong pang pow. Wlp2 JMPRET TASK2,TASK3 SUB tmp2,CNT CMP tmp2,CVal WC 'Maximum time to get back here is IF_C JMP #Wlp2 ' 716 clocks, we use 1024. MOV wt2,CNT ADD wt2,StpDly2 AND OUTA,Msk2 OR OUTA,scrt2 'Change only our pins. SUB StpDst2,1 WZ 'Are we done with this move? IF_Z JMP #StpLp2 ' if not keep on, JMP #FtchLp2 ' if we are, get next movement. dta2 long 0 'Index into hub RAM, to get parameters. wt2 long 0 'How long to wait till next step. cstp2 long 0 'Current step index. scrt2 long 0 'Working scratch pad. Msk2 long $FFFFFFF0 'Pin mask. NMsk2 long $0000000F 'Inverted Pin mask. StpDr2 long 0 StpDly2 long 0 StpDst2 long 0 StpShft2 long 0 '*********************************************************** '**** Task 3 Code ****************************************** '*********************************************************** FtchLp3 JMPRET TASK3,TASK4 MOV dta,PAR 'Grabbing parameters from the HUB. ADD dta,#32 RDLONG StpDr3,dta ADD dta,#4 RDLONG StpDly3,dta ADD dta,#4 RDLONG StpDst3,dta JMPRET TASK3,TASK4 StpLp3 MOV scrt3,Step 'Get the value of the step. ROR scrt3,cstp ROL scrt3,StpShft3 'Line up for the output pins. AND scrt3,NMsk3 'Be clean ADD cstp3,StpDr3 'Get read for next step, AND cstp3,#3 ' remember to keep bound 0, 3 'WAITCNT wt3,StpDly3 'Time it correctly. MOV tmp3,wt3 'And be able to ping pong pang pow. Wlp3 JMPRET TASK3,TASK4 SUB tmp3,CNT CMP tmp3,CVal WC 'Maximum time to get back here is IF_C JMP #Wlp3 ' 716 clocks, we use 1024. MOV wt3,CNT ADD wt3,StpDly3 AND OUTA,Msk3 OR OUTA,scrt3 'Change only our pins. SUB StpDst3,1 WZ 'Are we done with this move? IF_Z JMP #StpLp3 ' if not keep on, JMP #FtchLp3 ' if we are, get next movement. wt3 long 0 'How long to wait till next step. cstp3 long 0 'Current step index. scrt3 long 0 'Working scratch pad. Msk3 long $FFFFFFF0 'Pin mask. NMsk3 long $0000000F 'Inverted Pin mask. StpDr3 long 0 StpDly3 long 0 StpDst3 long 0 StpShft3 long 0 '*********************************************************** '**** Task 4 Code ****************************************** '*********************************************************** FtchLp4 JMPRET TASK4,TASK1 MOV dta,PAR 'Grabbing parameters from the HUB. ADD dta,#48 RDLONG StpDr4,dta ADD dta,#4 RDLONG StpDly4,dta ADD dta,#4 RDLONG StpDst4,dta JMPRET TASK4,TASK1 StpLp4 MOV scrt4,Step 'Get the value of the step. ROR scrt4,cstp4 ROL scrt4,StpShft4 'Line up for the output pins. AND scrt4,NMsk4 'Be clean ADD cstp4,StpDr4 'Get read for next step, AND cstp4,#3 ' remember to keep bound 0, 3 'WAITCNT wt4,StpDly4 'Time it correctly. MOV tmp4,wt4 'And be able to ping pong pang pow. Wlp4 JMPRET TASK4,TASK1 SUB tmp4,CNT CMP tmp4,CVal WC 'Maximum time to get back here is IF_C JMP #Wlp4 ' 716 clocks, we use 1024. MOV wt4,CNT ADD wt4,StpDly4 AND OUTA,Msk4 OR OUTA,scrt4 'Change only our pins. SUB StpDst4,1 WZ 'Are we done with this move? IF_Z JMP #StpLp4 ' if not keep on, JMP #FtchLp4 ' if we are, get next movement. wt4 long 0 'How long to wait till next step. cstp4 long 0 'Current step index. scrt4 long 0 'Working scratch pad. Msk4 long $FFFFFFF0 'Pin mask. NMsk4 long $0000000F 'Inverted Pin mask. StpDr4 long 0 StpDly4 long 0 StpDst4 long 0 StpShft4 long 0 '*********************************************************** '**** Task 5 Code ****************************************** '*********************************************************** '*********************************************************** '**** Values used by all tasks ***************************** '*********************************************************** Step long %0011_0110_1100_1001 dta long 0 'Index into hub RAM, to get parameters. CVal long 1024 'Value for comparing remaining time. TASK1 LONG 0 TASK2 LONG 0 TASK3 LONG 0 TASK4 LONG 0 {{ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ │is furnished to do so, subject to the following conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ }}Edit: Corrected one bug I noticed while looking at the code.