Skip to content

Commit

Permalink
Encoder support UNO R4 (untested)
Browse files Browse the repository at this point in the history
  • Loading branch information
tttapa committed Sep 3, 2023
1 parent 6f57a56 commit e20e32f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 16 deletions.
27 changes: 12 additions & 15 deletions src/Submodules/Encoder/AHEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@

BEGIN_CS_NAMESPACE

#if defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
#define NOT_AN_INTERRUPT 255
pin_size_t digitalPinToInterrupt(pin_size_t pin) {
if (pin == 2 || pin == 3)
return ::digitalPinToInterrupt(pin);
return NOT_AN_INTERRUPT;
}
#ifndef CS_CUSTOM_INTERRUPT_TO_INDEX
using interrupt_index_t = decltype(digitalPinToInterrupt(0));
static interrupt_index_t interruptToIndex(interrupt_index_t i) { return i; }
#endif

AHEncoder::AHEncoder(uint8_t pinA, uint8_t pinB)
Expand Down Expand Up @@ -53,18 +49,18 @@ void swap(AHEncoder &a, AHEncoder &b) {
if (a.interrupts_in_use > 0) {
int int1 = digitalPinToInterrupt(a.pins[0]);
if (int1 != NOT_AN_INTERRUPT)
AHEncoder::instance_table[int1] = &a;
AHEncoder::instance_table[interruptToIndex(int1)] = &a;
int int2 = digitalPinToInterrupt(a.pins[1]);
if (int2 != NOT_AN_INTERRUPT)
AHEncoder::instance_table[int2] = &a;
AHEncoder::instance_table[interruptToIndex(int2)] = &a;
}
if (b.interrupts_in_use > 0) {
int int1 = digitalPinToInterrupt(b.pins[0]);
if (int1 != NOT_AN_INTERRUPT)
AHEncoder::instance_table[int1] = &b;
AHEncoder::instance_table[interruptToIndex(int1)] = &b;
int int2 = digitalPinToInterrupt(b.pins[1]);
if (int2 != NOT_AN_INTERRUPT)
AHEncoder::instance_table[int2] = &b;
AHEncoder::instance_table[interruptToIndex(int2)] = &b;
}
interrupts();
}
Expand Down Expand Up @@ -110,11 +106,11 @@ void AHEncoder::end() {

void AHEncoder::attachInterruptCtx(int interrupt) {
if (interrupt != NOT_AN_INTERRUPT) {
if (instance_table[interrupt] != nullptr) {
if (instance_table[interruptToIndex(interrupt)] != nullptr) {
FATAL_ERROR(F("Multiple encoders on the same pin"), 0x7283);
return;
}
instance_table[interrupt] = this;
instance_table[interruptToIndex(interrupt)] = this;
++interrupts_in_use;
#ifdef ARDUINO_ARCH_RP2040
gpio_set_irq_enabled_with_callback(
Expand All @@ -124,7 +120,8 @@ void AHEncoder::attachInterruptCtx(int interrupt) {
arg->update();
});
#else
attachInterrupt(interrupt, get_isr(interrupt), CHANGE);
attachInterrupt(interrupt, get_isr(interruptToIndex(interrupt)),
CHANGE);
#endif
}
}
Expand All @@ -138,7 +135,7 @@ void AHEncoder::detachInterruptCtx(int interrupt) {
detachInterrupt(interrupt);
#endif
--interrupts_in_use;
instance_table[interrupt] = nullptr;
instance_table[interruptToIndex(interrupt)] = nullptr;
}
}

Expand Down
39 changes: 38 additions & 1 deletion src/Submodules/Encoder/NumInterrupts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,44 @@ BEGIN_CS_NAMESPACE

// Arduino UNO R4
#elif defined(ARDUINO_UNOR4_MINIMA) || defined(ARDUINO_UNOR4_WIFI)
#define CORE_NUM_INTERRUPT 2
#define CORE_NUM_INTERRUPT 13

#ifdef NOT_AN_INTERRUPT
#error \
"This version of the ArduinoCore-renesas is not supported. Please open an issue on GitHub: https://github.com/tttapa/Control-Surface/issues"
#endif
#define NOT_AN_INTERRUPT 255
constexpr pin_size_t pin_to_interrupt_index[] {
0, // GPIO 0 (P301) IRQ6
1, // GPIO 1 (P302) IRQ5
2, // GPIO 2 (P104) IRQ1
3, // GPIO 3 (P105) IRQ0
NOT_AN_INTERRUPT, // GPIO 4 (P106) -
NOT_AN_INTERRUPT, // GPIO 5 (P107) -
4, // GPIO 6 (P111) IRQ4
NOT_AN_INTERRUPT, // GPIO 7 (P112) -
5, // GPIO 8 (P304) IRQ9
NOT_AN_INTERRUPT, // GPIO 9 (P303) -
NOT_AN_INTERRUPT, // GPIO 10 (P103) -
6, // GPIO 11 (P411) IRQ4
7, // GPIO 12 (P410) IRQ5
NOT_AN_INTERRUPT, // GPIO 13 (P102) -
NOT_AN_INTERRUPT, // GPIO 14 (P014) -
8, // GPIO 15 (P000) IRQ6
9, // GPIO 16 (P001) IRQ7
10, // GPIO 17 (P002) IRQ2
11, // GPIO 18 (P101) IRQ1
12, // GPIO 19 (P100) IRQ2
};
inline pin_size_t digitalPinToInterrupt(pin_size_t pin) {
if (pin_to_interrupt_index[pin] == NOT_AN_INTERRUPT)
return NOT_AN_INTERRUPT;
return ::digitalPinToInterrupt(pin);
}
inline pin_size_t interruptToIndex(pin_size_t interrupt) {
return pin_to_interrupt_index[interrupt];
}
#define CS_CUSTOM_INTERRUPT_TO_INDEX 1

// Others
#else
Expand Down

0 comments on commit e20e32f

Please sign in to comment.