8 ms·
When I was doing stepper control on rp2040 I looked into using PIO but the 5 bit counters and 32 instruction limit made it too awkward to use. What worked bette
by fest 1y ago
When I was doing stepper control on rp2040 I looked into using PIO but the 5 bit counters and 32 instruction limit made it too awkward to use.
What worked better for my needs was dedicating 2nd core for just motion control and bit-banging the step/dir signals- simple to implement and good enough for the modest needs I had (just trapezoidal velocity profile for single axis motion).
- deleted 1y ago[deleted]
- deleted 1y ago[deleted]
- topspin 1y ago> 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.