Comment by topspin
> but the 5 bit counters
5 bit shift register, I believe you mean. Have a look at this. 16 instructions. Completely untested. I qualified my comment about RP2350 as "I believe," because I haven't actually done this: only investigated it via ChatGPT and Gemini. But it appears sound. Precision bit banging. PIO is pretty cool.
; PIO program for high-precision stepper profiles with a two-word data format.
; RP2350 clock is 150 MHz
; Word 1: [32-bit Low-Time Delay]. A value of 0 is the sentinel to stop.
; Word 2: [32-bit Repetition Count] (N-1).
.program stepper_pwm
.define HIGH_PULSE_CYCLES 2998 ; 20us @ 150MHz. Total delay is (CONSTANT + 2) cycles. 3000 - 2 = 2998.
.side_set 1 opt
entry_point:
pull block ; Pull Word 1 (Low-Time Delay) from DMA.
mov x, osr ; Copy to X for sent sentinel test
jmp !x, process_step ; fall through to the stop_sequence when sentinel == 0
stop_sequence:
nop side 0 ; Force the output pin LOW.
irq set 5 ; Signal the core that the profile has finished.
halt_loop:
jmp halt_loop ; Halt state machine.
process_step:
mov y, x ; Y now holds the 32-bit Low-Time Delay.
mov isr, y ; Save LOW delay in ISR for use in every repetition.
pull block ; Pull Word 2 (Repetition Count) from DMA.
mov x, osr ; X now holds the 32-bit Repetition Count.
rep_loop:
; High pulse duration = (HIGH_PULSE_CYCLES + 2) clock cycles.
mov y, HIGH_PULSE_CYCLES side 1
high_loop:
jmp y-- high_loop side 1
; Low pulse duration between reps = (LOW_DELAY_FROM_ISR + 3) clock cycles.
mov y, isr side 0
low_loop:
jmp y-- low_loop side 0
jmp x-- rep_loop ; Decrement repetition counter and loop if not zero.
jmp entry_point ; Finished all reps for this step, get the next one.