Skip to content

Commit 8c51bb7

Browse files
Clarify restoration of interrupt flag as needed.
1 parent 4a8c08b commit 8c51bb7

File tree

4 files changed

+15
-12
lines changed

4 files changed

+15
-12
lines changed

BasicEncoder.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ class BasicEncoder {
3838
}
3939
~BasicEncoder() {}
4040

41-
void begin() {
42-
reset();
43-
}
41+
void begin() { reset(); }
4442

4543
int8_t pin_state() {
4644
int8_t state_now = 0;
@@ -90,7 +88,7 @@ class BasicEncoder {
9088

9189
// Read changes frequently enough that overflows cannot happen.
9290
int8_t get_change() {
93-
uint8_t sreg = SREG;
91+
uint8_t sreg = SREG; // save the current interrupt enable flag
9492
noInterrupts();
9593
int8_t change = m_change;
9694
// the switch statement can make better code because only optimised
@@ -108,24 +106,24 @@ class BasicEncoder {
108106
m_change = 0;
109107
break;
110108
}
111-
SREG = sreg;
109+
SREG = sreg; // restore the previous interrupt enable flag state
112110
return change;
113111
}
114112

115113
int get_count() {
116-
uint8_t sreg = SREG;
114+
uint8_t sreg = SREG; // save the current interrupt enable flag
117115
noInterrupts();
118116
int count = m_steps / m_steps_per_count;
119-
SREG = sreg;
117+
SREG = sreg; // restore the previous interrupt enable flag state
120118
return count;
121119
}
122120

123121
void reset() {
124-
uint8_t sreg = SREG;
122+
uint8_t sreg = SREG; // save the current interrupt enable flag
125123
noInterrupts();
126124
m_steps = 0;
127125
m_change = 0;
128-
SREG = sreg;
126+
SREG = sreg; // restore the previous interrupt enable flag state
129127
}
130128

131129
void set_reverse() { m_reversed = true; }

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,8 @@ https://www.mikrocontroller.net/articles/Drehgeber
130130

131131
The library should work with multiple encoder instances. There is an example `two-encoders` that demonstrates this using a timer interrupt for polling. Pin-change interrupt implementations may also be fine if the encoders are in different groups though that has not yet been tested.
132132

133+
## A note about interrupts
134+
135+
In a few places, the code needs to disable interrupts to ensure that data values are not corrupted. Immediately before a call to `noInterrupts()`, the current value of the status register, `SREG`, is saved into a local variable. Once the critical code section is complete, the saved state of the interrupt enable flag is restored by simply copying the saved value of the status register back. The other flags are not critical in this context.
136+
137+
This method is used rather than simply enabling interrupts because interrupts may already have been disabled at the time the function is called and to re-enable interrupts when they should not be enabled might cause hard to track bugs in the user code.

examples/using-pin-change/using-pin-change.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ void pciSetup(byte pin) // Setup pin change interupt on pin
3737
}
3838

3939
void setup_encoders(int a, int b) {
40-
uint8_t old_sreg = SREG;
40+
uint8_t old_sreg = SREG; // save the current interrupt enable flag
4141
noInterrupts();
4242
pciSetup(a);
4343
pciSetup(b);
4444
encoder.reset();
45-
SREG = old_sreg;
45+
SREG = old_sreg; // restore the previous interrupt enable flag state
4646
}
4747

4848
ISR(PCINT2_vect) // pin change interrupt for D0 to D7

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "BasicEncoder",
3-
"version": "1.1.1",
3+
"version": "1.1.2",
44
"description": "BasicEncoder counts pulses from one or more simple rotary encoder control knobs.",
55
"keywords": "encoder, rotary encoder, quadrature",
66
"repository":

0 commit comments

Comments
 (0)