-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpwm.pio
87 lines (76 loc) · 2.89 KB
/
pwm.pio
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
.program pwm
.side_set 1 opt
; should enable autopull
wait 1 pin 0
.wrap_target
public begin:
out y, 16 ; period value
out x, 16 ; duty value
public switch:
jmp x!=y, low ; if x == y then set pin high, else set low
jmp high side 1 ; x == y, so set pin high
public high:
nop ; single dummy cycle to keep the two paths the same length
jmp y--, high side 1 ; set pin high, until y hits 0
jmp begin
public low:
jmp y--, switch side 0 ; set pin low and count down
.wrap
.program pwm_up_down
.side_set 1 opt
; should enable autopull
wait 1 pin 0
.wrap_target
public begin0:
out y, 16 ; period value
out x, 16 ; duty value
public switch0:
jmp x!=y, low0 ; if x == y then set pin high, else set low
jmp high0 side 1 ; x == y, so set pin high
public high0:
nop ; single dummy cycle to keep the two paths the same length
jmp y--, high0 side 1 ; set pin high, until y hits 0
jmp begin1
public low0:
jmp y--, switch0 side 0 ; set pin low and count down
public begin1:
out y, 16 ; period value
out x, 16 ; duty value
public switch1:
jmp x!=y, low1 ; if x == y then set pin high, else set low
jmp high1 side 0 ; x == y, so set pin high
public high1:
nop ; single dummy cycle to keep the two paths the same length
jmp y--, high1 side 0 ; set pin high, until y hits 0
jmp begin0
public low1:
jmp y--, switch1 side 1 ; set pin low and count down
.wrap
% c-sdk {
#include "hardware/gpio.h"
static inline void pwm_program_init(PIO pio, uint sm, uint offset, bool up_down, uint pin, bool polarity, uint sync_pin) {
// set the side set pin
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
// init set the pwm pin low
pio_sm_set_pins_with_mask(pio, sm, 0, (1u << pin));
// choose the counter mode
pio_sm_config c = up_down ? pwm_up_down_program_get_default_config(offset) : pwm_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
// set the sync pin
pio_gpio_init(pio, sync_pin);
gpio_pull_down(sync_pin);
// set pwm pin is output, sync_pin is input
pio_sm_set_pindirs_with_mask(pio, sm, (1u << pin), (1u << pin) | (1u << sync_pin));
sm_config_set_in_pins(&c, sync_pin);
// out shift to right, auto-pull enable, 32 bit threshold for auto-pull
sm_config_set_out_shift(&c, true, true, 32);
float div = 1.0f;
sm_config_set_clkdiv(&c, div);
// choose the pin polarity
gpio_set_outover(pin, polarity ? GPIO_OVERRIDE_NORMAL : GPIO_OVERRIDE_INVERT);
// picos are synchronized, so bypass input synchroniser to reduce input delay.
hw_set_bits(&pio->input_sync_bypass, 1u << sync_pin);
pio_sm_init(pio, sm, offset, &c);
}
%}