I want to generate a PWM signal with first pulse suppression and send it to laser controller which needs first pulse suppression upon laser beam OFF to ON to prevent high energy output at first pulse of PWM signal. Appreciate very much, if anybody can help me to modify PI PICO PIO PWM state machine to implement the first pulse suppression. Here is my modified PIO PWM state machine to turn ON and OFF PWM output upon signaling laser beam ON/OFF signal through jump input setup for the state machine.
.program pwm
.side_set 1 opt
pull noblock side 0 ; Pull from FIFO to OSR if available, else copy X to OSR. Set pwm pin low
mov x, osr ; Copy most-recently-pulled value back to scratch X
mov y, isr ; ISR contains PWM period. Y used as counter.
countloop:
jmp x!=y noset ; Set pwm pin high if X == Y, keep the two paths length matched
jmp pin sethi ; when beam enable pin is high set pwm pin high over side set pin, jump to the label sethi
jmp noset
sethi:
jmp skip side 1
noset:
nop ; Single dummy cycle to keep the two paths the same length
skip:
jmp y-- countloop ; Loop until Y hits 0, then pull a fresh PWM value from FIFO
pwm, period clock counts and level clock counts are set by following C functions.
% c-sdk {
static inline void pwm_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = pwm_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
sm_config_set_jmp_pin(&c, 2);
pio_sm_init(pio, sm, offset, &c);
}
%}
// Write `period` to the input shift register
void pio_pwm_set_period(PIO pio, uint sm, uint32_t period) {
pio_sm_set_enabled(pio, sm, false);
pio_sm_restart(pio,sm);
pio_sm_clear_fifos(pio,sm);
pio_sm_put_blocking(pio, sm, period);
pio_sm_exec(pio, sm, pio_encode_pull(false, false));
pio_sm_exec(pio, sm, pio_encode_out(pio_isr, 32));
pio_sm_set_enabled(pio, sm, true);
}
// Write `level` to TX FIFO. State machine will copy this into X.
void pio_pwm_set_level(PIO pio, uint sm, uint32_t level) {
pio_sm_put_blocking(pio, sm, level);
}
.program pwm
.side_set 1 opt
pull noblock side 0 ; Pull from FIFO to OSR if available, else copy X to OSR. Set pwm pin low
mov x, osr ; Copy most-recently-pulled value back to scratch X
mov y, isr ; ISR contains PWM period. Y used as counter.
countloop:
jmp x!=y noset ; Set pwm pin high if X == Y, keep the two paths length matched
jmp pin sethi ; when beam enable pin is high set pwm pin high over side set pin, jump to the label sethi
jmp noset
sethi:
jmp skip side 1
noset:
nop ; Single dummy cycle to keep the two paths the same length
skip:
jmp y-- countloop ; Loop until Y hits 0, then pull a fresh PWM value from FIFO
pwm, period clock counts and level clock counts are set by following C functions.
% c-sdk {
static inline void pwm_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = pwm_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
sm_config_set_jmp_pin(&c, 2);
pio_sm_init(pio, sm, offset, &c);
}
%}
// Write `period` to the input shift register
void pio_pwm_set_period(PIO pio, uint sm, uint32_t period) {
pio_sm_set_enabled(pio, sm, false);
pio_sm_restart(pio,sm);
pio_sm_clear_fifos(pio,sm);
pio_sm_put_blocking(pio, sm, period);
pio_sm_exec(pio, sm, pio_encode_pull(false, false));
pio_sm_exec(pio, sm, pio_encode_out(pio_isr, 32));
pio_sm_set_enabled(pio, sm, true);
}
// Write `level` to TX FIFO. State machine will copy this into X.
void pio_pwm_set_level(PIO pio, uint sm, uint32_t level) {
pio_sm_put_blocking(pio, sm, level);
}
Statistics: Posted by kapico — Wed Sep 24, 2025 6:53 pm — Replies 0 — Views 126