From 3cd1d4e60679b0d6222f945ff06942f8b9350c30 Mon Sep 17 00:00:00 2001 From: Thibaut VIARD <thibaut.viard@atmel.com> Date: Thu, 15 May 2014 00:07:03 +0200 Subject: [PATCH] Bringing support of External Interrupts --- cores/arduino/Arduino.h | 17 -- cores/arduino/WInterrupts.c | 230 ++++++++++++++++++ cores/arduino/WInterrupts.c.disabled | 182 -------------- cores/arduino/WInterrupts.h | 53 +++- cores/arduino/WVariant.h | 66 ++++- cores/arduino/wiring_analog.c | 12 +- cores/arduino/wiring_constants.h | 18 +- cores/arduino/wiring_digital.h | 10 +- .../validation_core/build_as6/test.cppproj | 4 + cores/validation/validation_core/test.cpp | 85 ++++++- variants/arduino_zero/variant.cpp | 92 +++---- variants/arduino_zero/variant.h | 2 +- 12 files changed, 496 insertions(+), 275 deletions(-) create mode 100644 cores/arduino/WInterrupts.c delete mode 100644 cores/arduino/WInterrupts.c.disabled diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index ee106b5b..f550858b 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -53,23 +53,6 @@ void yield( void ) ; void setup( void ) ; void loop( void ) ; -#define NOT_AN_INTERRUPT -1 - -typedef enum _EExt_Interrupts -{ - EXTERNAL_INT_0=0, - EXTERNAL_INT_1=1, - EXTERNAL_INT_2=2, - EXTERNAL_INT_3=3, - EXTERNAL_INT_4=4, - EXTERNAL_INT_5=5, - EXTERNAL_INT_6=6, - EXTERNAL_INT_7=7, - EXTERNAL_NUM_INTERRUPTS -} EExt_Interrupts ; - -typedef void (*voidFuncPtr)( void ) ; - #include "WVariant.h" #ifdef __cplusplus diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c new file mode 100644 index 00000000..6bbdf362 --- /dev/null +++ b/cores/arduino/WInterrupts.c @@ -0,0 +1,230 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "WInterrupts.h" +#include "variant.h" +#include "wiring_digital.h" + +#include <string.h> + +#ifdef __cplusplus +extern "C" { +#endif + +static struct +{ + uint32_t _ulPin ; + voidFuncPtr _callback ; +} callbacksInt[EXTERNAL_NUM_INTERRUPTS] ; + +/* Configure I/O interrupt sources */ +static void __initialize() +{ +#if 0 + int i ; + + for ( i = 0 ; i < EXTERNAL_NUM_INTERRUPTS ; i++ ) + { + callbacksInt[i]._callback = NULL ; + } +#else + memset( callbacksInt, 0, sizeof( callbacksInt ) ) ; +#endif + + NVIC_DisableIRQ( EIC_IRQn ) ; + NVIC_ClearPendingIRQ( EIC_IRQn ) ; + NVIC_SetPriority( EIC_IRQn, 0 ) ; + NVIC_EnableIRQ( EIC_IRQn ) ; + + // Enable GCLK for IEC (External Interrupt Controller) + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_EIC )) ; + +/* Shall we do that? + // Do a software reset on EIC + EIC->CTRL.SWRST.bit = 1 ; + + while ( (EIC->CTRL.SWRST.bit == 1) && (EIC->STATUS.SYNCBUSY.bit == 1) ) + { + // Wait for synchronisation + } +*/ +} + +/* + * \brief Specifies a named Interrupt Service Routine (ISR) to call when an interrupt occurs. + * Replaces any previous function that was attached to the interrupt. + */ +//void attachInterrupt( uint32_t ulPin, void (*callback)(void), EExt_IntMode mode ) +//void attachInterrupt( uint32_t ulPin, voidFuncPtr callback, EExt_IntMode mode ) +void attachInterrupt( uint32_t ulPin, voidFuncPtr callback, uint32_t ulMode ) +{ + static int enabled = 0 ; + uint32_t ulConfig ; + uint32_t ulPos ; + + if ( digitalPinToInterrupt( ulPin ) == NOT_AN_INTERRUPT ) + { + return ; + } + + if ( !enabled ) + { + __initialize() ; + enabled = 1 ; + } + + // Assign pin to EIC + pinPeripheral( ulPin, PIO_EXTINT ) ; + + // Assign callback to interrupt + callbacksInt[digitalPinToInterrupt( ulPin )]._ulPin = ulPin ; + callbacksInt[digitalPinToInterrupt( ulPin )]._callback = callback ; + + // Check if normal interrupt or NMI + if ( ulPin != 2 ) + { + // Look for right CONFIG register to be addressed + if ( digitalPinToInterrupt( ulPin ) > EXTERNAL_INT_7 ) + { + ulConfig = 1 ; + } + else + { + ulConfig = 0 ; + } + + // Configure the interrupt mode + ulPos = ((digitalPinToInterrupt( ulPin ) >> ulConfig ) << 2) ; + switch ( ulMode ) + { + case LOW: + EIC->CONFIG[ulConfig].reg = EIC_CONFIG_SENSE0_LOW_Val << ulPos ; + break ; + + case HIGH: + EIC->CONFIG[ulConfig].reg = EIC_CONFIG_SENSE0_HIGH_Val << ((digitalPinToInterrupt( ulPin ) >> ulConfig ) << 2) ; + break ; + + case CHANGE: + EIC->CONFIG[ulConfig].reg = EIC_CONFIG_SENSE0_BOTH_Val << ((digitalPinToInterrupt( ulPin ) >> ulConfig ) << 2) ; + break ; + + case FALLING: + EIC->CONFIG[ulConfig].reg = EIC_CONFIG_SENSE0_FALL_Val << ((digitalPinToInterrupt( ulPin ) >> ulConfig ) << 2) ; + break ; + + case RISING: + EIC->CONFIG[ulConfig].reg = EIC_CONFIG_SENSE0_RISE_Val << ((digitalPinToInterrupt( ulPin ) >> ulConfig ) << 2) ; + break ; + } + + // Enable the interrupt + EIC->INTENSET.reg = EIC_INTENSET_EXTINT( 1 << digitalPinToInterrupt( ulPin ) ) ; + } + else // Handles NMI on pin 2 + { + // Configure the interrupt mode + switch ( ulMode ) + { + case LOW: + EIC->NMICTRL.reg = EIC_NMICTRL_NMISENSE_LOW ; + break ; + + case HIGH: + EIC->NMICTRL.reg = EIC_NMICTRL_NMISENSE_HIGH ; + break ; + + case CHANGE: + EIC->NMICTRL.reg = EIC_NMICTRL_NMISENSE_BOTH ; + break ; + + case FALLING: + EIC->NMICTRL.reg = EIC_NMICTRL_NMISENSE_FALL ; + break ; + + case RISING: + EIC->NMICTRL.reg= EIC_NMICTRL_NMISENSE_RISE ; + break ; + } + + // Enable the interrupt + EIC->INTENSET.reg = EIC_INTENSET_EXTINT( 1 << digitalPinToInterrupt( ulPin ) ) ; + } +} + +/* + * \brief Turns off the given interrupt. + */ +void detachInterrupt( uint32_t ulPin ) +{ +/* + // Retrieve pin information + Pio *pio = g_APinDescription[pin].pPort; + uint32_t mask = g_APinDescription[pin].ulPin; + + // Disable interrupt + pio->PIO_IDR = mask; +*/ + if ( digitalPinToInterrupt( ulPin ) == NOT_AN_INTERRUPT ) + { + return ; + } + + EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT( 1 << digitalPinToInterrupt( ulPin ) ) ; +} + +/* + * External Interrupt Controller NVIC Interrupt Handler + */ +void EIC_Handler( void ) +{ + uint32_t ul ; + + // Test NMI first + if ( (EIC->NMIFLAG.reg & EIC_NMIFLAG_NMI) == EIC_NMIFLAG_NMI ) + { + // Call the callback function if assigned + if ( callbacksInt[EXTERNAL_INT_NMI]._callback != NULL ) + { + callbacksInt[EXTERNAL_INT_NMI]._callback() ; + } + + // Clear the interrupt + EIC->NMIFLAG.reg = EIC_NMIFLAG_NMI ; + } + + // Test the 16 normal interrupts + for ( ul = EXTERNAL_INT_0 ; ul < EXTERNAL_INT_15 ; ul++ ) + { + if ( (EIC->INTFLAG.reg & 1 << ul) != 0 ) + { + // Call the callback function if assigned + if ( callbacksInt[ul]._callback != NULL ) + { + callbacksInt[ul]._callback() ; + } + + // Clear the interrupt + EIC->INTFLAG.reg = 1 << ul ; + } + } +} + +#ifdef __cplusplus +} +#endif diff --git a/cores/arduino/WInterrupts.c.disabled b/cores/arduino/WInterrupts.c.disabled deleted file mode 100644 index 87b83e45..00000000 --- a/cores/arduino/WInterrupts.c.disabled +++ /dev/null @@ -1,182 +0,0 @@ -/* - Copyright (c) 2011-2012 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "WInterrupts.h" - -typedef void (*interruptCB)(void); - -static interruptCB callbacksPioA[32]; -static interruptCB callbacksPioB[32]; -static interruptCB callbacksPioC[32]; -static interruptCB callbacksPioD[32]; - -/* Configure PIO interrupt sources */ -static void __initialize() { - int i; - for (i=0; i<32; i++) { - callbacksPioA[i] = NULL; - callbacksPioB[i] = NULL; - callbacksPioC[i] = NULL; - callbacksPioD[i] = NULL; - } - - pmc_enable_periph_clk(ID_PIOA); - NVIC_DisableIRQ(PIOA_IRQn); - NVIC_ClearPendingIRQ(PIOA_IRQn); - NVIC_SetPriority(PIOA_IRQn, 0); - NVIC_EnableIRQ(PIOA_IRQn); - - pmc_enable_periph_clk(ID_PIOB); - NVIC_DisableIRQ(PIOB_IRQn); - NVIC_ClearPendingIRQ(PIOB_IRQn); - NVIC_SetPriority(PIOB_IRQn, 0); - NVIC_EnableIRQ(PIOB_IRQn); - - pmc_enable_periph_clk(ID_PIOC); - NVIC_DisableIRQ(PIOC_IRQn); - NVIC_ClearPendingIRQ(PIOC_IRQn); - NVIC_SetPriority(PIOC_IRQn, 0); - NVIC_EnableIRQ(PIOC_IRQn); - - pmc_enable_periph_clk(ID_PIOD); - NVIC_DisableIRQ(PIOD_IRQn); - NVIC_ClearPendingIRQ(PIOD_IRQn); - NVIC_SetPriority(PIOD_IRQn, 0); - NVIC_EnableIRQ(PIOD_IRQn); -} - - -void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode) -{ - static int enabled = 0; - if (!enabled) { - __initialize(); - enabled = 1; - } - - // Retrieve pin information - Pio *pio = g_APinDescription[pin].pPort; - uint32_t mask = g_APinDescription[pin].ulPin; - uint32_t pos = 0; - - uint32_t t; - for (t = mask; t>1; t>>=1, pos++) - ; - - // Set callback function - if (pio == PIOA) - callbacksPioA[pos] = callback; - if (pio == PIOB) - callbacksPioB[pos] = callback; - if (pio == PIOC) - callbacksPioC[pos] = callback; - if (pio == PIOD) - callbacksPioD[pos] = callback; - - // Configure the interrupt mode - if (mode == CHANGE) { - // Disable additional interrupt mode (detects both rising and falling edges) - pio->PIO_AIMDR = mask; - } else { - // Enable additional interrupt mode - pio->PIO_AIMER = mask; - - // Select mode of operation - if (mode == LOW) { - pio->PIO_LSR = mask; // "Level" Select Register - pio->PIO_FELLSR = mask; // "Falling Edge / Low Level" Select Register - } - if (mode == HIGH) { - pio->PIO_LSR = mask; // "Level" Select Register - pio->PIO_REHLSR = mask; // "Rising Edge / High Level" Select Register - } - if (mode == FALLING) { - pio->PIO_ESR = mask; // "Edge" Select Register - pio->PIO_FELLSR = mask; // "Falling Edge / Low Level" Select Register - } - if (mode == RISING) { - pio->PIO_ESR = mask; // "Edge" Select Register - pio->PIO_REHLSR = mask; // "Rising Edge / High Level" Select Register - } - } - - // Enable interrupt - pio->PIO_IER = mask; -} - -void detachInterrupt(uint32_t pin) -{ - // Retrieve pin information - Pio *pio = g_APinDescription[pin].pPort; - uint32_t mask = g_APinDescription[pin].ulPin; - - // Disable interrupt - pio->PIO_IDR = mask; -} - -#ifdef __cplusplus -extern "C" { -#endif - -void PIOA_Handler(void) { - uint32_t isr = PIOA->PIO_ISR; - uint32_t i; - for (i=0; i<32; i++, isr>>=1) { - if ((isr & 0x1) == 0) - continue; - if (callbacksPioA[i]) - callbacksPioA[i](); - } -} - -void PIOB_Handler(void) { - uint32_t isr = PIOB->PIO_ISR; - uint32_t i; - for (i=0; i<32; i++, isr>>=1) { - if ((isr & 0x1) == 0) - continue; - if (callbacksPioB[i]) - callbacksPioB[i](); - } -} - -void PIOC_Handler(void) { - uint32_t isr = PIOC->PIO_ISR; - uint32_t i; - for (i=0; i<32; i++, isr>>=1) { - if ((isr & 0x1) == 0) - continue; - if (callbacksPioC[i]) - callbacksPioC[i](); - } -} - -void PIOD_Handler(void) { - uint32_t isr = PIOD->PIO_ISR; - uint32_t i; - for (i=0; i<32; i++, isr>>=1) { - if ((isr & 0x1) == 0) - continue; - if (callbacksPioD[i]) - callbacksPioD[i](); - } -} - -#ifdef __cplusplus -} -#endif diff --git a/cores/arduino/WInterrupts.h b/cores/arduino/WInterrupts.h index bb698cdf..8314dff2 100644 --- a/cores/arduino/WInterrupts.h +++ b/cores/arduino/WInterrupts.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2011-2012 Arduino. All right reserved. + Copyright (c) 2014 Arduino. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -8,7 +8,7 @@ This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public @@ -19,18 +19,61 @@ #ifndef _WIRING_INTERRUPTS_ #define _WIRING_INTERRUPTS_ -#include "Arduino.h" +#include <stdint.h> #ifdef __cplusplus extern "C" { #endif -void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode); +// LOW 0 +// HIGH 1 +#define CHANGE 2 +#define FALLING 3 +#define RISING 4 -void detachInterrupt(uint32_t pin); +///* + //* Interrupt modes + //* The two first values are conflicting with the ones used by Digital API, so we use another name for each. + //*/ +//typedef enum _EExt_IntMode +//{ + //IM_LOW = 0, + //IM_HIGH = 1, + //CHANGE = 2, + //FALLING = 3, + //RISING = 4, + //IM_CHANGE = 2, + //IM_FALLING = 3, + //IM_RISING = 4, +//} EExt_IntMode ; + +#define DEFAULT 1 +#define EXTERNAL 0 + +typedef void (*voidFuncPtr)( void ) ; + +/* + * \brief Specifies a named Interrupt Service Routine (ISR) to call when an interrupt occurs. + * Replaces any previous function that was attached to the interrupt. + */ +//void attachInterrupt( uint32_t ulPin, void (*callback)(void), EExt_IntMode mode ) ; +//void attachInterrupt( uint32_t ulPin, voidFuncPtr callback, EExt_IntMode mode ) ; +void attachInterrupt( uint32_t ulPin, voidFuncPtr callback, uint32_t mode ) ; + +/* + * \brief Turns off the given interrupt. + */ +void detachInterrupt( uint32_t ulPin ) ; #ifdef __cplusplus } #endif +//#ifdef __cplusplus +//inline operator ::EExt_IntMode( uint32_t ul ) +//{ + //return (EExt_IntMode)ul ; +//} +//#endif + #endif /* _WIRING_INTERRUPTS_ */ diff --git a/cores/arduino/WVariant.h b/cores/arduino/WVariant.h index 2a05298d..295d7dc6 100644 --- a/cores/arduino/WVariant.h +++ b/cores/arduino/WVariant.h @@ -78,6 +78,29 @@ typedef enum _EPortType PORTC=2, } EPortType ; +typedef enum _EExt_Interrupts +{ + EXTERNAL_INT_0 = 0, // Available on pin 11 + EXTERNAL_INT_1, // Available on pin 13 + EXTERNAL_INT_2, // Available on pins 10, A0, A5 + EXTERNAL_INT_3, // Available on pin 12 + EXTERNAL_INT_4, // Available on pin 6, 8, A3 + EXTERNAL_INT_5, // Available on pin 7, 9, A4 + EXTERNAL_INT_6, // Available on pin 16 + EXTERNAL_INT_7, // Available on pin 17 + EXTERNAL_INT_8, // Available on pin A1 + EXTERNAL_INT_9, // Available on pin 3, A2 + EXTERNAL_INT_10, // Available on pin 0, 21 + EXTERNAL_INT_11, // Available on pin 1, 20 + EXTERNAL_INT_12, // Available on pin 18 + EXTERNAL_INT_13, // Available on pin EDBG_GPIO0 (43) + EXTERNAL_INT_14, // Available on pin 4 + EXTERNAL_INT_15, // Available on pin 5 + EXTERNAL_INT_NMI, // Available on pin 2 + EXTERNAL_NUM_INTERRUPTS, + NOT_AN_INTERRUPT = -1, + EXTERNAL_INT_NONE = NOT_AN_INTERRUPT, +} EExt_Interrupts ; //A B C D E F G H //EIC REF ADC AC PTC DAC SERCOM SERCOM_ALT TC/TCC TCC COM AC/GCLK @@ -111,6 +134,7 @@ typedef enum _EPioType #define PIN_ATTR_DIGITAL (1UL<<2) #define PIN_ATTR_PWM (1UL<<3) #define PIN_ATTR_TIMER (1UL<<4) +#define PIN_ATTR_EXTINT (1UL<<5) /* Types used for the table below */ typedef struct _PinDescription @@ -122,11 +146,51 @@ typedef struct _PinDescription EAnalogChannel ulADCChannelNumber ; /* ADC Channel number in the SAM device */ EPWMChannel ulPWMChannel ; ETCChannel ulTCChannel ; + EExt_Interrupts ulExtInt ; } PinDescription ; -/* Pins table to be instanciated into variant.cpp */ +/* Pins table to be instantiated into variant.cpp */ extern const PinDescription g_APinDescription[] ; +/* Generic Clock Multiplexer IDs */ +#define GCM_DFLL48M_REF (0x00U) +#define GCM_FDPLL96M_INPUT (0x01U) +#define GCM_FDPLL96M_32K (0x02U) +#define GCM_WDT (0x03U) +#define GCM_RTC (0x04U) +#define GCM_EIC (0x05U) +#define GCM_USB (0x06U) +#define GCM_EVSYS_CHANNEL_0 (0x07U) +#define GCM_EVSYS_CHANNEL_1 (0x08U) +#define GCM_EVSYS_CHANNEL_2 (0x09U) +#define GCM_EVSYS_CHANNEL_3 (0x0AU) +#define GCM_EVSYS_CHANNEL_4 (0x0BU) +#define GCM_EVSYS_CHANNEL_5 (0x0CU) +#define GCM_EVSYS_CHANNEL_6 (0x0DU) +#define GCM_EVSYS_CHANNEL_7 (0x0EU) +#define GCM_EVSYS_CHANNEL_8 (0x0FU) +#define GCM_EVSYS_CHANNEL_9 (0x10U) +#define GCM_EVSYS_CHANNEL_10 (0x11U) +#define GCM_EVSYS_CHANNEL_11 (0x12U) +#define GCM_SERCOMx_SLOW (0x13U) +#define GCM_SERCOM0_CORE (0x14U) +#define GCM_SERCOM1_CORE (0x15U) +#define GCM_SERCOM2_CORE (0x16U) +#define GCM_SERCOM3_CORE (0x17U) +#define GCM_SERCOM4_CORE (0x18U) +#define GCM_SERCOM5_CORE (0x19U) +#define GCM_TCC0_TCC1 (0x1AU) +#define GCM_TCC2_TC3 (0x1BU) +#define GCM_TC4_TC5 (0x1CU) +#define GCM_TC6_TC7 (0x1DU) +#define GCM_ADC (0x1EU) +#define GCM_AC_DIG (0x1FU) +#define GCM_AC_ANA (0x20U) +#define GCM_DAC (0x21U) +#define GCM_PTC (0x22U) +#define GCM_I2S_0 (0x23U) +#define GCM_I2S_1 (0x24U) + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 82ec417e..2a15282c 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -210,32 +210,32 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue ) { case 0: // TCC0 //Enable GCLK for TCC0 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( 0x1A )) ; + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ; break ; case 1: // TCC1 //Enable GCLK for TCC1 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( 0x1A )) ; + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ; break ; case 2: // TCC2 //Enable GCLK for TCC2 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( 0x1B )) ; + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ; break ; case 3: // TC3 //Enable GCLK for TC3 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( 0x1B )); + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )); break ; case 4: // TC4 //Enable GCLK for TC4 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( 0x1C )); + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 )); break ; case 5: // TC5 //Enable GCLK for TC5 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( 0x1C )) ; + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 )) ; break ; } diff --git a/cores/arduino/wiring_constants.h b/cores/arduino/wiring_constants.h index aac3734d..df1d7d58 100644 --- a/cores/arduino/wiring_constants.h +++ b/cores/arduino/wiring_constants.h @@ -49,14 +49,15 @@ enum BitOrder { MSBFIRST = 1 }; -// LOW 0 -// HIGH 1 -#define CHANGE 2 -#define FALLING 3 -#define RISING 4 - -#define DEFAULT 1 -#define EXTERNAL 0 +// moved to WInterrupts.h +//// LOW 0 +//// HIGH 1 +//#define CHANGE 2 +//#define FALLING 3 +//#define RISING 4 +// +//#define DEFAULT 1 +//#define EXTERNAL 0 // undefine stdlib's abs if encountered #ifdef abs @@ -97,7 +98,6 @@ typedef unsigned int word; typedef uint8_t boolean ; typedef uint8_t byte ; - #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/cores/arduino/wiring_digital.h b/cores/arduino/wiring_digital.h index 1db6cb56..e4a3ec11 100644 --- a/cores/arduino/wiring_digital.h +++ b/cores/arduino/wiring_digital.h @@ -23,12 +23,12 @@ extern "C" { #endif -#define INPUT (0x0) -#define OUTPUT (0x1) -#define INPUT_PULLUP (0x2) +#define INPUT (0x0ul) +#define OUTPUT (0x1ul) +#define INPUT_PULLUP (0x2ul) -#define LOW (0x0) -#define HIGH (0x1) +#define LOW (0x0ul) +#define HIGH (0x1ul) #include "WVariant.h" diff --git a/cores/validation/validation_core/build_as6/test.cppproj b/cores/validation/validation_core/build_as6/test.cppproj index 1f5cc024..935a7915 100644 --- a/cores/validation/validation_core/build_as6/test.cppproj +++ b/cores/validation/validation_core/build_as6/test.cppproj @@ -385,6 +385,10 @@ <SubType>compile</SubType> <Link>core\WCharacter.h</Link> </Compile> + <Compile Include="..\..\..\arduino\WInterrupts.c"> + <SubType>compile</SubType> + <Link>core\WInterrupts.c</Link> + </Compile> <Compile Include="..\..\..\arduino\WInterrupts.h"> <SubType>compile</SubType> <Link>core\WInterrupts.h</Link> diff --git a/cores/validation/validation_core/test.cpp b/cores/validation/validation_core/test.cpp index f571465c..0e2a384d 100644 --- a/cores/validation/validation_core/test.cpp +++ b/cores/validation/validation_core/test.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2011 Arduino. All right reserved. + Copyright (c) 2014 Arduino. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -18,6 +18,18 @@ #include "Arduino.h" +static void Interrupt_Pin3( void ) ; // Ext Int Callback in LOW mode +static void Interrupt_Pin4( void ) ; // Ext Int Callback in HIGH mode +static void Interrupt_Pin5( void ) ; // Ext Int Callback in FALLING mode +static void Interrupt_Pin6( void ) ; // Ext Int Callback in RISING mode +static void Interrupt_Pin7( void ) ; // Ext Int Callback in CHANGE mode + +static uint32_t ul_Interrupt_Pin3 = 0 ; +static uint32_t ul_Interrupt_Pin4 = 0 ; +static uint32_t ul_Interrupt_Pin5 = 0 ; +static uint32_t ul_Interrupt_Pin6 = 0 ; +static uint32_t ul_Interrupt_Pin7 = 0 ; + void setup( void ) { // Initialize the digital pin as an output. @@ -45,6 +57,13 @@ void setup( void ) //********************************************** Serial5.begin( 115200 ) ; // Output to EDBG Virtual COM Port + + // Test External Interrupt + attachInterrupt( 3, Interrupt_Pin3, LOW ) ; + attachInterrupt( 4, Interrupt_Pin4, HIGH ) ; + attachInterrupt( 5, Interrupt_Pin5, FALLING ) ; + attachInterrupt( 6, Interrupt_Pin6, RISING ) ; + attachInterrupt( 7, Interrupt_Pin7, CHANGE) ; } static void led_step1( void ) @@ -93,11 +112,10 @@ void loop( void ) analogWrite( 6, duty_cycle ) ; analogWrite( 5, duty_cycle ) ; analogWrite( 4, duty_cycle ) ; - analogWrite( 3, duty_cycle ) ; Serial5.print("Analog pins: "); - for ( int i = A1 ; i <= A0+NUM_ANALOG_INPUTS ; i++ ) + for ( uint32_t i = A1 ; i <= A0+NUM_ANALOG_INPUTS ; i++ ) { /* int a = analogRead(i); @@ -106,4 +124,65 @@ void loop( void ) */ } Serial5.println(); + + Serial5.println("External interrupt pins:"); + if ( ul_Interrupt_Pin3 == 1 ) + { + Serial5.println( "Pin 3 triggered (LOW)" ) ; + ul_Interrupt_Pin3 = 0 ; + } + + if ( ul_Interrupt_Pin4 == 1 ) + { + Serial5.println( "Pin 4 triggered (HIGH)" ) ; + ul_Interrupt_Pin4 = 0 ; + } + + if ( ul_Interrupt_Pin5 == 1 ) + { + Serial5.println( "Pin 5 triggered (FALLING)" ) ; + ul_Interrupt_Pin5 = 0 ; + } + + if ( ul_Interrupt_Pin6 == 1 ) + { + Serial5.println( "Pin 6 triggered (RISING)" ) ; + ul_Interrupt_Pin6 = 0 ; + } + + if ( ul_Interrupt_Pin7 == 1 ) + { + Serial5.println( "Pin 3 triggered (CHANGE)" ) ; + ul_Interrupt_Pin7 = 0 ; + } +} + +// Ext Int Callback in LOW mode +static void Interrupt_Pin3( void ) +{ + ul_Interrupt_Pin3 = 1 ; +} + +// Ext Int Callback in HIGH mode +static void Interrupt_Pin4( void ) +{ + ul_Interrupt_Pin4 = 1 ; +} + +// Ext Int Callback in CHANGE mode +static void Interrupt_Pin5( void ) +{ + ul_Interrupt_Pin5 = 1 ; +} + +// Ext Int Callback in FALLING mode +static void Interrupt_Pin6( void ) +{ + ul_Interrupt_Pin6 = 1 ; +} + +// Ext Int Callback in RISING mode +static void Interrupt_Pin7( void ) +{ + ul_Interrupt_Pin7 = 1 ; } diff --git a/variants/arduino_zero/variant.cpp b/variants/arduino_zero/variant.cpp index 8bf63478..27ff3791 100644 --- a/variants/arduino_zero/variant.cpp +++ b/variants/arduino_zero/variant.cpp @@ -108,85 +108,85 @@ const PinDescription g_APinDescription[]= // 0 .. 19 - Digital pins // ---------------------- // 0/1 - SERCOM/UART (Serial1) - { PORTA, 10, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // RX: SERCOM0/PAD[2] - { PORTA, 11, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // TX: SERCOM0/PAD[3] + { PORTA, 10, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // RX: SERCOM0/PAD[2] + { PORTA, 11, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // TX: SERCOM0/PAD[3] // 2..12 - { PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0 }, // TCC0/WO[0] - { PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1 }, // TCC0/WO[1] - { PORTA, 14, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH4, TCC0_CH4 }, // TCC0/WO[4] - { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH5, TCC0_CH5 }, // TCC0/WO[5] - { PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH6, TCC0_CH6 }, // TCC0/WO[6] - { PORTA, 21, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH7, TCC0_CH7 }, // TCC0/WO[7] - { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH0, TCC1_CH0 }, // TCC1/WO[0] - { PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH1, TCC1_CH1 }, // TCC1/WO[1] - { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0 }, // TC3/WO[0] - { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0 }, // TCC2/WO[0] - { PORTA, 19, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1 }, // TC3/WO[1] + { PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + { PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + { PORTA, 14, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH4, TCC0_CH4, EXTERNAL_INT_14 }, // TCC0/WO[4] + { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH5, TCC0_CH5, EXTERNAL_INT_15 }, // TCC0/WO[5] + { PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_4 }, // TCC0/WO[6] + { PORTA, 21, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_5 }, // TCC0/WO[7] + { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_4 }, // TCC1/WO[0] + { PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_5 }, // TCC1/WO[1] + { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // TC3/WO[0] + { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // TCC2/WO[0] + { PORTA, 19, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_3 }, // TC3/WO[1] // 13 (LED) - { PORTA, 17, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM2_CH1, NOT_ON_TIMER }, // TCC2/WO[1] + { PORTA, 17, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM2_CH1, NOT_ON_TIMER, EXTERNAL_INT_1 }, // TCC2/WO[1] // 14 (GND) - { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // 15 (AREF) - { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // DAC/VREFP + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP // 16..17 I2C (SDA/SCL and also EDBG:SDA/SCL) - { PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SDA: SERCOM3/PAD[0] - { PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SCL: SERCOM3/PAD[1] + { PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // SCL: SERCOM3/PAD[1] // 18..23 SPI (ICSP:MISO,SCK,MOSI) - { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // MISO: SERCOM4/PAD[0] - { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // 5V0 - { PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SCK: SERCOM4/PAD[3] - { PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI: SERCOM4/PAD[2] - { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // RESET - { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // GND + { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0] + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // 5V0 + { PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3] + { PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2] + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // RESET + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // GND // 24..29 - Analog pins // -------------------- // 24 - A0 (DAC output) - { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER }, // DAC/VOUT + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT // 25..29 - A1-A5 - { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[2] - { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[3] - { PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[4] - { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[5] - { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER }, // ADC/AIN[10] + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // ADC/AIN[2] + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // ADC/AIN[3] + { PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // ADC/AIN[4] + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // ADC/AIN[5] + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[10] // 30..31 - RX/TX LEDS (PB03/PA27) - { PORTB, 3, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // use as pure output + { PORTB, 3, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // use as pure output { PORTA, 27, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // use as pure output // 32..33 - USB - { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // USB/SOF - { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // USB/DM - { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // USB/DP + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/SOF + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP // 35 .. 46 - EDBG // ---------------------- // 35/36 - EDBG/UART - { PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // TX: SERCOM5/PAD[2] - { PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // RX: SERCOM5/PAD[3] + { PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // TX: SERCOM5/PAD[2] + { PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // RX: SERCOM5/PAD[3] // 37/38 I2C (SDA/SCL and also EDBG:SDA/SCL) - { PORTA, 22, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SDA: SERCOM3/PAD[0] - { PORTA, 23, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SCL: SERCOM3/PAD[1] + { PORTA, 22, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SCL: SERCOM3/PAD[1] // 39 .. 42 - EDBG/SPI - { PORTA, 19, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // MISO: SERCOM1/PAD[3] - { PORTA, 16, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI: SERCOM1/PAD[0] - { PORTA, 18, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SS: SERCOM1/PAD[2] - { PORTA, 17, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER }, // SCK: SERCOM1/PAD[1] + { PORTA, 19, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // MISO: SERCOM1/PAD[3] + { PORTA, 16, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // MOSI: SERCOM1/PAD[0] + { PORTA, 18, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SS: SERCOM1/PAD[2] + { PORTA, 17, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SCK: SERCOM1/PAD[1] // 43 .. 46 - EDBG/Digital - { PORTA, 13, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH5, NOT_ON_TIMER }, // EIC/EXTINT[13] *TCC2/WO[1] TCC0/WO[7] - { PORTA, 21, PIO_PWM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH7, NOT_ON_TIMER }, // Pin 7 - { PORTA, 6, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH0, NOT_ON_TIMER }, // Pin 8 - { PORTA, 7, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH1, NOT_ON_TIMER }, // Pin 9 + { PORTA, 13, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH5, NOT_ON_TIMER, EXTERNAL_INT_13 }, // EIC/EXTINT[13] *TCC2/WO[1] TCC0/WO[7] + { PORTA, 21, PIO_PWM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH7, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 7 + { PORTA, 6, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH0, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 8 + { PORTA, 7, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH1, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 9 } ; const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; diff --git a/variants/arduino_zero/variant.h b/variants/arduino_zero/variant.h index aa76bd06..a9ef5bda 100644 --- a/variants/arduino_zero/variant.h +++ b/variants/arduino_zero/variant.h @@ -70,7 +70,7 @@ extern "C"{ #define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) // Interrupts -#define digitalPinToInterrupt(p) (-1) // ((p) < NUM_DIGITAL_PINS ? (p) : -1) +#define digitalPinToInterrupt(P) ( g_APinDescription[P].ulExtInt ) // LEDs #define PIN_LED_13 (13u) -- GitLab