Control Surface pin-t-adl
MIDI Control Surface library for Arduino
AHEncoder.ipp
Go to the documentation of this file.
1#pragma once
2
3#include "AHEncoder.hpp"
4
6
7template <unsigned NumISR>
8auto AHEncoder::get_isr(unsigned interrupt) -> isr_func_t {
9 return interrupt == NumISR - 1
11 : get_isr<NumISR - 1>(interrupt); // Compile-time tail recursion
12}
13
14template <>
15inline auto AHEncoder::get_isr<0>(unsigned) -> isr_func_t {
16 return nullptr;
17}
18
19inline int32_t AHEncoder::read() {
20 if (interrupts_in_use < 2)
21 update();
22 return position.get();
23}
24
25inline int32_t AHEncoder::readAndReset(int32_t newpos) {
26 if (interrupts_in_use < 2)
27 update();
28 return position.xchg(newpos);
29}
30
31inline void AHEncoder::write(int32_t p) {
32 if (interrupts_in_use < 2)
33 update();
34 position.set(p);
35}
36
37// _______ _______
38// Pin1 ______| |_______| |______ Pin1
39// negative <--- _______ _______ __ --> positive
40// Pin2 __| |_______| |_______| Pin2
41
42// new new old old
43// pin2 pin1 pin2 pin1 Result
44// ---- ---- ---- ---- ------
45// 0 0 0 0 no movement
46// 0 0 0 1 +1
47// 0 0 1 0 -1
48// 0 0 1 1 +2 (assume pin1 edges only)
49// 0 1 0 0 -1
50// 0 1 0 1 no movement
51// 0 1 1 0 -2 (assume pin1 edges only)
52// 0 1 1 1 +1
53// 1 0 0 0 +1
54// 1 0 0 1 -2 (assume pin1 edges only)
55// 1 0 1 0 no movement
56// 1 0 1 1 -1
57// 1 1 0 0 +2 (assume pin1 edges only)
58// 1 1 0 1 -1
59// 1 1 1 0 +1
60// 1 1 1 1 no movement
61
62inline void AHEncoder::update() {
63 uint8_t s = state & 0b11;
64 if (direct_pins[0].read())
65 s |= 4;
66 if (direct_pins[1].read())
67 s |= 8;
68 state = (s >> 2);
69 switch (s) {
70 case 1:
71 case 7:
72 case 8:
73 case 14: position.add_isr(1); return;
74 case 2:
75 case 4:
76 case 11:
77 case 13: position.add_isr(-1); return;
78 case 3:
79 case 12: position.add_isr(2); return;
80 case 6:
81 case 9: position.add_isr(-2); return;
82 }
83}
84
#define CS_ENCODER_ISR_ATTR
Definition: AHEncoder.hpp:13
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
uint8_t state
Definition: AHEncoder.hpp:82
AtomicPosition< int32_t > position
Definition: AHEncoder.hpp:84
void(*)() isr_func_t
The type of a handler function.
Definition: AHEncoder.hpp:70
static isr_func_t get_isr(unsigned interrupt)
Get a pointer to the interrupt handler function for the given interrupt.
static AHEncoder * instance_table[NUM_DIGITAL_PINS]
Array of pointers to all instances with active interrupts.
Definition: AHEncoder.hpp:91
void write(int32_t p)
Set the absolute position to the given value.
Definition: AHEncoder.ipp:31
uint8_t interrupts_in_use
Definition: AHEncoder.hpp:81
int32_t read()
Read the current absolute position of the encoder.
Definition: AHEncoder.ipp:19
int32_t readAndReset(int32_t newpos=0)
Read the current absolute position of the encoder and reset it to zero afterwards.
Definition: AHEncoder.ipp:25
DirectPinRead direct_pins[2]
Definition: AHEncoder.hpp:83
void update()
Private handler function that is called from the ISR.
Definition: AHEncoder.ipp:62
type xchg(type other)
void set(type other)
void add_isr(type other)
type get() const