Skip to content

Commit 19a2415

Browse files
Fix interrupt masking on Arduino Due
1 parent 7d514e6 commit 19a2415

File tree

2 files changed

+43
-28
lines changed

2 files changed

+43
-28
lines changed

libraries/SPI/SPI.cpp

+37-25
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,11 @@ void SPIClass::init() {
4747
if (initialized)
4848
return;
4949
interruptMode = 0;
50-
interruptMask = 0;
5150
interruptSave = 0;
51+
interruptMask[0] = 0;
52+
interruptMask[1] = 0;
53+
interruptMask[2] = 0;
54+
interruptMask[3] = 0;
5255
initCb();
5356
SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS);
5457
SPI_Enable(spi);
@@ -59,9 +62,11 @@ void SPIClass::init() {
5962
#define interruptsStatus() __interruptsStatus()
6063
static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
6164
static inline unsigned char __interruptsStatus(void) {
62-
unsigned int primask;
65+
unsigned int primask, faultmask;
6366
asm volatile ("mrs %0, primask" : "=r" (primask));
6467
if (primask) return 0;
68+
asm volatile ("mrs %0, faultmask" : "=r" (faultmask));
69+
if (faultmask) return 0;
6570
return 1;
6671
}
6772
#endif
@@ -72,37 +77,41 @@ void SPIClass::usingInterrupt(uint8_t interruptNumber)
7277

7378
irestore = interruptsStatus();
7479
noInterrupts();
75-
if (interruptMode < 2) {
80+
if (interruptMode < 16) {
7681
if (interruptNumber > NUM_DIGITAL_PINS) {
77-
interruptMode = 2;
82+
interruptMode = 16;
7883
} else {
79-
uint8_t imask = interruptMask;
8084
Pio *pio = g_APinDescription[interruptNumber].pPort;
85+
uint32_t mask = g_APinDescription[interruptNumber].ulPin;
8186
if (pio == PIOA) {
82-
imask |= 1;
87+
interruptMode |= 1;
88+
interruptMask[0] |= mask;
8389
} else if (pio == PIOB) {
84-
imask |= 2;
90+
interruptMode |= 2;
91+
interruptMask[1] |= mask;
8592
} else if (pio == PIOC) {
86-
imask |= 4;
93+
interruptMode |= 4;
94+
interruptMask[2] |= mask;
8795
} else if (pio == PIOD) {
88-
imask |= 8;
96+
interruptMode |= 8;
97+
interruptMask[3] |= mask;
98+
} else {
99+
interruptMode = 16;
89100
}
90-
interruptMask = imask;
91-
interruptMode = 1;
92101
}
93102
}
94103
if (irestore) interrupts();
95104
}
96105

97106
void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
98107
{
99-
if (interruptMode > 0) {
100-
if (interruptMode == 1) {
101-
uint8_t imask = interruptMask;
102-
if (imask & 1) NVIC_DisableIRQ(PIOA_IRQn);
103-
if (imask & 2) NVIC_DisableIRQ(PIOB_IRQn);
104-
if (imask & 4) NVIC_DisableIRQ(PIOC_IRQn);
105-
if (imask & 8) NVIC_DisableIRQ(PIOD_IRQn);
108+
uint8_t mode = interruptMode;
109+
if (mode > 0) {
110+
if (mode < 16) {
111+
if (mode & 1) PIOA->PIO_IDR = interruptMask[0];
112+
if (mode & 2) PIOB->PIO_IDR = interruptMask[1];
113+
if (mode & 4) PIOC->PIO_IDR = interruptMask[2];
114+
if (mode & 8) PIOD->PIO_IDR = interruptMask[3];
106115
} else {
107116
interruptSave = interruptsStatus();
108117
noInterrupts();
@@ -111,17 +120,20 @@ void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
111120
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(pin);
112121
bitOrder[ch] = settings.border;
113122
SPI_ConfigureNPCS(spi, ch, settings.config);
123+
//setBitOrder(pin, settings.border);
124+
//setDataMode(pin, settings.datamode);
125+
//setClockDivider(pin, settings.clockdiv);
114126
}
115127

116128
void SPIClass::endTransaction(void)
117129
{
118-
if (interruptMode > 0) {
119-
if (interruptMode == 1) {
120-
uint8_t imask = interruptMask;
121-
if (imask & 1) NVIC_EnableIRQ(PIOA_IRQn);
122-
if (imask & 2) NVIC_EnableIRQ(PIOB_IRQn);
123-
if (imask & 4) NVIC_EnableIRQ(PIOC_IRQn);
124-
if (imask & 8) NVIC_EnableIRQ(PIOD_IRQn);
130+
uint8_t mode = interruptMode;
131+
if (mode > 0) {
132+
if (mode < 16) {
133+
if (mode & 1) PIOA->PIO_IER = interruptMask[0];
134+
if (mode & 2) PIOB->PIO_IER = interruptMask[1];
135+
if (mode & 4) PIOC->PIO_IER = interruptMask[2];
136+
if (mode & 8) PIOD->PIO_IER = interruptMask[3];
125137
} else {
126138
if (interruptSave) interrupts();
127139
}

libraries/SPI/SPI.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,11 @@ class SPISettings {
316316
}
317317
}
318318
config = (dataMode & 3) | SPI_CSR_CSAAT | SPI_CSR_SCBR(div) | SPI_CSR_DLYBCT(1);
319+
//clockdiv = div;
320+
//datamode = dataMode;
319321
}
320322
uint32_t config;
323+
//uint8_t clockdiv, datamode;
321324
BitOrder border;
322325
friend class SPIClass;
323326
};
@@ -370,9 +373,9 @@ class SPIClass {
370373
uint32_t mode[SPI_CHANNELS_NUM];
371374
void (*initCb)(void);
372375
bool initialized;
373-
uint8_t interruptMode; // 0=none, 1=mask, 2=global
374-
uint8_t interruptMask; // bits 0:3=pin change
375-
uint8_t interruptSave; // temp storage, to restore state
376+
uint8_t interruptMode; // 0=none, 1-15=mask, 16=global
377+
uint8_t interruptSave; // temp storage, to restore state
378+
uint32_t interruptMask[4];
376379
};
377380

378381
#if SPI_INTERFACES_COUNT > 0

0 commit comments

Comments
 (0)