Skip to content

Commit 87c84c0

Browse files
committed
SPI: fix irqs > 32
1 parent dee5b72 commit 87c84c0

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

libraries/SPI/src/SPI.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ void SPIClass::init()
6262
return;
6363
interruptMode = SPI_IMODE_NONE;
6464
interruptSave = 0;
65-
interruptMask = 0;
65+
interruptMask_lo = 0;
66+
interruptMask_hi = 0;
6667
initialized = true;
6768
}
6869

@@ -91,7 +92,11 @@ void SPIClass::usingInterrupt(int interruptNumber)
9192
irqMap = (uint8_t*)malloc(EXTERNAL_NUM_INTERRUPTS);
9293
}
9394
interruptMode |= SPI_IMODE_EXTINT;
94-
interruptMask |= (1 << interruptNumber);
95+
if (interruptNumber < 32) {
96+
interruptMask_lo |= 1 << interruptNumber;
97+
} else {
98+
interruptMask_hi |= 1 << (interruptNumber - 32);
99+
}
95100
}
96101
}
97102

@@ -103,17 +108,21 @@ void SPIClass::notUsingInterrupt(int interruptNumber)
103108
if (interruptMode & SPI_IMODE_GLOBAL)
104109
return; // can't go back, as there is no reference count
105110

106-
interruptMask &= ~(1 << interruptNumber);
111+
if (interruptNumber < 32) {
112+
interruptMask_lo &= ~(1 << interruptNumber);
113+
} else {
114+
interruptMask_hi &= ~(1 << (interruptNumber - 32));
115+
}
107116

108-
if (interruptMask == 0) {
117+
if (interruptMask_lo == 0 && interruptMask_hi == 0) {
109118
interruptMode = SPI_IMODE_NONE;
110119
free(irqMap);
111120
irqMap = NULL;
112121
}
113122
}
114123

115124
void SPIClass::detachMaskedInterrupts() {
116-
unsigned long long temp = interruptMask;
125+
uint64_t temp = interruptMask_lo;
117126
uint8_t shift = 0;
118127
while (temp != 0) {
119128
if (temp & 1) {
@@ -124,10 +133,21 @@ void SPIClass::detachMaskedInterrupts() {
124133
temp = temp >> 1;
125134
shift++;
126135
}
136+
temp = interruptMask_hi;
137+
shift = 32;
138+
while (temp != 0) {
139+
if (temp & 1) {
140+
uint8_t* pin_ctrl_reg = getPINnCTRLregister(portToPortStruct(shift/8), shift%8);
141+
irqMap[shift] = *pin_ctrl_reg;
142+
*pin_ctrl_reg &= ~(PORT_ISC_gm);
143+
}
144+
temp = temp >> 1;
145+
shift++;
146+
}
127147
}
128148

129149
void SPIClass::reattachMaskedInterrupts() {
130-
unsigned long long temp = interruptMask;
150+
uint64_t temp = interruptMask_lo;
131151
uint8_t shift = 0;
132152
while (temp != 0) {
133153
if (temp & 1) {
@@ -137,6 +157,16 @@ void SPIClass::reattachMaskedInterrupts() {
137157
temp = temp >> 1;
138158
shift++;
139159
}
160+
temp = interruptMask_hi;
161+
shift = 32;
162+
while (temp != 0) {
163+
if (temp & 1) {
164+
uint8_t* pin_ctrl_reg = getPINnCTRLregister(portToPortStruct(shift/8), shift%8);
165+
*pin_ctrl_reg |= irqMap[shift];
166+
}
167+
temp = temp >> 1;
168+
shift++;
169+
}
140170
}
141171

142172
void SPIClass::beginTransaction(SPISettings settings)

libraries/SPI/src/SPI.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ class SPIClass {
182182
bool initialized;
183183
uint8_t interruptMode;
184184
char interruptSave;
185-
unsigned long long interruptMask;
185+
uint32_t interruptMask_lo;
186+
uint32_t interruptMask_hi;
186187
uint8_t* irqMap = NULL;
187188
};
188189

0 commit comments

Comments
 (0)