#ifdef ARDUINO

#include "interface.h"
#include "interrupts.h"

#ifndef ARDUINO_ARCH_ESP8266
	#define IRAM_ATTR
#endif /* !ARDUINO_ARCH_ESP8266 */

#ifdef ARDUINO_ARCH_ESP8266
IRAM_ATTR void isr_0_RISING()
{
	real_isr(0, Rising_c);
}
IRAM_ATTR void isr_0_FALLING()
{
	real_isr(0, Falling_c);
}
IRAM_ATTR void isr_0_CHANGE()
{
	real_isr(0, Change_c);
}
IRAM_ATTR void isr_0_LOW()
{
	real_isr(0, Low_c);
}
IRAM_ATTR void isr_0_HIGH()
{
	real_isr(0, High_c);
}
#endif /* ARDUINO_ARCH_ESP8266 */
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ESP8266)
IRAM_ATTR void isr_2_RISING()
{
	real_isr(2, Rising_c);
}
IRAM_ATTR void isr_2_FALLING()
{
	real_isr(2, Falling_c);
}
IRAM_ATTR void isr_2_CHANGE()
{
	real_isr(2, Change_c);
}
IRAM_ATTR void isr_2_LOW()
{
	real_isr(2, Low_c);
}
#ifndef ARDUINO_ARCH_AVR
IRAM_ATTR void isr_2_HIGH()
{
	real_isr(2, High_c);
}
#endif /* !ARDUINO_ARCH_AVR */
#endif /* defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ESP8266) */
#ifdef ARDUINO_ARCH_AVR
IRAM_ATTR void isr_3_RISING()
{
	real_isr(3, Rising_c);
}
IRAM_ATTR void isr_3_FALLING()
{
	real_isr(3, Falling_c);
}
IRAM_ATTR void isr_3_CHANGE()
{
	real_isr(3, Change_c);
}
IRAM_ATTR void isr_3_LOW()
{
	real_isr(3, Low_c);
}
#endif /* ARDUINO_ARCH_AVR */
#ifdef ARDUINO_ARCH_ESP8266
IRAM_ATTR void isr_4_RISING()
{
	real_isr(4, Rising_c);
}
IRAM_ATTR void isr_4_FALLING()
{
	real_isr(4, Falling_c);
}
IRAM_ATTR void isr_4_CHANGE()
{
	real_isr(4, Change_c);
}
IRAM_ATTR void isr_4_LOW()
{
	real_isr(4, Low_c);
}
IRAM_ATTR void isr_4_HIGH()
{
	real_isr(4, High_c);
}
#endif /* ARDUINO_ARCH_AVR */
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_SAMD)
IRAM_ATTR void isr_5_RISING()
{
	real_isr(5, Rising_c);
}
IRAM_ATTR void isr_5_FALLING()
{
	real_isr(5, Falling_c);
}
IRAM_ATTR void isr_5_CHANGE()
{
	real_isr(5, Change_c);
}
IRAM_ATTR void isr_5_LOW()
{
	real_isr(5, Low_c);
}
IRAM_ATTR void isr_5_HIGH()
{
	real_isr(5, High_c);
}
#endif /* defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_SAMD) */
#ifdef ARDUINO_ARCH_SAMD
IRAM_ATTR void isr_6_CHANGE() {
	real_isr(6, Change_c);
}
IRAM_ATTR void isr_6_RISING() {
	real_isr(6, Rising_c);
}
IRAM_ATTR void isr_6_FALLING() {
	real_isr(6, Falling_c);
}
IRAM_ATTR void isr_6_LOW() {
	real_isr(6, Low_c);
}
IRAM_ATTR void isr_6_HIGH() {
	real_isr(6, High_c);
}
IRAM_ATTR void isr_9_CHANGE() {
	real_isr(9, Change_c);
}
IRAM_ATTR void isr_9_RISING() {
	real_isr(9, Rising_c);
}
IRAM_ATTR void isr_9_FALLING() {
	real_isr(9, Falling_c);
}
IRAM_ATTR void isr_9_LOW() {
	real_isr(9, Low_c);
}
IRAM_ATTR void isr_9_HIGH() {
	real_isr(9, High_c);
}
IRAM_ATTR void isr_10_CHANGE() {
	real_isr(10, Change_c);
}
IRAM_ATTR void isr_10_RISING() {
	real_isr(10, Rising_c);
}
IRAM_ATTR void isr_10_FALLING() {
	real_isr(10, Falling_c);
}
IRAM_ATTR void isr_10_LOW() {
	real_isr(10, Low_c);
}
IRAM_ATTR void isr_10_HIGH() {
	real_isr(10, High_c);
}
IRAM_ATTR void isr_11_CHANGE() {
	real_isr(11, Change_c);
}
IRAM_ATTR void isr_11_RISING() {
	real_isr(11, Rising_c);
}
IRAM_ATTR void isr_11_FALLING() {
	real_isr(11, Falling_c);
}
IRAM_ATTR void isr_11_LOW() {
	real_isr(11, Low_c);
}
IRAM_ATTR void isr_11_HIGH() {
	real_isr(11, High_c);
}
#endif /* ARDUINO_ARCH_SAMD21 */
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_SAMD)
IRAM_ATTR void isr_12_RISING()
{
	real_isr(12, Rising_c);
}
IRAM_ATTR void isr_12_FALLING()
{
	real_isr(12, Falling_c);
}
IRAM_ATTR void isr_12_CHANGE()
{
	real_isr(12, Change_c);
}
IRAM_ATTR void isr_12_LOW()
{
	real_isr(12, Low_c);
}
IRAM_ATTR void isr_12_HIGH()
{
	real_isr(12, High_c);
}
IRAM_ATTR void isr_13_RISING()
{
	real_isr(13, Rising_c);
}
IRAM_ATTR void isr_13_FALLING()
{
	real_isr(13, Falling_c);
}
IRAM_ATTR void isr_13_CHANGE()
{
	real_isr(13, Change_c);
}
IRAM_ATTR void isr_13_LOW()
{
	real_isr(13, Low_c);
}
IRAM_ATTR void isr_13_HIGH()
{
	real_isr(13, High_c);
}
IRAM_ATTR void isr_14_RISING()
{
	real_isr(14, Rising_c);
}
IRAM_ATTR void isr_14_FALLING()
{
	real_isr(14, Falling_c);
}
IRAM_ATTR void isr_14_CHANGE()
{
	real_isr(14, Change_c);
}
IRAM_ATTR void isr_14_LOW()
{
	real_isr(14, Low_c);
}
IRAM_ATTR void isr_14_HIGH()
{
	real_isr(14, High_c);
}
IRAM_ATTR void isr_15_RISING()
{
	real_isr(15, Rising_c);
}
IRAM_ATTR void isr_15_FALLING()
{
	real_isr(15, Falling_c);
}
IRAM_ATTR void isr_15_CHANGE()
{
	real_isr(15, Change_c);
}
IRAM_ATTR void isr_15_LOW()
{
	real_isr(15, Low_c);
}
IRAM_ATTR void isr_15_HIGH()
{
	real_isr(15, High_c);
}
#endif /* defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_SAMD) */
#ifdef ARDUINO_ARCH_SAMD
IRAM_ATTR void isr_16_CHANGE() {
	real_isr(16, Change_c);
}
IRAM_ATTR void isr_16_RISING() {
	real_isr(16, Rising_c);
}
IRAM_ATTR void isr_16_FALLING() {
	real_isr(16, Falling_c);
}
IRAM_ATTR void isr_16_LOW() {
	real_isr(16, Low_c);
}
IRAM_ATTR void isr_16_HIGH() {
	real_isr(16, High_c);
}
IRAM_ATTR void isr_17_CHANGE() {
	real_isr(17, Change_c);
}
IRAM_ATTR void isr_17_RISING() {
	real_isr(17, Rising_c);
}
IRAM_ATTR void isr_17_FALLING() {
	real_isr(17, Falling_c);
}
IRAM_ATTR void isr_17_LOW() {
	real_isr(17, Low_c);
}
IRAM_ATTR void isr_17_HIGH() {
	real_isr(17, High_c);
}
IRAM_ATTR void isr_18_CHANGE() {
	real_isr(18, Change_c);
}
IRAM_ATTR void isr_18_RISING() {
	real_isr(18, Rising_c);
}
IRAM_ATTR void isr_18_FALLING() {
	real_isr(18, Falling_c);
}
IRAM_ATTR void isr_18_LOW() {
	real_isr(18, Low_c);
}
IRAM_ATTR void isr_18_HIGH() {
	real_isr(18, High_c);
}
IRAM_ATTR void isr_19_CHANGE() {
	real_isr(19, Change_c);
}
IRAM_ATTR void isr_19_RISING() {
	real_isr(19, Rising_c);
}
IRAM_ATTR void isr_19_FALLING() {
	real_isr(19, Falling_c);
}
IRAM_ATTR void isr_19_LOW() {
	real_isr(19, Low_c);
}
IRAM_ATTR void isr_19_HIGH() {
	real_isr(19, High_c);
}
#endif /* ARDUINO_ARCH_SAMD21 */

