1
1
;
2
- ; Copyright (c) 2021- 2023 pmarques-dev @ github
2
+ ; Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
3
3
;
4
4
; SPDX-License-Identifier: BSD-3-Clause
5
5
;
26
26
; to sysclk / 10 (e.g., sysclk 125MHz, max step rate = 12.5 Msteps/sec)
27
27
28
28
; 00 state
29
- JMP update ; read 00
30
- JMP decrement ; read 01
31
- JMP increment ; read 10
32
- JMP update ; read 11
29
+ JMP update ; read 00
30
+ JMP decrement ; read 01
31
+ JMP increment ; read 10
32
+ JMP update ; read 11
33
33
34
34
; 01 state
35
- JMP increment ; read 00
36
- JMP update ; read 01
37
- JMP update ; read 10
38
- JMP decrement ; read 11
35
+ JMP increment ; read 00
36
+ JMP update ; read 01
37
+ JMP update ; read 10
38
+ JMP decrement ; read 11
39
39
40
40
; 10 state
41
- JMP decrement ; read 00
42
- JMP update ; read 01
43
- JMP update ; read 10
44
- JMP increment ; read 11
41
+ JMP decrement ; read 00
42
+ JMP update ; read 01
43
+ JMP update ; read 10
44
+ JMP increment ; read 11
45
45
46
46
; to reduce code size, the last 2 states are implemented in place and become the
47
47
; target for the other jumps
48
48
49
49
; 11 state
50
- JMP update ; read 00
51
- JMP increment ; read 01
50
+ JMP update ; read 00
51
+ JMP increment ; read 01
52
52
decrement:
53
- ; note: the target of this instruction must be the next address, so that
54
- ; the effect of the instruction does not depend on the value of Y. The
55
- ; same is true for the "JMP X--" below. Basically "JMP Y--, <next addr>"
56
- ; is just a pure "decrement Y" instruction, with no other side effects
57
- JMP Y--, update ; read 10
53
+ ; note: the target of this instruction must be the next address, so that
54
+ ; the effect of the instruction does not depend on the value of Y. The
55
+ ; same is true for the "JMP X--" below. Basically "JMP Y--, <next addr>"
56
+ ; is just a pure "decrement Y" instruction, with no other side effects
57
+ JMP Y--, update ; read 10
58
58
59
- ; this is where the main loop starts
59
+ ; this is where the main loop starts
60
60
.wrap_target
61
61
update:
62
- MOV ISR, Y
63
- PUSH noblock
62
+ MOV ISR, Y ; read 11
63
+ PUSH noblock
64
64
65
65
sample_pins:
66
- ; we shift into ISR the last state of the 2 input pins (now in OSR) and
67
- ; the new state of the 2 pins, thus producing the 4 bit target for the
68
- ; computed jump into the correct action for this state. Both the PUSH
69
- ; above and the OUT below zero the other bits in ISR
70
- OUT ISR, 2
71
- IN PINS, 2
72
-
73
- ; save the state in the OSR, so that we can use ISR for other purposes
74
- MOV OSR, ISR
75
- ; jump to the correct state machine action
76
- MOV PC, ISR
77
-
78
- ; the PIO does not have a increment instruction, so to do that we do a
79
- ; negate, decrement, negate sequence
66
+ ; we shift into ISR the last state of the 2 input pins (now in OSR) and
67
+ ; the new state of the 2 pins, thus producing the 4 bit target for the
68
+ ; computed jump into the correct action for this state. Both the PUSH
69
+ ; above and the OUT below zero out the other bits in ISR
70
+ OUT ISR, 2
71
+ IN PINS, 2
72
+
73
+ ; save the state in the OSR, so that we can use ISR for other purposes
74
+ MOV OSR, ISR
75
+ ; jump to the correct state machine action
76
+ MOV PC, ISR
77
+
78
+ ; the PIO does not have a increment instruction, so to do that we do a
79
+ ; negate, decrement, negate sequence
80
80
increment:
81
- MOV Y, ~Y
82
- JMP Y--, increment_cont
81
+ MOV Y, ~Y
82
+ JMP Y--, increment_cont
83
83
increment_cont:
84
- MOV Y, ~Y
85
- .wrap ; the .wrap here avoids one jump instruction and saves a cycle too
84
+ MOV Y, ~Y
85
+ .wrap ; the .wrap here avoids one jump instruction and saves a cycle too
86
86
87
87
88
88
@@ -97,46 +97,45 @@ increment_cont:
97
97
98
98
static inline void quadrature_encoder_program_init(PIO pio, uint sm, uint pin, int max_step_rate)
99
99
{
100
- pio_sm_set_consecutive_pindirs(pio, sm, pin, 2, false);
101
- gpio_pull_up(pin);
102
- gpio_pull_up(pin + 1);
103
-
104
- pio_sm_config c = quadrature_encoder_program_get_default_config(0);
105
-
106
- sm_config_set_in_pins(&c, pin); // for WAIT, IN
107
- sm_config_set_jmp_pin(&c, pin); // for JMP
108
- // shift to left, autopull disabled
109
- sm_config_set_in_shift(&c, false, false, 32);
110
- // don't join FIFO's
111
- sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_NONE);
112
-
113
- // passing "0" as the sample frequency,
114
- if (max_step_rate == 0) {
115
- sm_config_set_clkdiv(&c, 1.0);
116
- } else {
117
- // one state machine loop takes at most 10 cycles
118
- float div = (float)clock_get_hz(clk_sys) / (10 * max_step_rate);
119
- sm_config_set_clkdiv(&c, div);
120
- }
121
-
122
- pio_sm_init(pio, sm, 0, &c);
123
- pio_sm_set_enabled(pio, sm, true);
100
+ pio_sm_set_consecutive_pindirs(pio, sm, pin, 2, false);
101
+ gpio_pull_up(pin);
102
+ gpio_pull_up(pin + 1);
103
+
104
+ pio_sm_config c = quadrature_encoder_program_get_default_config(0);
105
+
106
+ sm_config_set_in_pins(&c, pin); // for WAIT, IN
107
+ sm_config_set_jmp_pin(&c, pin); // for JMP
108
+ // shift to left, autopull disabled
109
+ sm_config_set_in_shift(&c, false, false, 32);
110
+ // don't join FIFO's
111
+ sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_NONE);
112
+
113
+ // passing "0" as the sample frequency,
114
+ if (max_step_rate == 0) {
115
+ sm_config_set_clkdiv(&c, 1.0);
116
+ } else {
117
+ // one state machine loop takes at most 10 cycles
118
+ float div = (float)clock_get_hz(clk_sys) / (10 * max_step_rate);
119
+ sm_config_set_clkdiv(&c, div);
120
+ }
121
+
122
+ pio_sm_init(pio, sm, 0, &c);
123
+ pio_sm_set_enabled(pio, sm, true);
124
124
}
125
125
126
126
static inline int32_t quadrature_encoder_get_count(PIO pio, uint sm)
127
127
{
128
- uint ret;
129
- int n;
130
-
131
- // if the FIFO has N entries, we fetch them to drain the FIFO,
132
- // plus one entry which will be guaranteed to not be stale
133
- n = pio_sm_get_rx_fifo_level(pio, sm) + 1;
134
- while (n > 0) {
135
- ret = pio_sm_get_blocking(pio, sm);
136
- n--;
137
- }
138
- return ret;
128
+ uint ret;
129
+ int n;
130
+
131
+ // if the FIFO has N entries, we fetch them to drain the FIFO,
132
+ // plus one entry which will be guaranteed to not be stale
133
+ n = pio_sm_get_rx_fifo_level(pio, sm) + 1;
134
+ while (n > 0) {
135
+ ret = pio_sm_get_blocking(pio, sm);
136
+ n--;
137
+ }
138
+ return ret;
139
139
}
140
140
141
141
%}
142
-
0 commit comments