diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index 1f02a58c..83017230 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -90,6 +90,7 @@ extern const uint8_t digital_pin_to_port[]; extern const uint8_t digital_pin_to_bit_mask[]; extern const uint8_t digital_pin_to_bit_position[]; extern const uint8_t digital_pin_to_timer[]; +extern const uint8_t analog_pin_to_channel[]; // Get the bit location within the hardware port of the given virtual pin. // This comes from the pins_*.c file for the active board configuration. @@ -155,5 +156,12 @@ bool isDoubleBondedActive(uint8_t pin); #endif +#ifdef __cplusplus +extern "C" { +#endif #include "pins_arduino.h" +#ifdef __cplusplus +} // extern "C" +#endif + #endif diff --git a/cores/arduino/UART.h b/cores/arduino/UART.h index 574f0c35..5de83d17 100644 --- a/cores/arduino/UART.h +++ b/cores/arduino/UART.h @@ -27,6 +27,8 @@ #include "api/HardwareSerial.h" #include "pins_arduino.h" +using namespace arduino; + // Define constants and variables for buffering incoming serial data. We're // using a ring buffer (I think), in which head is the index of the location // to which to write the next incoming character and tail is the index of the diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.cpp similarity index 87% rename from cores/arduino/WInterrupts.c rename to cores/arduino/WInterrupts.cpp index 64cd9ae6..55155f4c 100644 --- a/cores/arduino/WInterrupts.c +++ b/cores/arduino/WInterrupts.cpp @@ -32,9 +32,10 @@ #include "wiring_private.h" -static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS]; +static volatile voidFuncPtrParam intFunc[EXTERNAL_NUM_INTERRUPTS]; +static void* args[EXTERNAL_NUM_INTERRUPTS]; -void attachInterrupt(uint8_t pin, void (*userFunc)(void), PinStatus mode) { +void attachInterruptParam(pin_size_t pin, void (*userFunc)(void*), PinStatus mode, void* params) { /* Get bit position and check pin validity */ uint8_t bit_pos = digitalPinToBitPosition(pin); @@ -46,24 +47,27 @@ void attachInterrupt(uint8_t pin, void (*userFunc)(void), PinStatus mode) { /* Check interrupt number and apply function pointer to correct array index */ if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { intFunc[interruptNum] = userFunc; + args[interruptNum] = params; // Configure the interrupt mode (trigger on low input, any change, rising // edge, or falling edge). The mode constants were chosen to correspond // to the configuration bits in the hardware register, so we simply apply // the setting in the pin control register + int isc_mode; + switch (mode) { case CHANGE: - mode = PORT_ISC_BOTHEDGES_gc; + isc_mode = PORT_ISC_BOTHEDGES_gc; break; case FALLING: - mode = PORT_ISC_FALLING_gc; + isc_mode = PORT_ISC_FALLING_gc; break; case RISING: - mode = PORT_ISC_RISING_gc; + isc_mode = PORT_ISC_RISING_gc; break; case LOW: - mode = PORT_ISC_LEVEL_gc; + isc_mode = PORT_ISC_LEVEL_gc; break; default: // AVR doesn't support level triggered interrupts @@ -80,10 +84,14 @@ void attachInterrupt(uint8_t pin, void (*userFunc)(void), PinStatus mode) { *pin_ctrl_reg &= ~(PORT_ISC_gm); /* Apply ISC setting */ - *pin_ctrl_reg |= mode; + *pin_ctrl_reg |= isc_mode; } } +void attachInterrupt(uint8_t pin, void (*userFunc)(void), PinStatus mode) { + attachInterruptParam(pin, (voidFuncPtrParam)userFunc, mode, NULL); +} + void detachInterrupt(uint8_t pin) { /* Get bit position and check pin validity */ uint8_t bit_pos = digitalPinToBitPosition(pin); @@ -127,7 +135,7 @@ static void port_interrupt_handler(uint8_t port) { if(intFunc[interrupt_num] != 0){ /* Call function */ - intFunc[interrupt_num](); + intFunc[interrupt_num](args[interrupt_num]); } } bit_pos++; diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index c5a715b5..cda2b4da 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -23,7 +23,6 @@ */ #include "wiring_private.h" -#include "pins_arduino.h" #include "Arduino.h" uint8_t analog_reference = DEFAULT; diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 48a8a74c..d2c94f1c 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -24,8 +24,6 @@ #define SPI_IMODE_EXTINT 1 #define SPI_IMODE_GLOBAL 2 -const SPISettings DEFAULT_SPI_SETTINGS = SPISettings(); - SPIClass::SPIClass(uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, uint8_t uc_pinSS, uint8_t uc_mux) { initialized = false; @@ -66,7 +64,7 @@ void SPIClass::init() initialized = true; } -void SPIClass::config(SPISettings settings) +void SPIClass::config(SPISettingsMegaAVR settings) { SPI0.CTRLA = settings.ctrla; SPI0.CTRLB = settings.ctrlb; @@ -173,7 +171,7 @@ void SPIClass::reattachMaskedInterrupts() { } } -void SPIClass::beginTransaction(SPISettings settings) +void SPIClass::beginTransaction(SPISettingsMegaAVR settings) { if (interruptMode != SPI_IMODE_NONE) { diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index 18262c9d..38fbfb1b 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -31,7 +31,7 @@ // - endTransaction() // - usingInterrupt() // - SPISetting(clock, bitOrder, dataMode) -#define SPI_HAS_TRANSACTION 1 +// #define SPI_HAS_TRANSACTION 1 // SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method #define SPI_HAS_NOTUSINGINTERRUPT 1 @@ -52,9 +52,9 @@ #define EXTERNAL_NUM_INTERRUPTS NUM_TOTAL_PINS #endif -class SPISettings { +class SPISettingsMegaAVR : public arduino::SPISettings { public: - SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) { + SPISettingsMegaAVR(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) { if (__builtin_constant_p(clock)) { init_AlwaysInline(clock, bitOrder, dataMode); } else { @@ -63,7 +63,9 @@ class SPISettings { } // Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first. - SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); } + SPISettingsMegaAVR() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); } + + SPISettingsMegaAVR(SPISettings& x) { SPISettingsMegaAVR(x.getClockFreq(), x.getBitOrder(), x.getDataMode()); } private: void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) { @@ -142,12 +144,12 @@ class SPISettings { /* member variables containing the desired SPI settings */ uint8_t ctrla; uint8_t ctrlb; - friend class SPIClass; + friend class SPIClassMegaAVR; }; -class SPIClass { +class SPIClassMegaAVR : public arduino::HardwareSPI { public: - SPIClass(uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, uint8_t uc_pinSS, uint8_t uc_mux); + SPIClassMegaAVR(uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, uint8_t uc_pinSS, uint8_t uc_mux); byte transfer(uint8_t data); uint16_t transfer16(uint16_t data); @@ -156,7 +158,10 @@ class SPIClass { // Transaction Functions void usingInterrupt(int interruptNumber); void notUsingInterrupt(int interruptNumber); - void beginTransaction(SPISettings settings); + void beginTransaction(SPISettingsMegaAVR settings); + void beginTransaction(SPISettings settings) { + beginTransaction(SPISettingsMegaAVR(settings)); + } void endTransaction(void); void begin(); @@ -169,13 +174,16 @@ class SPIClass { private: void init(); - void config(SPISettings settings); + void config(SPISettingsMegaAVR settings); + void config(SPISettings settings) { + config(SPISettingsMegaAVR(settings)); + } // These undocumented functions should not be used. SPI.transfer() // polls the hardware flag which is automatically cleared as the // AVR responds to SPI's interrupt - inline static void attachInterrupt() { SPI0.INTCTRL |= (SPI_IE_bm); } - inline static void detachInterrupt() { SPI0.INTCTRL &= ~(SPI_IE_bm); } + inline void attachInterrupt() { SPI0.INTCTRL |= (SPI_IE_bm); } + inline void detachInterrupt() { SPI0.INTCTRL &= ~(SPI_IE_bm); } void detachMaskedInterrupts(); void reattachMaskedInterrupts(); @@ -199,6 +207,7 @@ class SPIClass { #endif }; +#define SPIClass SPIClassMegaAVR #if SPI_INTERFACES_COUNT > 0 extern SPIClass SPI; diff --git a/variants/nona4809/pins_arduino.h b/variants/nona4809/pins_arduino.h index 39c3794f..589dc2ae 100644 --- a/variants/nona4809/pins_arduino.h +++ b/variants/nona4809/pins_arduino.h @@ -273,7 +273,6 @@ const uint8_t analog_pin_to_channel[] = { #endif -extern const uint8_t analog_pin_to_channel[]; #define digitalPinToAnalogInput(p) ((p < ANALOG_INPUT_OFFSET) ? analog_pin_to_channel[p] : analog_pin_to_channel[p - ANALOG_INPUT_OFFSET] ) // These serial port names are intended to allow libraries and architecture-neutral