3 bool knob_prev_a = false;
4 static knob_report_t knob_report = {.dir = 0, .phase = 0};
7 // I use pins D1 (ISR1) & D4 for a knob.
9 // Set pin mode for D4 as input.
10 DDRD &= ~(0UL << ENCODER_PIN_2);
12 // Enable internal pull-up for D4.
13 // This is done by "writing" 1 to a pin that has its mode set to input.
14 PORTD |= (1 << ENCODER_PIN_2);
16 // Enable interrupt for D1
17 // For more info on the below flags see this awesome section 11.1 (pages 89-90) here:
18 // https://cdn-shop.adafruit.com/datasheets/atmel-7766-8-bit-avr-atmega16u4-32u4_datasheet.pdf
19 // Set pin mode & pull-up.
20 DDRD &= ~(0UL << ENCODER_PIN_1);
21 PORTD |= (1UL << ENCODER_PIN_1);
24 EICRA |= 0b00010000; // 0b01 - any edge
30 bool a = PIND & (1 << ENCODER_PIN_1);
32 if (knob_prev_a != a) {
33 // "A" channel has REALLY changed.
34 knob_report.phase = a;
36 bool b = PIND & (1 << ENCODER_PIN_2);
38 // Halfway through CCW rotation (A == B)
40 // +---YOU ARE HERE (A=1, B=1)
41 // | +---OR HERE (A=0, B=0)
48 // Halfway through CW rotation (A != B)
50 // +---YOU ARE HERE (A=1, B=0)
51 // | +---OR HERE (A=0, B=1)
54 // A: _____/^^^^^\_____
55 // B: ________/^^^^^\__
61 knob_report_t knob_report_read(void) {
62 // Return knob report.
66 void knob_report_reset(void) {
67 // Call this ASAP once you've processed the previous knob report.
68 // TODO: This should probably be called within `knob_report_read`.
70 knob_report.phase = 0;