feat:encoder with existing lib (#2)

Co-authored-by: Clement <c.boesmier@aptatio.com>
Reviewed-on: #2
This commit is contained in:
2023-10-20 18:32:17 +02:00
parent 6e2da886fc
commit 3a6d55c646
19 changed files with 1943 additions and 8 deletions

View File

@ -0,0 +1,104 @@
#ifndef direct_pin_read_h_
#define direct_pin_read_h_
#if defined(__AVR__)
#define IO_REG_TYPE uint8_t
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#elif defined(TEENSYDUINO) && (defined(KINETISK) || defined(KINETISL))
#define IO_REG_TYPE uint8_t
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#elif defined(__SAM3X8E__) // || defined(ESP8266)
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#elif defined(__PIC32MX__)
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0)
/* ESP8266 v2.0.0 Arduino workaround for bug https://github.com/esp8266/Arduino/issues/1110 */
#elif defined(ESP8266)
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) ((volatile uint32_t *)(0x60000000+(0x318)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
/* ESP32 Arduino (https://github.com/espressif/arduino-esp32) */
#elif defined(ESP32)
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#elif defined(__SAMD21G18A__)
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) portModeRegister(digitalPinToPort(pin))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*((base)+8)) & (mask)) ? 1 : 0)
#elif defined(__SAMD51__)
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) portInputRegister(digitalPinToPort(pin))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#elif defined(RBL_NRF51822)
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) (0)
#define PIN_TO_BITMASK(pin) (pin)
#define DIRECT_PIN_READ(base, pin) nrf_gpio_pin_read(pin)
#elif defined(__arc__) /* Arduino101/Genuino101 specifics */
#include "scss_registers.h"
#include "portable.h"
#include "avr/pgmspace.h"
#define GPIO_ID(pin) (g_APinDescription[pin].ulGPIOId)
#define GPIO_TYPE(pin) (g_APinDescription[pin].ulGPIOType)
#define GPIO_BASE(pin) (g_APinDescription[pin].ulGPIOBase)
#define EXT_PORT_OFFSET_SS 0x0A
#define EXT_PORT_OFFSET_SOC 0x50
#define PIN_TO_BASEREG(pin) ((volatile uint32_t *)g_APinDescription[pin].ulGPIOBase)
#define PIN_TO_BITMASK(pin) pin
#define IO_REG_TYPE uint32_t
static inline __attribute__((always_inline))
IO_REG_TYPE directRead(volatile IO_REG_TYPE *base, IO_REG_TYPE pin)
{
IO_REG_TYPE ret;
if (SS_GPIO == GPIO_TYPE(pin)) {
ret = READ_ARC_REG(((IO_REG_TYPE)base + EXT_PORT_OFFSET_SS));
} else {
ret = MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, EXT_PORT_OFFSET_SOC);
}
return ((ret >> GPIO_ID(pin)) & 0x01);
}
#define DIRECT_PIN_READ(base, pin) directRead(base, pin)
#endif
#endif

View File

@ -0,0 +1,87 @@
#if defined(__AVR__)
#include <avr/io.h>
#include <avr/interrupt.h>
#define attachInterrupt(num, func, mode) enableInterrupt(num)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define SCRAMBLE_INT_ORDER(num) ((num < 4) ? num + 2 : ((num < 6) ? num - 4 : num))
#define DESCRAMBLE_INT_ORDER(num) ((num < 2) ? num + 4 : ((num < 6) ? num - 2 : num))
#else
#define SCRAMBLE_INT_ORDER(num) (num)
#define DESCRAMBLE_INT_ORDER(num) (num)
#endif
static void enableInterrupt(uint8_t num)
{
switch (DESCRAMBLE_INT_ORDER(num)) {
#if defined(EICRA) && defined(EIMSK)
case 0:
EICRA = (EICRA & 0xFC) | 0x01;
EIMSK |= 0x01;
return;
case 1:
EICRA = (EICRA & 0xF3) | 0x04;
EIMSK |= 0x02;
return;
case 2:
EICRA = (EICRA & 0xCF) | 0x10;
EIMSK |= 0x04;
return;
case 3:
EICRA = (EICRA & 0x3F) | 0x40;
EIMSK |= 0x08;
return;
#elif defined(MCUCR) && defined(GICR)
case 0:
MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
GICR |= (1 << INT0);
return;
case 1:
MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
GICR |= (1 << INT1);
return;
#elif defined(MCUCR) && defined(GIMSK)
case 0:
MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
GIMSK |= (1 << INT0);
return;
case 1:
MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
GIMSK |= (1 << INT1);
return;
#endif
#if defined(EICRB) && defined(EIMSK)
case 4:
EICRB = (EICRB & 0xFC) | 0x01;
EIMSK |= 0x10;
return;
case 5:
EICRB = (EICRB & 0xF3) | 0x04;
EIMSK |= 0x20;
return;
case 6:
EICRB = (EICRB & 0xCF) | 0x10;
EIMSK |= 0x40;
return;
case 7:
EICRB = (EICRB & 0x3F) | 0x40;
EIMSK |= 0x80;
return;
#endif
}
}
#elif defined(__PIC32MX__)
#ifdef ENCODER_OPTIMIZE_INTERRUPTS
#undef ENCODER_OPTIMIZE_INTERRUPTS
#endif
#else
#ifdef ENCODER_OPTIMIZE_INTERRUPTS
#undef ENCODER_OPTIMIZE_INTERRUPTS
#endif
#endif

