Skip to content

Commit 81f5c30

Browse files
committed
Only use section attribute in .cpp
1 parent 1c216fd commit 81f5c30

2 files changed

Lines changed: 352 additions & 169 deletions

File tree

Encoder.cpp

Lines changed: 291 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,300 @@
11

22
#include "Encoder.h"
33

4-
// Yes, all the code is in the header file, to provide the user
4+
// Most the code is in the header file, to provide the user
55
// configure options with #define (before they include it), and
66
// to facilitate some crafty optimizations!
77

88
Encoder_internal_state_t * Encoder::interruptArgs[];
99

10+
void ENCODER_ISR_ATTR Encoder::update(Encoder_internal_state_t *arg) ENCODER_ISR_ATTR {
11+
#if defined(__AVR__)
12+
// The compiler believes this is just 1 line of code, so
13+
// it will inline this function into each interrupt
14+
// handler. That's a tiny bit faster, but grows the code.
15+
// Especially when used with ENCODER_OPTIMIZE_INTERRUPTS,
16+
// the inline nature allows the ISR prologue and epilogue
17+
// to only save/restore necessary registers, for very nice
18+
// speed increase.
19+
asm volatile (
20+
"ld r30, X+" "\n\t"
21+
"ld r31, X+" "\n\t"
22+
"ld r24, Z" "\n\t" // r24 = pin1 input
23+
"ld r30, X+" "\n\t"
24+
"ld r31, X+" "\n\t"
25+
"ld r25, Z" "\n\t" // r25 = pin2 input
26+
"ld r30, X+" "\n\t" // r30 = pin1 mask
27+
"ld r31, X+" "\n\t" // r31 = pin2 mask
28+
"ld r22, X" "\n\t" // r22 = state
29+
"andi r22, 3" "\n\t"
30+
"and r24, r30" "\n\t"
31+
"breq L%=1" "\n\t" // if (pin1)
32+
"ori r22, 4" "\n\t" // state |= 4
33+
"L%=1:" "and r25, r31" "\n\t"
34+
"breq L%=2" "\n\t" // if (pin2)
35+
"ori r22, 8" "\n\t" // state |= 8
36+
"L%=2:" "ldi r30, lo8(pm(L%=table))" "\n\t"
37+
"ldi r31, hi8(pm(L%=table))" "\n\t"
38+
"add r30, r22" "\n\t"
39+
"adc r31, __zero_reg__" "\n\t"
40+
"asr r22" "\n\t"
41+
"asr r22" "\n\t"
42+
"st X+, r22" "\n\t" // store new state
43+
"ld r22, X+" "\n\t"
44+
"ld r23, X+" "\n\t"
45+
"ld r24, X+" "\n\t"
46+
"ld r25, X+" "\n\t"
47+
"ijmp" "\n\t" // jumps to update_finishup()
48+
// TODO move this table to another static function,
49+
// so it doesn't get needlessly duplicated. Easier
50+
// said than done, due to linker issues and inlining
51+
"L%=table:" "\n\t"
52+
"rjmp L%=end" "\n\t" // 0
53+
"rjmp L%=plus1" "\n\t" // 1
54+
"rjmp L%=minus1" "\n\t" // 2
55+
"rjmp L%=plus2" "\n\t" // 3
56+
"rjmp L%=minus1" "\n\t" // 4
57+
"rjmp L%=end" "\n\t" // 5
58+
"rjmp L%=minus2" "\n\t" // 6
59+
"rjmp L%=plus1" "\n\t" // 7
60+
"rjmp L%=plus1" "\n\t" // 8
61+
"rjmp L%=minus2" "\n\t" // 9
62+
"rjmp L%=end" "\n\t" // 10
63+
"rjmp L%=minus1" "\n\t" // 11
64+
"rjmp L%=plus2" "\n\t" // 12
65+
"rjmp L%=minus1" "\n\t" // 13
66+
"rjmp L%=plus1" "\n\t" // 14
67+
"rjmp L%=end" "\n\t" // 15
68+
"L%=minus2:" "\n\t"
69+
"subi r22, 2" "\n\t"
70+
"sbci r23, 0" "\n\t"
71+
"sbci r24, 0" "\n\t"
72+
"sbci r25, 0" "\n\t"
73+
"rjmp L%=store" "\n\t"
74+
"L%=minus1:" "\n\t"
75+
"subi r22, 1" "\n\t"
76+
"sbci r23, 0" "\n\t"
77+
"sbci r24, 0" "\n\t"
78+
"sbci r25, 0" "\n\t"
79+
"rjmp L%=store" "\n\t"
80+
"L%=plus2:" "\n\t"
81+
"subi r22, 254" "\n\t"
82+
"rjmp L%=z" "\n\t"
83+
"L%=plus1:" "\n\t"
84+
"subi r22, 255" "\n\t"
85+
"L%=z:" "sbci r23, 255" "\n\t"
86+
"sbci r24, 255" "\n\t"
87+
"sbci r25, 255" "\n\t"
88+
"L%=store:" "\n\t"
89+
"st -X, r25" "\n\t"
90+
"st -X, r24" "\n\t"
91+
"st -X, r23" "\n\t"
92+
"st -X, r22" "\n\t"
93+
"L%=end:" "\n"
94+
: : "x" (arg) : "r22", "r23", "r24", "r25", "r30", "r31");
95+
#else
96+
uint8_t p1val = DIRECT_PIN_READ(arg->pin1_register, arg->pin1_bitmask);
97+
uint8_t p2val = DIRECT_PIN_READ(arg->pin2_register, arg->pin2_bitmask);
98+
uint8_t state = arg->state & 3;
99+
if (p1val) state |= 4;
100+
if (p2val) state |= 8;
101+
arg->state = (state >> 2);
102+
switch (state) {
103+
case 1: case 7: case 8: case 14:
104+
arg->position++;
105+
return;
106+
case 2: case 4: case 11: case 13:
107+
arg->position--;
108+
return;
109+
case 3: case 12:
110+
arg->position += 2;
111+
return;
112+
case 6: case 9:
113+
arg->position -= 2;
114+
return;
115+
}
116+
#endif
117+
}
10118