#ifdef ARDUINO_ARCH_AVR
static void (*isr_map[20])() = {
	// Pin 0
	NULL, NULL, NULL, NULL, NULL,
	// Pin 1
	NULL, NULL, NULL, NULL, NULL,
	// Pin 2
	isr_2_CHANGE, isr_2_RISING, isr_2_FALLING, isr_2_LOW, NULL,
	// Pin 3
	isr_3_CHANGE, isr_3_RISING, isr_3_FALLING, isr_3_LOW, NULL
};
#elif defined(ARDUINO_ARCH_ESP8266)
static void (*isr_map[80])() = {
	// Pin 0
	isr_0_CHANGE, isr_0_RISING, isr_0_FALLING, isr_0_LOW, isr_0_HIGH,
	// Pin 1
	NULL, NULL, NULL, NULL, NULL,
	// Pin 2
	isr_2_CHANGE, isr_2_RISING, isr_2_FALLING, isr_2_LOW, isr_2_HIGH,
	// Pin 3
	NULL, NULL, NULL, NULL, NULL,
	// Pin 4
	isr_4_CHANGE, isr_4_RISING, isr_4_FALLING, isr_4_LOW, isr_4_HIGH,
	// Pin 5
	isr_5_CHANGE, isr_5_RISING, isr_5_FALLING, isr_5_LOW, isr_5_HIGH,
	// Pin 6
	NULL, NULL, NULL, NULL, NULL,
	// Pin 7
	NULL, NULL, NULL, NULL, NULL,
	// Pin 8
	NULL, NULL, NULL, NULL, NULL,
	// Pin 9
	NULL, NULL, NULL, NULL, NULL,
	// Pin 10
	NULL, NULL, NULL, NULL, NULL,
	// Pin 11
	NULL, NULL, NULL, NULL, NULL,
	// Pin 12
	isr_12_CHANGE, isr_12_RISING, isr_12_FALLING, isr_12_LOW, isr_12_HIGH,
	// Pin 13
	isr_13_CHANGE, isr_13_RISING, isr_13_FALLING, isr_13_LOW, isr_13_HIGH,
	// Pin 14
	isr_14_CHANGE, isr_14_RISING, isr_14_FALLING, isr_14_LOW, isr_14_HIGH,
	// Pin 15
	isr_15_CHANGE, isr_15_RISING, isr_15_FALLING, isr_15_LOW, isr_15_HIGH
};
#elif defined(ARDUINO_ARCH_SAMD)
static void (*isr_map[100])() = {
	// Pin 0
	NULL, NULL, NULL, NULL, NULL,
	// Pin 1
	NULL, NULL, NULL, NULL, NULL,
	// Pin 2
	NULL, NULL, NULL, NULL, NULL,
	// Pin 3
	NULL, NULL, NULL, NULL, NULL,
	// Pin 4
	NULL, NULL, NULL, NULL, NULL,
	// Pin 5
	isr_5_CHANGE, isr_5_RISING, isr_5_FALLING, isr_5_LOW, isr_5_HIGH,
	// Pin 6
	isr_6_CHANGE, isr_6_RISING, isr_6_FALLING, isr_6_LOW, isr_6_HIGH,
	// Pin 7
	NULL, NULL, NULL, NULL, NULL,
	// Pin 8
	NULL, NULL, NULL, NULL, NULL,
	// Pin 9
	isr_9_CHANGE, isr_9_RISING, isr_9_FALLING, isr_9_LOW, isr_9_HIGH,
	// Pin 10
	isr_10_CHANGE, isr_10_RISING, isr_10_FALLING, isr_10_LOW, isr_10_HIGH,
	// Pin 11
	isr_11_CHANGE, isr_11_RISING, isr_11_FALLING, isr_11_LOW, isr_11_HIGH,
	// Pin 12
	isr_12_CHANGE, isr_12_RISING, isr_12_FALLING, isr_12_LOW, isr_12_HIGH,
	// Pin 13
	isr_13_CHANGE, isr_13_RISING, isr_13_FALLING, isr_13_LOW, isr_13_HIGH,
	// Pin 14
	isr_14_CHANGE, isr_14_RISING, isr_14_FALLING, isr_14_LOW, isr_14_HIGH,
	// Pin 15
	isr_15_CHANGE, isr_15_RISING, isr_15_FALLING, isr_15_LOW, isr_15_HIGH,
	// Pin 16
	isr_16_CHANGE, isr_16_RISING, isr_16_FALLING, isr_16_LOW, isr_16_HIGH,
	// Pin 17
	isr_17_CHANGE, isr_17_RISING, isr_17_FALLING, isr_17_LOW, isr_17_HIGH,
	// Pin 18
	isr_18_CHANGE, isr_18_RISING, isr_18_FALLING, isr_18_LOW, isr_18_HIGH,
	// Pin 19
	isr_19_CHANGE, isr_19_RISING, isr_19_FALLING, isr_19_LOW, isr_19_HIGH
};
#else /* defined(ARDUINO_ARCH_SAMD) */
	static void (*isr_map[0])() = {};
#endif /* defined(ARDUINO_ARCH_SAMD) */

void (*get_isr(uint16_t pin, enum InterruptMode mode))()
{
	if (pin > MAX_INTERRUPT_PIN) {
		return NULL;
	}

	return *isr_map[pin * 5 + mode];
}

#endif /*Arduino*/