View File

@ -0,0 +1,340 @@
// interrupt pins for known boards
// Teensy (and maybe others) define these automatically
#if !defined(CORE_NUM_INTERRUPT)
// Wiring boards
#if defined(WIRING)
#define CORE_NUM_INTERRUPT NUM_EXTERNAL_INTERRUPTS
#if NUM_EXTERNAL_INTERRUPTS > 0
#define CORE_INT0_PIN EI0
#endif
#if NUM_EXTERNAL_INTERRUPTS > 1
#define CORE_INT1_PIN EI1
#endif
#if NUM_EXTERNAL_INTERRUPTS > 2
#define CORE_INT2_PIN EI2
#endif
#if NUM_EXTERNAL_INTERRUPTS > 3
#define CORE_INT3_PIN EI3
#endif
#if NUM_EXTERNAL_INTERRUPTS > 4
#define CORE_INT4_PIN EI4
#endif
#if NUM_EXTERNAL_INTERRUPTS > 5
#define CORE_INT5_PIN EI5
#endif
#if NUM_EXTERNAL_INTERRUPTS > 6
#define CORE_INT6_PIN EI6
#endif
#if NUM_EXTERNAL_INTERRUPTS > 7
#define CORE_INT7_PIN EI7
#endif
// Arduino Uno, Duemilanove, Diecimila, LilyPad, Mini, Fio, etc...
#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) ||defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__)
#define CORE_NUM_INTERRUPT 2
#define CORE_INT0_PIN 2
#define CORE_INT1_PIN 3
// Arduino Mega
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define CORE_NUM_INTERRUPT 6
#define CORE_INT0_PIN 2
#define CORE_INT1_PIN 3
#define CORE_INT2_PIN 21
#define CORE_INT3_PIN 20
#define CORE_INT4_PIN 19
#define CORE_INT5_PIN 18
// Arduino Nano Every, Uno R2 Wifi
#elif defined(__AVR_ATmega4809__)
#define CORE_NUM_INTERRUPT 22
#define CORE_INT0_PIN 0
#define CORE_INT1_PIN 1
#define CORE_INT2_PIN 2
#define CORE_INT3_PIN 3
#define CORE_INT4_PIN 4
#define CORE_INT5_PIN 5
#define CORE_INT6_PIN 6
#define CORE_INT7_PIN 7
#define CORE_INT8_PIN 8
#define CORE_INT9_PIN 9
#define CORE_INT10_PIN 10
#define CORE_INT11_PIN 11
#define CORE_INT12_PIN 12
#define CORE_INT13_PIN 13
#define CORE_INT14_PIN 14
#define CORE_INT15_PIN 15
#define CORE_INT16_PIN 16
#define CORE_INT17_PIN 17
#define CORE_INT18_PIN 18
#define CORE_INT19_PIN 19
#define CORE_INT20_PIN 20
#define CORE_INT21_PIN 21
// Arduino Leonardo (untested)
#elif defined(__AVR_ATmega32U4__) && !defined(CORE_TEENSY)
#define CORE_NUM_INTERRUPT 5
#define CORE_INT0_PIN 3
#define CORE_INT1_PIN 2
#define CORE_INT2_PIN 0
#define CORE_INT3_PIN 1
#define CORE_INT4_PIN 7
// Sanguino (untested) and ATmega1284P
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284P__)
#define CORE_NUM_INTERRUPT 3
#define CORE_INT0_PIN 10
#define CORE_INT1_PIN 11
#define CORE_INT2_PIN 2
// ATmega32u2 and ATmega32u16 based boards with HoodLoader2
#elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__)
#define CORE_NUM_INTERRUPT 8
#define CORE_INT0_PIN 8
#define CORE_INT1_PIN 17
#define CORE_INT2_PIN 13
#define CORE_INT3_PIN 14
#define CORE_INT4_PIN 15
#define CORE_INT5_PIN 16
#define CORE_INT6_PIN 19
#define CORE_INT7_PIN 20
// Chipkit Uno32 - attachInterrupt may not support CHANGE option
#elif defined(__PIC32MX__) && defined(_BOARD_UNO_)
#define CORE_NUM_INTERRUPT 5
#define CORE_INT0_PIN 38
#define CORE_INT1_PIN 2
#define CORE_INT2_PIN 7
#define CORE_INT3_PIN 8
#define CORE_INT4_PIN 35
// Chipkit Uno32 - attachInterrupt may not support CHANGE option
#elif defined(__PIC32MX__) && defined(_BOARD_MEGA_)
#define CORE_NUM_INTERRUPT 5
#define CORE_INT0_PIN 3
#define CORE_INT1_PIN 2
#define CORE_INT2_PIN 7
#define CORE_INT3_PIN 21
#define CORE_INT4_PIN 20
// http://hlt.media.mit.edu/?p=1229
#elif defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
#define CORE_NUM_INTERRUPT 1
#define CORE_INT0_PIN 2
// ATtiny441 ATtiny841
#elif defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__)
#define CORE_NUM_INTERRUPT 1
#define CORE_INT0_PIN 9
//https://github.com/SpenceKonde/ATTinyCore/blob/master/avr/extras/ATtiny_x313.md
#elif defined(__AVR_ATtinyX313__)
#define CORE_NUM_INTERRUPT 2
#define CORE_INT0_PIN 4
#define CORE_INT1_PIN 5
// Attiny167 same core as abobe
#elif defined(__AVR_ATtiny167__)
#define CORE_NUM_INTERRUPT 2
#define CORE_INT0_PIN 14
#define CORE_INT1_PIN 3
// Arduino Due
#elif defined(__SAM3X8E__)
#define CORE_NUM_INTERRUPT 54
#define CORE_INT0_PIN 0
#define CORE_INT1_PIN 1
#define CORE_INT2_PIN 2
#define CORE_INT3_PIN 3
#define CORE_INT4_PIN 4
#define CORE_INT5_PIN 5
#define CORE_INT6_PIN 6
#define CORE_INT7_PIN 7
#define CORE_INT8_PIN 8
#define CORE_INT9_PIN 9
#define CORE_INT10_PIN 10
#define CORE_INT11_PIN 11
#define CORE_INT12_PIN 12
#define CORE_INT13_PIN 13
#define CORE_INT14_PIN 14
#define CORE_INT15_PIN 15
#define CORE_INT16_PIN 16
#define CORE_INT17_PIN 17
#define CORE_INT18_PIN 18
#define CORE_INT19_PIN 19
#define CORE_INT20_PIN 20
#define CORE_INT21_PIN 21
#define CORE_INT22_PIN 22
#define CORE_INT23_PIN 23
#define CORE_INT24_PIN 24
#define CORE_INT25_PIN 25
#define CORE_INT26_PIN 26
#define CORE_INT27_PIN 27
#define CORE_INT28_PIN 28
#define CORE_INT29_PIN 29
#define CORE_INT30_PIN 30
#define CORE_INT31_PIN 31
#define CORE_INT32_PIN 32
#define CORE_INT33_PIN 33
#define CORE_INT34_PIN 34
#define CORE_INT35_PIN 35
#define CORE_INT36_PIN 36
#define CORE_INT37_PIN 37
#define CORE_INT38_PIN 38
#define CORE_INT39_PIN 39
#define CORE_INT40_PIN 40
#define CORE_INT41_PIN 41
#define CORE_INT42_PIN 42
#define CORE_INT43_PIN 43
#define CORE_INT44_PIN 44
#define CORE_INT45_PIN 45
#define CORE_INT46_PIN 46
#define CORE_INT47_PIN 47
#define CORE_INT48_PIN 48
#define CORE_INT49_PIN 49
#define CORE_INT50_PIN 50
#define CORE_INT51_PIN 51
#define CORE_INT52_PIN 52
#define CORE_INT53_PIN 53
// ESP8266 (https://github.com/esp8266/Arduino/)
#elif defined(ESP8266)
#define CORE_NUM_INTERRUPT EXTERNAL_NUM_INTERRUPTS
#define CORE_INT0_PIN 0
#define CORE_INT1_PIN 1
#define CORE_INT2_PIN 2
#define CORE_INT3_PIN 3
#define CORE_INT4_PIN 4
#define CORE_INT5_PIN 5
// GPIO6-GPIO11 are typically used to interface with the flash memory IC on
// most esp8266 modules, so we should avoid adding interrupts to these pins.
#define CORE_INT12_PIN 12
#define CORE_INT13_PIN 13
#define CORE_INT14_PIN 14
#define CORE_INT15_PIN 15
// ESP32 (https://github.com/espressif/arduino-esp32)
#elif defined(ESP32)
#define CORE_NUM_INTERRUPT 40
#define CORE_INT0_PIN 0
#define CORE_INT1_PIN 1
#define CORE_INT2_PIN 2
#define CORE_INT3_PIN 3
#define CORE_INT4_PIN 4
#define CORE_INT5_PIN 5
// GPIO6-GPIO11 are typically used to interface with the flash memory IC on
// esp32, so we should avoid adding interrupts to these pins.
#define CORE_INT12_PIN 12
#define CORE_INT13_PIN 13
#define CORE_INT14_PIN 14
#define CORE_INT15_PIN 15
#define CORE_INT16_PIN 16
#define CORE_INT17_PIN 17
#define CORE_INT18_PIN 18
#define CORE_INT19_PIN 19
#define CORE_INT21_PIN 21
#define CORE_INT22_PIN 22
#define CORE_INT23_PIN 23
#define CORE_INT25_PIN 25
#define CORE_INT26_PIN 26
#define CORE_INT27_PIN 27
#define CORE_INT32_PIN 32
#define CORE_INT33_PIN 33
#define CORE_INT34_PIN 34
#define CORE_INT35_PIN 35
#define CORE_INT36_PIN 36
#define CORE_INT39_PIN 39
// Arduino Zero - TODO: interrupts do not seem to work
// please help, contribute a fix!
#elif defined(__SAMD21G18A__)
#define CORE_NUM_INTERRUPT 31
#define CORE_INT0_PIN 0
#define CORE_INT1_PIN 1
#define CORE_INT2_PIN 2
#define CORE_INT3_PIN 3
#define CORE_INT4_PIN 4
#define CORE_INT5_PIN 5
#define CORE_INT6_PIN 6
#define CORE_INT7_PIN 7
#define CORE_INT8_PIN 8
#define CORE_INT9_PIN 9
#define CORE_INT10_PIN 10
#define CORE_INT11_PIN 11
#define CORE_INT12_PIN 12
#define CORE_INT13_PIN 13
#define CORE_INT14_PIN 14
#define CORE_INT15_PIN 15
#define CORE_INT16_PIN 16
#define CORE_INT17_PIN 17
#define CORE_INT18_PIN 18
#define CORE_INT19_PIN 19
#define CORE_INT20_PIN 20
#define CORE_INT21_PIN 21
#define CORE_INT22_PIN 22
#define CORE_INT23_PIN 23
#define CORE_INT24_PIN 24
#define CORE_INT25_PIN 25
#define CORE_INT26_PIN 26
#define CORE_INT27_PIN 27
#define CORE_INT28_PIN 28
#define CORE_INT29_PIN 29
#define CORE_INT30_PIN 30
#elif defined(__SAMD51__)
#define CORE_NUM_INTERRUPT 26
#define CORE_INT0_PIN 0
#define CORE_INT1_PIN 1
#define CORE_INT2_PIN 2
#define CORE_INT3_PIN 3
#define CORE_INT4_PIN 4
#define CORE_INT5_PIN 5
#define CORE_INT6_PIN 6
#define CORE_INT7_PIN 7
#define CORE_INT8_PIN 8
#define CORE_INT9_PIN 9
#define CORE_INT10_PIN 10
#define CORE_INT11_PIN 11
#define CORE_INT12_PIN 12
#define CORE_INT13_PIN 13
#define CORE_INT14_PIN 14
#define CORE_INT15_PIN 15
#define CORE_INT16_PIN 16
#define CORE_INT17_PIN 17
#define CORE_INT18_PIN 18
#define CORE_INT19_PIN 19
#define CORE_INT20_PIN 20
#define CORE_INT21_PIN 21
#define CORE_INT22_PIN 22
#define CORE_INT23_PIN 23
#define CORE_INT24_PIN 24
#define CORE_INT25_PIN 25
// Arduino 101
#elif defined(__arc__)
#define CORE_NUM_INTERRUPT 14
#define CORE_INT2_PIN 2
#define CORE_INT5_PIN 5
#define CORE_INT7_PIN 7
#define CORE_INT8_PIN 8
#define CORE_INT10_PIN 10
#define CORE_INT11_PIN 11
#define CORE_INT12_PIN 12
#define CORE_INT13_PIN 13
#endif
#endif
#if !defined(CORE_NUM_INTERRUPT)
#error "Interrupts are unknown for this board, please add to this code"
#endif
#if CORE_NUM_INTERRUPT <= 0
#error "Encoder requires interrupt pins, but this board does not have any :("
#error "You could try defining ENCODER_DO_NOT_USE_INTERRUPTS as a kludge."
#endif