119+
#if defined(ENCODER_USE_INTERRUPTS) && !defined(ENCODER_OPTIMIZE_INTERRUPTS)
120+
#ifdef CORE_INT0_PIN
121+
void Encoder::isr0(void) ENCODER_ISR_ATTR { update(interruptArgs[0]); }
122+
#endif
123+
#ifdef CORE_INT1_PIN
124+
void Encoder::isr1(void) ENCODER_ISR_ATTR { update(interruptArgs[1]); }
125+
#endif
126+
#ifdef CORE_INT2_PIN
127+
void Encoder::isr2(void) ENCODER_ISR_ATTR { update(interruptArgs[2]); }
128+
#endif
129+
#ifdef CORE_INT3_PIN
130+
void Encoder::isr3(void) ENCODER_ISR_ATTR { update(interruptArgs[3]); }
131+
#endif
132+
#ifdef CORE_INT4_PIN
133+
void Encoder::isr4(void) ENCODER_ISR_ATTR { update(interruptArgs[4]); }
134+
#endif
135+
#ifdef CORE_INT5_PIN
136+
void Encoder::isr5(void) ENCODER_ISR_ATTR { update(interruptArgs[5]); }
137+
#endif
138+
#ifdef CORE_INT6_PIN
139+
void Encoder::isr6(void) ENCODER_ISR_ATTR { update(interruptArgs[6]); }
140+
#endif
141+
#ifdef CORE_INT7_PIN
142+
void Encoder::isr7(void) ENCODER_ISR_ATTR { update(interruptArgs[7]); }
143+
#endif
144+
#ifdef CORE_INT8_PIN
145+
void Encoder::isr8(void) ENCODER_ISR_ATTR { update(interruptArgs[8]); }
146+
#endif
147+
#ifdef CORE_INT9_PIN
148+
void Encoder::isr9(void) ENCODER_ISR_ATTR { update(interruptArgs[9]); }
149+
#endif
150+
#ifdef CORE_INT10_PIN
151+
void Encoder::isr10(void) ENCODER_ISR_ATTR { update(interruptArgs[10]); }
152+
#endif
153+
#ifdef CORE_INT11_PIN
154+
void Encoder::isr11(void) ENCODER_ISR_ATTR { update(interruptArgs[11]); }
155+
#endif
156+
#ifdef CORE_INT12_PIN
157+
void Encoder::isr12(void) ENCODER_ISR_ATTR { update(interruptArgs[12]); }
158+
#endif
159+
#ifdef CORE_INT13_PIN
160+
void Encoder::isr13(void) ENCODER_ISR_ATTR { update(interruptArgs[13]); }
161+
#endif
162+
#ifdef CORE_INT14_PIN
163+
void Encoder::isr14(void) ENCODER_ISR_ATTR { update(interruptArgs[14]); }
164+
#endif
165+
#ifdef CORE_INT15_PIN
166+
void Encoder::isr15(void) ENCODER_ISR_ATTR { update(interruptArgs[15]); }
167+
#endif
168+
#ifdef CORE_INT16_PIN
169+
void Encoder::isr16(void) ENCODER_ISR_ATTR { update(interruptArgs[16]); }
170+
#endif
171+
#ifdef CORE_INT17_PIN
172+
void Encoder::isr17(void) ENCODER_ISR_ATTR { update(interruptArgs[17]); }
173+
#endif
174+
#ifdef CORE_INT18_PIN
175+
void Encoder::isr18(void) ENCODER_ISR_ATTR { update(interruptArgs[18]); }
176+
#endif
177+
#ifdef CORE_INT19_PIN
178+
void Encoder::isr19(void) ENCODER_ISR_ATTR { update(interruptArgs[19]); }
179+
#endif
180+
#ifdef CORE_INT20_PIN
181+
void Encoder::isr20(void) ENCODER_ISR_ATTR { update(interruptArgs[20]); }
182+
#endif
183+
#ifdef CORE_INT21_PIN
184+
void Encoder::isr21(void) ENCODER_ISR_ATTR { update(interruptArgs[21]); }
185+
#endif
186+
#ifdef CORE_INT22_PIN
187+
void Encoder::isr22(void) ENCODER_ISR_ATTR { update(interruptArgs[22]); }
188+
#endif
189+
#ifdef CORE_INT23_PIN
190+
void Encoder::isr23(void) ENCODER_ISR_ATTR { update(interruptArgs[23]); }
191+
#endif
192+
#ifdef CORE_INT24_PIN
193+
void Encoder::isr24(void) ENCODER_ISR_ATTR { update(interruptArgs[24]); }
194+
#endif
195+
#ifdef CORE_INT25_PIN
196+
void Encoder::isr25(void) ENCODER_ISR_ATTR { update(interruptArgs[25]); }
197+
#endif
198+
#ifdef CORE_INT26_PIN
199+
void Encoder::isr26(void) ENCODER_ISR_ATTR { update(interruptArgs[26]); }
200+
#endif
201+
#ifdef CORE_INT27_PIN
202+
void Encoder::isr27(void) ENCODER_ISR_ATTR { update(interruptArgs[27]); }
203+
#endif
204+
#ifdef CORE_INT28_PIN
205+
void Encoder::isr28(void) ENCODER_ISR_ATTR { update(interruptArgs[28]); }
206+
#endif
207+
#ifdef CORE_INT29_PIN
208+
void Encoder::isr29(void) ENCODER_ISR_ATTR { update(interruptArgs[29]); }
209+
#endif
210+
#ifdef CORE_INT30_PIN
211+
void Encoder::isr30(void) ENCODER_ISR_ATTR { update(interruptArgs[30]); }
212+
#endif
213+
#ifdef CORE_INT31_PIN
214+
void Encoder::isr31(void) ENCODER_ISR_ATTR { update(interruptArgs[31]); }
215+
#endif
216+
#ifdef CORE_INT32_PIN
217+
void Encoder::isr32(void) ENCODER_ISR_ATTR { update(interruptArgs[32]); }
218+
#endif
219+
#ifdef CORE_INT33_PIN
220+
void Encoder::isr33(void) ENCODER_ISR_ATTR { update(interruptArgs[33]); }
221+
#endif
222+
#ifdef CORE_INT34_PIN
223+
void Encoder::isr34(void) ENCODER_ISR_ATTR { update(interruptArgs[34]); }
224+
#endif
225+
#ifdef CORE_INT35_PIN
226+
void Encoder::isr35(void) ENCODER_ISR_ATTR { update(interruptArgs[35]); }
227+
#endif
228+
#ifdef CORE_INT36_PIN
229+
void Encoder::isr36(void) ENCODER_ISR_ATTR { update(interruptArgs[36]); }
230+
#endif
231+
#ifdef CORE_INT37_PIN
232+
void Encoder::isr37(void) ENCODER_ISR_ATTR { update(interruptArgs[37]); }
233+
#endif
234+
#ifdef CORE_INT38_PIN
235+
void Encoder::isr38(void) ENCODER_ISR_ATTR { update(interruptArgs[38]); }
236+
#endif
237+
#ifdef CORE_INT39_PIN
238+
void Encoder::isr39(void) ENCODER_ISR_ATTR { update(interruptArgs[39]); }
239+
#endif
240+
#ifdef CORE_INT40_PIN
241+
void Encoder::isr40(void) ENCODER_ISR_ATTR { update(interruptArgs[40]); }
242+
#endif
243+
#ifdef CORE_INT41_PIN
244+
void Encoder::isr41(void) ENCODER_ISR_ATTR { update(interruptArgs[41]); }
245+
#endif
246+
#ifdef CORE_INT42_PIN
247+
void Encoder::isr42(void) ENCODER_ISR_ATTR { update(interruptArgs[42]); }
248+
#endif
249+
#ifdef CORE_INT43_PIN
250+
void Encoder::isr43(void) ENCODER_ISR_ATTR { update(interruptArgs[43]); }
251+
#endif
252+
#ifdef CORE_INT44_PIN
253+
void Encoder::isr44(void) ENCODER_ISR_ATTR { update(interruptArgs[44]); }
254+
#endif
255+
#ifdef CORE_INT45_PIN
256+
void Encoder::isr45(void) ENCODER_ISR_ATTR { update(interruptArgs[45]); }
257+
#endif
258+
#ifdef CORE_INT46_PIN
259+
void Encoder::isr46(void) ENCODER_ISR_ATTR { update(interruptArgs[46]); }
260+
#endif
261+
#ifdef CORE_INT47_PIN
262+
void Encoder::isr47(void) ENCODER_ISR_ATTR { update(interruptArgs[47]); }
263+
#endif
264+
#ifdef CORE_INT48_PIN
265+
void Encoder::isr48(void) ENCODER_ISR_ATTR { update(interruptArgs[48]); }
266+
#endif
267+
#ifdef CORE_INT49_PIN
268+
void Encoder::isr49(void) ENCODER_ISR_ATTR { update(interruptArgs[49]); }
269+
#endif
270+
#ifdef CORE_INT50_PIN
271+
void Encoder::isr50(void) ENCODER_ISR_ATTR { update(interruptArgs[50]); }
272+
#endif
273+
#ifdef CORE_INT51_PIN
274+
void Encoder::isr51(void) ENCODER_ISR_ATTR { update(interruptArgs[51]); }
275+
#endif
276+
#ifdef CORE_INT52_PIN
277+
void Encoder::isr52(void) ENCODER_ISR_ATTR { update(interruptArgs[52]); }
278+
#endif
279+
#ifdef CORE_INT53_PIN
280+
void Encoder::isr53(void) ENCODER_ISR_ATTR { update(interruptArgs[53]); }
281+
#endif
282+
#ifdef CORE_INT54_PIN
283+
void Encoder::isr54(void) ENCODER_ISR_ATTR { update(interruptArgs[54]); }
284+
#endif
285+
#ifdef CORE_INT55_PIN
286+
void Encoder::isr55(void) ENCODER_ISR_ATTR { update(interruptArgs[55]); }
287+
#endif
288+
#ifdef CORE_INT56_PIN
289+
void Encoder::isr56(void) ENCODER_ISR_ATTR { update(interruptArgs[56]); }
290+
#endif
291+
#ifdef CORE_INT57_PIN
292+
void Encoder::isr57(void) ENCODER_ISR_ATTR { update(interruptArgs[57]); }
293+
#endif
294+
#ifdef CORE_INT58_PIN
295+
void Encoder::isr58(void) ENCODER_ISR_ATTR { update(interruptArgs[58]); }
296+
#endif
297+
#ifdef CORE_INT59_PIN
298+
void Encoder::isr59(void) ENCODER_ISR_ATTR { update(interruptArgs[59]); }
299+
#endif
300+
#endif

0 commit comments

Comments
 (0)