PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

Encoder.h 26KB

3 lat temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. /* Encoder Library, for measuring quadrature encoded signals
  2. * http://www.pjrc.com/teensy/td_libs_Encoder.html
  3. * Copyright (c) 2011,2013 PJRC.COM, LLC - Paul Stoffregen <paul@pjrc.com>
  4. *
  5. * Version 1.2 - fix -2 bug in C-only code
  6. * Version 1.1 - expand to support boards with up to 60 interrupts
  7. * Version 1.0 - initial release
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. */
  27. #ifndef Encoder_h_
  28. #define Encoder_h_
  29. #if defined(ARDUINO) && ARDUINO >= 100
  30. #include "Arduino.h"
  31. #elif defined(WIRING)
  32. #include "Wiring.h"
  33. #else
  34. #include "WProgram.h"
  35. #include "pins_arduino.h"
  36. #endif
  37. #include "utility/direct_pin_read.h"
  38. #if defined(ENCODER_USE_INTERRUPTS) || !defined(ENCODER_DO_NOT_USE_INTERRUPTS)
  39. #define ENCODER_USE_INTERRUPTS
  40. #define ENCODER_ARGLIST_SIZE CORE_NUM_INTERRUPT
  41. #include "utility/interrupt_pins.h"
  42. #ifdef ENCODER_OPTIMIZE_INTERRUPTS
  43. #include "utility/interrupt_config.h"
  44. #endif
  45. #else
  46. #define ENCODER_ARGLIST_SIZE 0
  47. #endif
  48. // All the data needed by interrupts is consolidated into this ugly struct
  49. // to facilitate assembly language optimizing of the speed critical update.
  50. // The assembly code uses auto-incrementing addressing modes, so the struct
  51. // must remain in exactly this order.
  52. typedef struct {
  53. volatile IO_REG_TYPE * pin1_register;
  54. volatile IO_REG_TYPE * pin2_register;
  55. IO_REG_TYPE pin1_bitmask;
  56. IO_REG_TYPE pin2_bitmask;
  57. uint8_t state;
  58. int32_t position;
  59. } Encoder_internal_state_t;
  60. class Encoder
  61. {
  62. public:
  63. Encoder(uint8_t pin1, uint8_t pin2) {
  64. #ifdef INPUT_PULLUP
  65. pinMode(pin1, INPUT_PULLUP);
  66. pinMode(pin2, INPUT_PULLUP);
  67. #else
  68. pinMode(pin1, INPUT);
  69. digitalWrite(pin1, HIGH);
  70. pinMode(pin2, INPUT);
  71. digitalWrite(pin2, HIGH);
  72. #endif
  73. encoder.pin1_register = PIN_TO_BASEREG(pin1);
  74. encoder.pin1_bitmask = PIN_TO_BITMASK(pin1);
  75. encoder.pin2_register = PIN_TO_BASEREG(pin2);
  76. encoder.pin2_bitmask = PIN_TO_BITMASK(pin2);
  77. encoder.position = 0;
  78. // allow time for a passive R-C filter to charge
  79. // through the pullup resistors, before reading
  80. // the initial state
  81. delayMicroseconds(2000);
  82. uint8_t s = 0;
  83. if (DIRECT_PIN_READ(encoder.pin1_register, encoder.pin1_bitmask)) s |= 1;
  84. if (DIRECT_PIN_READ(encoder.pin2_register, encoder.pin2_bitmask)) s |= 2;
  85. encoder.state = s;
  86. #ifdef ENCODER_USE_INTERRUPTS
  87. interrupts_in_use = attach_interrupt(pin1, &encoder);
  88. interrupts_in_use += attach_interrupt(pin2, &encoder);
  89. #endif
  90. //update_finishup(); // to force linker to include the code (does not work)
  91. }
  92. #ifdef ENCODER_USE_INTERRUPTS
  93. inline int32_t read() {
  94. if (interrupts_in_use < 2) {
  95. noInterrupts();
  96. update(&encoder);
  97. } else {
  98. noInterrupts();
  99. }
  100. int32_t ret = encoder.position;
  101. interrupts();
  102. return ret;
  103. }
  104. inline int32_t readAndReset() {
  105. if (interrupts_in_use < 2) {
  106. noInterrupts();
  107. update(&encoder);
  108. } else {
  109. noInterrupts();
  110. }
  111. int32_t ret = encoder.position;
  112. encoder.position = 0;
  113. interrupts();
  114. return ret;
  115. }
  116. inline void write(int32_t p) {
  117. noInterrupts();
  118. encoder.position = p;
  119. interrupts();
  120. }
  121. #else
  122. inline int32_t read() {
  123. update(&encoder);
  124. return encoder.position;
  125. }
  126. inline int32_t readAndReset() {
  127. update(&encoder);
  128. int32_t ret = encoder.position;
  129. encoder.position = 0;
  130. return ret;
  131. }
  132. inline void write(int32_t p) {
  133. encoder.position = p;
  134. }
  135. #endif
  136. private:
  137. Encoder_internal_state_t encoder;
  138. #ifdef ENCODER_USE_INTERRUPTS
  139. uint8_t interrupts_in_use;
  140. #endif
  141. public:
  142. static Encoder_internal_state_t * interruptArgs[ENCODER_ARGLIST_SIZE];
  143. // _______ _______
  144. // Pin1 ______| |_______| |______ Pin1
  145. // negative <--- _______ _______ __ --> positive
  146. // Pin2 __| |_______| |_______| Pin2
  147. // new new old old
  148. // pin2 pin1 pin2 pin1 Result
  149. // ---- ---- ---- ---- ------
  150. // 0 0 0 0 no movement
  151. // 0 0 0 1 +1
  152. // 0 0 1 0 -1
  153. // 0 0 1 1 +2 (assume pin1 edges only)
  154. // 0 1 0 0 -1
  155. // 0 1 0 1 no movement
  156. // 0 1 1 0 -2 (assume pin1 edges only)
  157. // 0 1 1 1 +1
  158. // 1 0 0 0 +1
  159. // 1 0 0 1 -2 (assume pin1 edges only)
  160. // 1 0 1 0 no movement
  161. // 1 0 1 1 -1
  162. // 1 1 0 0 +2 (assume pin1 edges only)
  163. // 1 1 0 1 -1
  164. // 1 1 1 0 +1
  165. // 1 1 1 1 no movement
  166. /*
  167. // Simple, easy-to-read "documentation" version :-)
  168. //
  169. void update(void) {
  170. uint8_t s = state & 3;
  171. if (digitalRead(pin1)) s |= 4;
  172. if (digitalRead(pin2)) s |= 8;
  173. switch (s) {
  174. case 0: case 5: case 10: case 15:
  175. break;
  176. case 1: case 7: case 8: case 14:
  177. position++; break;
  178. case 2: case 4: case 11: case 13:
  179. position--; break;
  180. case 3: case 12:
  181. position += 2; break;
  182. default:
  183. position -= 2; break;
  184. }
  185. state = (s >> 2);
  186. }
  187. */
  188. public:
  189. // update() is not meant to be called from outside Encoder,
  190. // but it is public to allow static interrupt routines.
  191. // DO NOT call update() directly from sketches.
  192. static void update(Encoder_internal_state_t *arg) {
  193. #if defined(__AVR__)
  194. // The compiler believes this is just 1 line of code, so
  195. // it will inline this function into each interrupt
  196. // handler. That's a tiny bit faster, but grows the code.
  197. // Especially when used with ENCODER_OPTIMIZE_INTERRUPTS,
  198. // the inline nature allows the ISR prologue and epilogue
  199. // to only save/restore necessary registers, for very nice
  200. // speed increase.
  201. asm volatile (
  202. "ld r30, X+" "\n\t"
  203. "ld r31, X+" "\n\t"
  204. "ld r24, Z" "\n\t" // r24 = pin1 input
  205. "ld r30, X+" "\n\t"
  206. "ld r31, X+" "\n\t"
  207. "ld r25, Z" "\n\t" // r25 = pin2 input
  208. "ld r30, X+" "\n\t" // r30 = pin1 mask
  209. "ld r31, X+" "\n\t" // r31 = pin2 mask
  210. "ld r22, X" "\n\t" // r22 = state
  211. "andi r22, 3" "\n\t"
  212. "and r24, r30" "\n\t"
  213. "breq L%=1" "\n\t" // if (pin1)
  214. "ori r22, 4" "\n\t" // state |= 4
  215. "L%=1:" "and r25, r31" "\n\t"
  216. "breq L%=2" "\n\t" // if (pin2)
  217. "ori r22, 8" "\n\t" // state |= 8
  218. "L%=2:" "ldi r30, lo8(pm(L%=table))" "\n\t"
  219. "ldi r31, hi8(pm(L%=table))" "\n\t"
  220. "add r30, r22" "\n\t"
  221. "adc r31, __zero_reg__" "\n\t"
  222. "asr r22" "\n\t"
  223. "asr r22" "\n\t"
  224. "st X+, r22" "\n\t" // store new state
  225. "ld r22, X+" "\n\t"
  226. "ld r23, X+" "\n\t"
  227. "ld r24, X+" "\n\t"
  228. "ld r25, X+" "\n\t"
  229. "ijmp" "\n\t" // jumps to update_finishup()
  230. // TODO move this table to another static function,
  231. // so it doesn't get needlessly duplicated. Easier
  232. // said than done, due to linker issues and inlining
  233. "L%=table:" "\n\t"
  234. "rjmp L%=end" "\n\t" // 0
  235. "rjmp L%=plus1" "\n\t" // 1
  236. "rjmp L%=minus1" "\n\t" // 2
  237. "rjmp L%=plus2" "\n\t" // 3
  238. "rjmp L%=minus1" "\n\t" // 4
  239. "rjmp L%=end" "\n\t" // 5
  240. "rjmp L%=minus2" "\n\t" // 6
  241. "rjmp L%=plus1" "\n\t" // 7
  242. "rjmp L%=plus1" "\n\t" // 8
  243. "rjmp L%=minus2" "\n\t" // 9
  244. "rjmp L%=end" "\n\t" // 10
  245. "rjmp L%=minus1" "\n\t" // 11
  246. "rjmp L%=plus2" "\n\t" // 12
  247. "rjmp L%=minus1" "\n\t" // 13
  248. "rjmp L%=plus1" "\n\t" // 14
  249. "rjmp L%=end" "\n\t" // 15
  250. "L%=minus2:" "\n\t"
  251. "subi r22, 2" "\n\t"
  252. "sbci r23, 0" "\n\t"
  253. "sbci r24, 0" "\n\t"
  254. "sbci r25, 0" "\n\t"
  255. "rjmp L%=store" "\n\t"
  256. "L%=minus1:" "\n\t"
  257. "subi r22, 1" "\n\t"
  258. "sbci r23, 0" "\n\t"
  259. "sbci r24, 0" "\n\t"
  260. "sbci r25, 0" "\n\t"
  261. "rjmp L%=store" "\n\t"
  262. "L%=plus2:" "\n\t"
  263. "subi r22, 254" "\n\t"
  264. "rjmp L%=z" "\n\t"
  265. "L%=plus1:" "\n\t"
  266. "subi r22, 255" "\n\t"
  267. "L%=z:" "sbci r23, 255" "\n\t"
  268. "sbci r24, 255" "\n\t"
  269. "sbci r25, 255" "\n\t"
  270. "L%=store:" "\n\t"
  271. "st -X, r25" "\n\t"
  272. "st -X, r24" "\n\t"
  273. "st -X, r23" "\n\t"
  274. "st -X, r22" "\n\t"
  275. "L%=end:" "\n"
  276. : : "x" (arg) : "r22", "r23", "r24", "r25", "r30", "r31");
  277. #else
  278. uint8_t p1val = DIRECT_PIN_READ(arg->pin1_register, arg->pin1_bitmask);
  279. uint8_t p2val = DIRECT_PIN_READ(arg->pin2_register, arg->pin2_bitmask);
  280. uint8_t state = arg->state & 3;
  281. if (p1val) state |= 4;
  282. if (p2val) state |= 8;
  283. arg->state = (state >> 2);
  284. switch (state) {
  285. case 1: case 7: case 8: case 14:
  286. arg->position++;
  287. return;
  288. case 2: case 4: case 11: case 13:
  289. arg->position--;
  290. return;
  291. case 3: case 12:
  292. arg->position += 2;
  293. return;
  294. case 6: case 9:
  295. arg->position -= 2;
  296. return;
  297. }
  298. #endif
  299. }
  300. private:
  301. /*
  302. #if defined(__AVR__)
  303. // TODO: this must be a no inline function
  304. // even noinline does not seem to solve difficult
  305. // problems with this. Oh well, it was only meant
  306. // to shrink code size - there's no performance
  307. // improvement in this, only code size reduction.
  308. __attribute__((noinline)) void update_finishup(void) {
  309. asm volatile (
  310. "ldi r30, lo8(pm(Ltable))" "\n\t"
  311. "ldi r31, hi8(pm(Ltable))" "\n\t"
  312. "Ltable:" "\n\t"
  313. "rjmp L%=end" "\n\t" // 0
  314. "rjmp L%=plus1" "\n\t" // 1
  315. "rjmp L%=minus1" "\n\t" // 2
  316. "rjmp L%=plus2" "\n\t" // 3
  317. "rjmp L%=minus1" "\n\t" // 4
  318. "rjmp L%=end" "\n\t" // 5
  319. "rjmp L%=minus2" "\n\t" // 6
  320. "rjmp L%=plus1" "\n\t" // 7
  321. "rjmp L%=plus1" "\n\t" // 8
  322. "rjmp L%=minus2" "\n\t" // 9
  323. "rjmp L%=end" "\n\t" // 10
  324. "rjmp L%=minus1" "\n\t" // 11
  325. "rjmp L%=plus2" "\n\t" // 12
  326. "rjmp L%=minus1" "\n\t" // 13
  327. "rjmp L%=plus1" "\n\t" // 14
  328. "rjmp L%=end" "\n\t" // 15
  329. "L%=minus2:" "\n\t"
  330. "subi r22, 2" "\n\t"
  331. "sbci r23, 0" "\n\t"
  332. "sbci r24, 0" "\n\t"
  333. "sbci r25, 0" "\n\t"
  334. "rjmp L%=store" "\n\t"
  335. "L%=minus1:" "\n\t"
  336. "subi r22, 1" "\n\t"
  337. "sbci r23, 0" "\n\t"
  338. "sbci r24, 0" "\n\t"
  339. "sbci r25, 0" "\n\t"
  340. "rjmp L%=store" "\n\t"
  341. "L%=plus2:" "\n\t"
  342. "subi r22, 254" "\n\t"
  343. "rjmp L%=z" "\n\t"
  344. "L%=plus1:" "\n\t"
  345. "subi r22, 255" "\n\t"
  346. "L%=z:" "sbci r23, 255" "\n\t"
  347. "sbci r24, 255" "\n\t"
  348. "sbci r25, 255" "\n\t"
  349. "L%=store:" "\n\t"
  350. "st -X, r25" "\n\t"
  351. "st -X, r24" "\n\t"
  352. "st -X, r23" "\n\t"
  353. "st -X, r22" "\n\t"
  354. "L%=end:" "\n"
  355. : : : "r22", "r23", "r24", "r25", "r30", "r31");
  356. }
  357. #endif
  358. */
  359. #ifdef ENCODER_USE_INTERRUPTS
  360. // this giant function is an unfortunate consequence of Arduino's
  361. // attachInterrupt function not supporting any way to pass a pointer
  362. // or other context to the attached function.
  363. static uint8_t attach_interrupt(uint8_t pin, Encoder_internal_state_t *state) {
  364. switch (pin) {
  365. #ifdef CORE_INT0_PIN
  366. case CORE_INT0_PIN:
  367. interruptArgs[0] = state;
  368. attachInterrupt(0, isr0, CHANGE);
  369. break;
  370. #endif
  371. #ifdef CORE_INT1_PIN
  372. case CORE_INT1_PIN:
  373. interruptArgs[1] = state;
  374. attachInterrupt(1, isr1, CHANGE);
  375. break;
  376. #endif
  377. #ifdef CORE_INT2_PIN
  378. case CORE_INT2_PIN:
  379. interruptArgs[2] = state;
  380. attachInterrupt(2, isr2, CHANGE);
  381. break;
  382. #endif
  383. #ifdef CORE_INT3_PIN
  384. case CORE_INT3_PIN:
  385. interruptArgs[3] = state;
  386. attachInterrupt(3, isr3, CHANGE);
  387. break;
  388. #endif
  389. #ifdef CORE_INT4_PIN
  390. case CORE_INT4_PIN:
  391. interruptArgs[4] = state;
  392. attachInterrupt(4, isr4, CHANGE);
  393. break;
  394. #endif
  395. #ifdef CORE_INT5_PIN
  396. case CORE_INT5_PIN:
  397. interruptArgs[5] = state;
  398. attachInterrupt(5, isr5, CHANGE);
  399. break;
  400. #endif
  401. #ifdef CORE_INT6_PIN
  402. case CORE_INT6_PIN:
  403. interruptArgs[6] = state;
  404. attachInterrupt(6, isr6, CHANGE);
  405. break;
  406. #endif
  407. #ifdef CORE_INT7_PIN
  408. case CORE_INT7_PIN:
  409. interruptArgs[7] = state;
  410. attachInterrupt(7, isr7, CHANGE);
  411. break;
  412. #endif
  413. #ifdef CORE_INT8_PIN
  414. case CORE_INT8_PIN:
  415. interruptArgs[8] = state;
  416. attachInterrupt(8, isr8, CHANGE);
  417. break;
  418. #endif
  419. #ifdef CORE_INT9_PIN
  420. case CORE_INT9_PIN:
  421. interruptArgs[9] = state;
  422. attachInterrupt(9, isr9, CHANGE);
  423. break;
  424. #endif
  425. #ifdef CORE_INT10_PIN
  426. case CORE_INT10_PIN:
  427. interruptArgs[10] = state;
  428. attachInterrupt(10, isr10, CHANGE);
  429. break;
  430. #endif
  431. #ifdef CORE_INT11_PIN
  432. case CORE_INT11_PIN:
  433. interruptArgs[11] = state;
  434. attachInterrupt(11, isr11, CHANGE);
  435. break;
  436. #endif
  437. #ifdef CORE_INT12_PIN
  438. case CORE_INT12_PIN:
  439. interruptArgs[12] = state;
  440. attachInterrupt(12, isr12, CHANGE);
  441. break;
  442. #endif
  443. #ifdef CORE_INT13_PIN
  444. case CORE_INT13_PIN:
  445. interruptArgs[13] = state;
  446. attachInterrupt(13, isr13, CHANGE);
  447. break;
  448. #endif
  449. #ifdef CORE_INT14_PIN
  450. case CORE_INT14_PIN:
  451. interruptArgs[14] = state;
  452. attachInterrupt(14, isr14, CHANGE);
  453. break;
  454. #endif
  455. #ifdef CORE_INT15_PIN
  456. case CORE_INT15_PIN:
  457. interruptArgs[15] = state;
  458. attachInterrupt(15, isr15, CHANGE);
  459. break;
  460. #endif
  461. #ifdef CORE_INT16_PIN
  462. case CORE_INT16_PIN:
  463. interruptArgs[16] = state;
  464. attachInterrupt(16, isr16, CHANGE);
  465. break;
  466. #endif
  467. #ifdef CORE_INT17_PIN
  468. case CORE_INT17_PIN:
  469. interruptArgs[17] = state;
  470. attachInterrupt(17, isr17, CHANGE);
  471. break;
  472. #endif
  473. #ifdef CORE_INT18_PIN
  474. case CORE_INT18_PIN:
  475. interruptArgs[18] = state;
  476. attachInterrupt(18, isr18, CHANGE);
  477. break;
  478. #endif
  479. #ifdef CORE_INT19_PIN
  480. case CORE_INT19_PIN:
  481. interruptArgs[19] = state;
  482. attachInterrupt(19, isr19, CHANGE);
  483. break;
  484. #endif
  485. #ifdef CORE_INT20_PIN
  486. case CORE_INT20_PIN:
  487. interruptArgs[20] = state;
  488. attachInterrupt(20, isr20, CHANGE);
  489. break;
  490. #endif
  491. #ifdef CORE_INT21_PIN
  492. case CORE_INT21_PIN:
  493. interruptArgs[21] = state;
  494. attachInterrupt(21, isr21, CHANGE);
  495. break;
  496. #endif
  497. #ifdef CORE_INT22_PIN
  498. case CORE_INT22_PIN:
  499. interruptArgs[22] = state;
  500. attachInterrupt(22, isr22, CHANGE);
  501. break;
  502. #endif
  503. #ifdef CORE_INT23_PIN
  504. case CORE_INT23_PIN:
  505. interruptArgs[23] = state;
  506. attachInterrupt(23, isr23, CHANGE);
  507. break;
  508. #endif
  509. #ifdef CORE_INT24_PIN
  510. case CORE_INT24_PIN:
  511. interruptArgs[24] = state;
  512. attachInterrupt(24, isr24, CHANGE);
  513. break;
  514. #endif
  515. #ifdef CORE_INT25_PIN
  516. case CORE_INT25_PIN:
  517. interruptArgs[25] = state;
  518. attachInterrupt(25, isr25, CHANGE);
  519. break;
  520. #endif
  521. #ifdef CORE_INT26_PIN
  522. case CORE_INT26_PIN:
  523. interruptArgs[26] = state;
  524. attachInterrupt(26, isr26, CHANGE);
  525. break;
  526. #endif
  527. #ifdef CORE_INT27_PIN
  528. case CORE_INT27_PIN:
  529. interruptArgs[27] = state;
  530. attachInterrupt(27, isr27, CHANGE);
  531. break;
  532. #endif
  533. #ifdef CORE_INT28_PIN
  534. case CORE_INT28_PIN:
  535. interruptArgs[28] = state;
  536. attachInterrupt(28, isr28, CHANGE);
  537. break;
  538. #endif
  539. #ifdef CORE_INT29_PIN
  540. case CORE_INT29_PIN:
  541. interruptArgs[29] = state;
  542. attachInterrupt(29, isr29, CHANGE);
  543. break;
  544. #endif
  545. #ifdef CORE_INT30_PIN
  546. case CORE_INT30_PIN:
  547. interruptArgs[30] = state;
  548. attachInterrupt(30, isr30, CHANGE);
  549. break;
  550. #endif
  551. #ifdef CORE_INT31_PIN
  552. case CORE_INT31_PIN:
  553. interruptArgs[31] = state;
  554. attachInterrupt(31, isr31, CHANGE);
  555. break;
  556. #endif
  557. #ifdef CORE_INT32_PIN
  558. case CORE_INT32_PIN:
  559. interruptArgs[32] = state;
  560. attachInterrupt(32, isr32, CHANGE);
  561. break;
  562. #endif
  563. #ifdef CORE_INT33_PIN
  564. case CORE_INT33_PIN:
  565. interruptArgs[33] = state;
  566. attachInterrupt(33, isr33, CHANGE);
  567. break;
  568. #endif
  569. #ifdef CORE_INT34_PIN
  570. case CORE_INT34_PIN:
  571. interruptArgs[34] = state;
  572. attachInterrupt(34, isr34, CHANGE);
  573. break;
  574. #endif
  575. #ifdef CORE_INT35_PIN
  576. case CORE_INT35_PIN:
  577. interruptArgs[35] = state;
  578. attachInterrupt(35, isr35, CHANGE);
  579. break;
  580. #endif
  581. #ifdef CORE_INT36_PIN
  582. case CORE_INT36_PIN:
  583. interruptArgs[36] = state;
  584. attachInterrupt(36, isr36, CHANGE);
  585. break;
  586. #endif
  587. #ifdef CORE_INT37_PIN
  588. case CORE_INT37_PIN:
  589. interruptArgs[37] = state;
  590. attachInterrupt(37, isr37, CHANGE);
  591. break;
  592. #endif
  593. #ifdef CORE_INT38_PIN
  594. case CORE_INT38_PIN:
  595. interruptArgs[38] = state;
  596. attachInterrupt(38, isr38, CHANGE);
  597. break;
  598. #endif
  599. #ifdef CORE_INT39_PIN
  600. case CORE_INT39_PIN:
  601. interruptArgs[39] = state;
  602. attachInterrupt(39, isr39, CHANGE);
  603. break;
  604. #endif
  605. #ifdef CORE_INT40_PIN
  606. case CORE_INT40_PIN:
  607. interruptArgs[40] = state;
  608. attachInterrupt(40, isr40, CHANGE);
  609. break;
  610. #endif
  611. #ifdef CORE_INT41_PIN
  612. case CORE_INT41_PIN:
  613. interruptArgs[41] = state;
  614. attachInterrupt(41, isr41, CHANGE);
  615. break;
  616. #endif
  617. #ifdef CORE_INT42_PIN
  618. case CORE_INT42_PIN:
  619. interruptArgs[42] = state;
  620. attachInterrupt(42, isr42, CHANGE);
  621. break;
  622. #endif
  623. #ifdef CORE_INT43_PIN
  624. case CORE_INT43_PIN:
  625. interruptArgs[43] = state;
  626. attachInterrupt(43, isr43, CHANGE);
  627. break;
  628. #endif
  629. #ifdef CORE_INT44_PIN
  630. case CORE_INT44_PIN:
  631. interruptArgs[44] = state;
  632. attachInterrupt(44, isr44, CHANGE);
  633. break;
  634. #endif
  635. #ifdef CORE_INT45_PIN
  636. case CORE_INT45_PIN:
  637. interruptArgs[45] = state;
  638. attachInterrupt(45, isr45, CHANGE);
  639. break;
  640. #endif
  641. #ifdef CORE_INT46_PIN
  642. case CORE_INT46_PIN:
  643. interruptArgs[46] = state;
  644. attachInterrupt(46, isr46, CHANGE);
  645. break;
  646. #endif
  647. #ifdef CORE_INT47_PIN
  648. case CORE_INT47_PIN:
  649. interruptArgs[47] = state;
  650. attachInterrupt(47, isr47, CHANGE);
  651. break;
  652. #endif
  653. #ifdef CORE_INT48_PIN
  654. case CORE_INT48_PIN:
  655. interruptArgs[48] = state;
  656. attachInterrupt(48, isr48, CHANGE);
  657. break;
  658. #endif
  659. #ifdef CORE_INT49_PIN
  660. case CORE_INT49_PIN:
  661. interruptArgs[49] = state;
  662. attachInterrupt(49, isr49, CHANGE);
  663. break;
  664. #endif
  665. #ifdef CORE_INT50_PIN
  666. case CORE_INT50_PIN:
  667. interruptArgs[50] = state;
  668. attachInterrupt(50, isr50, CHANGE);
  669. break;
  670. #endif
  671. #ifdef CORE_INT51_PIN
  672. case CORE_INT51_PIN:
  673. interruptArgs[51] = state;
  674. attachInterrupt(51, isr51, CHANGE);
  675. break;
  676. #endif
  677. #ifdef CORE_INT52_PIN
  678. case CORE_INT52_PIN:
  679. interruptArgs[52] = state;
  680. attachInterrupt(52, isr52, CHANGE);
  681. break;
  682. #endif
  683. #ifdef CORE_INT53_PIN
  684. case CORE_INT53_PIN:
  685. interruptArgs[53] = state;
  686. attachInterrupt(53, isr53, CHANGE);
  687. break;
  688. #endif
  689. #ifdef CORE_INT54_PIN
  690. case CORE_INT54_PIN:
  691. interruptArgs[54] = state;
  692. attachInterrupt(54, isr54, CHANGE);
  693. break;
  694. #endif
  695. #ifdef CORE_INT55_PIN
  696. case CORE_INT55_PIN:
  697. interruptArgs[55] = state;
  698. attachInterrupt(55, isr55, CHANGE);
  699. break;
  700. #endif
  701. #ifdef CORE_INT56_PIN
  702. case CORE_INT56_PIN:
  703. interruptArgs[56] = state;
  704. attachInterrupt(56, isr56, CHANGE);
  705. break;
  706. #endif
  707. #ifdef CORE_INT57_PIN
  708. case CORE_INT57_PIN:
  709. interruptArgs[57] = state;
  710. attachInterrupt(57, isr57, CHANGE);
  711. break;
  712. #endif
  713. #ifdef CORE_INT58_PIN
  714. case CORE_INT58_PIN:
  715. interruptArgs[58] = state;
  716. attachInterrupt(58, isr58, CHANGE);
  717. break;
  718. #endif
  719. #ifdef CORE_INT59_PIN
  720. case CORE_INT59_PIN:
  721. interruptArgs[59] = state;
  722. attachInterrupt(59, isr59, CHANGE);
  723. break;
  724. #endif
  725. default:
  726. return 0;
  727. }
  728. return 1;
  729. }
  730. #endif // ENCODER_USE_INTERRUPTS
  731. #if defined(ENCODER_USE_INTERRUPTS) && !defined(ENCODER_OPTIMIZE_INTERRUPTS)
  732. #ifdef CORE_INT0_PIN
  733. static void isr0(void) { update(interruptArgs[0]); }
  734. #endif
  735. #ifdef CORE_INT1_PIN
  736. static void isr1(void) { update(interruptArgs[1]); }
  737. #endif
  738. #ifdef CORE_INT2_PIN
  739. static void isr2(void) { update(interruptArgs[2]); }
  740. #endif
  741. #ifdef CORE_INT3_PIN
  742. static void isr3(void) { update(interruptArgs[3]); }
  743. #endif
  744. #ifdef CORE_INT4_PIN
  745. static void isr4(void) { update(interruptArgs[4]); }
  746. #endif
  747. #ifdef CORE_INT5_PIN
  748. static void isr5(void) { update(interruptArgs[5]); }
  749. #endif
  750. #ifdef CORE_INT6_PIN
  751. static void isr6(void) { update(interruptArgs[6]); }
  752. #endif
  753. #ifdef CORE_INT7_PIN
  754. static void isr7(void) { update(interruptArgs[7]); }
  755. #endif
  756. #ifdef CORE_INT8_PIN
  757. static void isr8(void) { update(interruptArgs[8]); }
  758. #endif
  759. #ifdef CORE_INT9_PIN
  760. static void isr9(void) { update(interruptArgs[9]); }
  761. #endif
  762. #ifdef CORE_INT10_PIN
  763. static void isr10(void) { update(interruptArgs[10]); }
  764. #endif
  765. #ifdef CORE_INT11_PIN
  766. static void isr11(void) { update(interruptArgs[11]); }
  767. #endif
  768. #ifdef CORE_INT12_PIN
  769. static void isr12(void) { update(interruptArgs[12]); }
  770. #endif
  771. #ifdef CORE_INT13_PIN
  772. static void isr13(void) { update(interruptArgs[13]); }
  773. #endif
  774. #ifdef CORE_INT14_PIN
  775. static void isr14(void) { update(interruptArgs[14]); }
  776. #endif
  777. #ifdef CORE_INT15_PIN
  778. static void isr15(void) { update(interruptArgs[15]); }
  779. #endif
  780. #ifdef CORE_INT16_PIN
  781. static void isr16(void) { update(interruptArgs[16]); }
  782. #endif
  783. #ifdef CORE_INT17_PIN
  784. static void isr17(void) { update(interruptArgs[17]); }
  785. #endif
  786. #ifdef CORE_INT18_PIN
  787. static void isr18(void) { update(interruptArgs[18]); }
  788. #endif
  789. #ifdef CORE_INT19_PIN
  790. static void isr19(void) { update(interruptArgs[19]); }
  791. #endif
  792. #ifdef CORE_INT20_PIN
  793. static void isr20(void) { update(interruptArgs[20]); }
  794. #endif
  795. #ifdef CORE_INT21_PIN
  796. static void isr21(void) { update(interruptArgs[21]); }
  797. #endif
  798. #ifdef CORE_INT22_PIN
  799. static void isr22(void) { update(interruptArgs[22]); }
  800. #endif
  801. #ifdef CORE_INT23_PIN
  802. static void isr23(void) { update(interruptArgs[23]); }
  803. #endif
  804. #ifdef CORE_INT24_PIN
  805. static void isr24(void) { update(interruptArgs[24]); }
  806. #endif
  807. #ifdef CORE_INT25_PIN
  808. static void isr25(void) { update(interruptArgs[25]); }
  809. #endif
  810. #ifdef CORE_INT26_PIN
  811. static void isr26(void) { update(interruptArgs[26]); }
  812. #endif
  813. #ifdef CORE_INT27_PIN
  814. static void isr27(void) { update(interruptArgs[27]); }
  815. #endif
  816. #ifdef CORE_INT28_PIN
  817. static void isr28(void) { update(interruptArgs[28]); }
  818. #endif
  819. #ifdef CORE_INT29_PIN
  820. static void isr29(void) { update(interruptArgs[29]); }
  821. #endif
  822. #ifdef CORE_INT30_PIN
  823. static void isr30(void) { update(interruptArgs[30]); }
  824. #endif
  825. #ifdef CORE_INT31_PIN
  826. static void isr31(void) { update(interruptArgs[31]); }
  827. #endif
  828. #ifdef CORE_INT32_PIN
  829. static void isr32(void) { update(interruptArgs[32]); }
  830. #endif
  831. #ifdef CORE_INT33_PIN
  832. static void isr33(void) { update(interruptArgs[33]); }
  833. #endif
  834. #ifdef CORE_INT34_PIN
  835. static void isr34(void) { update(interruptArgs[34]); }
  836. #endif
  837. #ifdef CORE_INT35_PIN
  838. static void isr35(void) { update(interruptArgs[35]); }
  839. #endif
  840. #ifdef CORE_INT36_PIN
  841. static void isr36(void) { update(interruptArgs[36]); }
  842. #endif
  843. #ifdef CORE_INT37_PIN
  844. static void isr37(void) { update(interruptArgs[37]); }
  845. #endif
  846. #ifdef CORE_INT38_PIN
  847. static void isr38(void) { update(interruptArgs[38]); }
  848. #endif
  849. #ifdef CORE_INT39_PIN
  850. static void isr39(void) { update(interruptArgs[39]); }
  851. #endif
  852. #ifdef CORE_INT40_PIN
  853. static void isr40(void) { update(interruptArgs[40]); }
  854. #endif
  855. #ifdef CORE_INT41_PIN
  856. static void isr41(void) { update(interruptArgs[41]); }
  857. #endif
  858. #ifdef CORE_INT42_PIN
  859. static void isr42(void) { update(interruptArgs[42]); }
  860. #endif
  861. #ifdef CORE_INT43_PIN
  862. static void isr43(void) { update(interruptArgs[43]); }
  863. #endif
  864. #ifdef CORE_INT44_PIN
  865. static void isr44(void) { update(interruptArgs[44]); }
  866. #endif
  867. #ifdef CORE_INT45_PIN
  868. static void isr45(void) { update(interruptArgs[45]); }
  869. #endif
  870. #ifdef CORE_INT46_PIN
  871. static void isr46(void) { update(interruptArgs[46]); }
  872. #endif
  873. #ifdef CORE_INT47_PIN
  874. static void isr47(void) { update(interruptArgs[47]); }
  875. #endif
  876. #ifdef CORE_INT48_PIN
  877. static void isr48(void) { update(interruptArgs[48]); }
  878. #endif
  879. #ifdef CORE_INT49_PIN
  880. static void isr49(void) { update(interruptArgs[49]); }
  881. #endif
  882. #ifdef CORE_INT50_PIN
  883. static void isr50(void) { update(interruptArgs[50]); }
  884. #endif
  885. #ifdef CORE_INT51_PIN
  886. static void isr51(void) { update(interruptArgs[51]); }
  887. #endif
  888. #ifdef CORE_INT52_PIN
  889. static void isr52(void) { update(interruptArgs[52]); }
  890. #endif
  891. #ifdef CORE_INT53_PIN
  892. static void isr53(void) { update(interruptArgs[53]); }
  893. #endif
  894. #ifdef CORE_INT54_PIN
  895. static void isr54(void) { update(interruptArgs[54]); }
  896. #endif
  897. #ifdef CORE_INT55_PIN
  898. static void isr55(void) { update(interruptArgs[55]); }
  899. #endif
  900. #ifdef CORE_INT56_PIN
  901. static void isr56(void) { update(interruptArgs[56]); }
  902. #endif
  903. #ifdef CORE_INT57_PIN
  904. static void isr57(void) { update(interruptArgs[57]); }
  905. #endif
  906. #ifdef CORE_INT58_PIN
  907. static void isr58(void) { update(interruptArgs[58]); }
  908. #endif
  909. #ifdef CORE_INT59_PIN
  910. static void isr59(void) { update(interruptArgs[59]); }
  911. #endif
  912. #endif
  913. };
  914. #if defined(ENCODER_USE_INTERRUPTS) && defined(ENCODER_OPTIMIZE_INTERRUPTS)
  915. #if defined(__AVR__)
  916. #if defined(INT0_vect) && CORE_NUM_INTERRUPT > 0
  917. ISR(INT0_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(0)]); }
  918. #endif
  919. #if defined(INT1_vect) && CORE_NUM_INTERRUPT > 1
  920. ISR(INT1_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(1)]); }
  921. #endif
  922. #if defined(INT2_vect) && CORE_NUM_INTERRUPT > 2
  923. ISR(INT2_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(2)]); }
  924. #endif
  925. #if defined(INT3_vect) && CORE_NUM_INTERRUPT > 3
  926. ISR(INT3_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(3)]); }
  927. #endif
  928. #if defined(INT4_vect) && CORE_NUM_INTERRUPT > 4
  929. ISR(INT4_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(4)]); }
  930. #endif
  931. #if defined(INT5_vect) && CORE_NUM_INTERRUPT > 5
  932. ISR(INT5_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(5)]); }
  933. #endif
  934. #if defined(INT6_vect) && CORE_NUM_INTERRUPT > 6
  935. ISR(INT6_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(6)]); }
  936. #endif
  937. #if defined(INT7_vect) && CORE_NUM_INTERRUPT > 7
  938. ISR(INT7_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(7)]); }
  939. #endif
  940. #endif // AVR
  941. #if defined(attachInterrupt)
  942. // Don't intefere with other libraries or sketch use of attachInterrupt()
  943. // https://github.com/PaulStoffregen/Encoder/issues/8
  944. #undef attachInterrupt
  945. #endif
  946. #endif // ENCODER_OPTIMIZE_INTERRUPTS
  947. #endif