diff --git a/arch/arm/include/samdl/samd21_irq.h b/arch/arm/include/samdl/samd21_irq.h index e0b26bf962a..8c44ed256d8 100644 --- a/arch/arm/include/samdl/samd21_irq.h +++ b/arch/arm/include/samdl/samd21_irq.h @@ -86,9 +86,9 @@ #define SAM_IRQ_NINTS (28) /* Total number of interrupts */ #define SAM_IRQ_NIRQS (SAM_IRQ_INTERRUPT+28) /* The number of real interrupts */ -/* GPIO interrupts. Up to 16 pins may be configured to support interrupts */ +/* EIC interrupts. Up to 16 pins may be configured to support interrupts */ -#ifdef CONFIG_SAMDL_GPIOIRQ +#ifdef CONFIG_SAMDL_EIC # define SAM_IRQ_EXTINT0 (SAM_IRQ_NIRQS+0) /* External interrupt 0 */ # define SAM_IRQ_EXTINT1 (SAM_IRQ_NIRQS+1) /* External interrupt 1 */ # define SAM_IRQ_EXTINT2 (SAM_IRQ_NIRQS+2) /* External interrupt 2 */ diff --git a/arch/arm/src/samdl/Kconfig b/arch/arm/src/samdl/Kconfig index ec8507a048b..9813e7192dc 100644 --- a/arch/arm/src/samdl/Kconfig +++ b/arch/arm/src/samdl/Kconfig @@ -572,6 +572,10 @@ config SAMDL_USB default n depends on SAMDL_HAVE_USB +config SAMDL_EIC + bool "External Interrupt Controller" + default n + config SAMDL_WDT bool "Watchdog Timer" default n diff --git a/arch/arm/src/samdl/Make.defs b/arch/arm/src/samdl/Make.defs index 71b156c6c77..1ce9c0e5b8e 100644 --- a/arch/arm/src/samdl/Make.defs +++ b/arch/arm/src/samdl/Make.defs @@ -102,3 +102,7 @@ endif ifeq ($(CONFIG_SAMDL_USB),y) CHIP_CSRCS += sam_usb.c endif + +ifeq ($(CONFIG_SAMDL_EIC),y) +CHIP_CSRCS += sam_eic.c +endif diff --git a/arch/arm/src/samdl/chip/samd_eic.h b/arch/arm/src/samdl/chip/samd_eic.h new file mode 100644 index 00000000000..9bbd0dc4feb --- /dev/null +++ b/arch/arm/src/samdl/chip/samd_eic.h @@ -0,0 +1,191 @@ +/******************************************************************************************** + * arch/arm/src/samdl/chip/samd_eic.h + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Matt Thompson + * + * References: + * "Microchip SAMD21 datasheet" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_EIC_H +#define __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_EIC_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +#ifdef CONFIG_ARCH_FAMILY_SAMD21 + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ +/* EIC register offsets *********************************************************************/ + +#define SAM_EIC_CTRLA_OFFSET 0x0000 /* Control A register */ +#define SAM_EIC_STATUS_OFFSET 0x0001 /* Status register */ +#define SAM_EIC_NMICTRL_OFFSET 0x0002 /* Non-maskable interrupt control register */ +#define SAM_EIC_NMIFLAG_OFFSET 0x0003 /* Non-maskable interrupt flag register */ +#define SAM_EIC_EVCTRL_OFFSET 0x0004 /* Event control register */ +#define SAM_EIC_INTENCLR_OFFSET 0x0008 /* Interrupt enable clear register */ +#define SAM_EIC_INTENSET_OFFSET 0x000c /* Interrupt enable set register */ +#define SAM_EIC_INTFLAG_OFFSET 0x0010 /* Interrupt flag and status clear register */ +#define SAM_EIC_WAKEUP_OFFSET 0x0014 /* Wakeup register */ +#define SAM_EIC_CONFIG0_OFFSET 0x0018 /* Configuration 0 register */ +#define SAM_EIC_CONFIG1_OFFSET 0x001c /* Configuration 1 register */ +#define SAM_EIC_CONFIG2_OFFSET 0x0020 /* Configuration 2 register */ + +/* EIC register addresses *******************************************************************/ + +#define SAM_EIC_CTRLA (SAM_EIC_BASE+SAM_EIC_CTRLA_OFFSET) +#define SAM_EIC_STATUS (SAM_EIC_BASE+SAM_EIC_STATUS_OFFSET) +#define SAM_EIC_NMICTRL (SAM_EIC_BASE+SAM_EIC_NMICTRL_OFFSET) +#define SAM_EIC_NMIFLAG (SAM_EIC_BASE+SAM_EIC_NMIFLAG_OFFSET) +#define SAM_EIC_EVCTRL (SAM_EIC_BASE+SAM_EIC_EVCTRL_OFFSET) +#define SAM_EIC_INTENCLR (SAM_EIC_BASE+SAM_EIC_INTENCLR_OFFSET) +#define SAM_EIC_INTENSET (SAM_EIC_BASE+SAM_EIC_INTENSET_OFFSET) +#define SAM_EIC_INTFLAG (SAM_EIC_BASE+SAM_EIC_INTFLAG_OFFSET) +#define SAM_EIC_WAKEUP (SAM_EIC_BASE+SAM_EIC_WAKEUP_OFFSET) +#define SAM_EIC_CONFIG0 (SAM_EIC_BASE+SAM_EIC_CONFIG0_OFFSET) +#define SAM_EIC_CONFIG1 (SAM_EIC_BASE+SAM_EIC_CONFIG1_OFFSET) +#define SAM_EIC_CONFIG2 (SAM_EIC_BASE+SAM_EIC_CONFIG2_OFFSET) + +/* EIC register bit definitions *************************************************************/ + +/* Control A register */ + +#define EIC_CTRLA_SWRST (1 << 0) /* Bit 0: Software reset */ +#define EIC_CTRLA_ENABLE (1 << 1) /* Bit 1: Enable */ + +/* Status register */ + +#define EIC_STATUS_SYNCBUSY (1 << 7) /* Bit 7: Syncronization busy */ + +/* Non-maskable interrupt control register */ + +#define EIC_NMICTRL_NMISENSE_SHIFT (0) /* Bits 0-2: Non-maskable interrupt sense */ +#define EIC_NMICTRL_NMISENSE_MASK (7 << EIC_NVMICTRL_NMISENSE_SHIFT) +# define EIC_NMICTRL_NMISENSE_NONE (0 << EIC_NVMICTRL_NMISENSE_SHIFT) /* No detection */ +# define EIC_NMICTRL_NMISENSE_RISE (1 << EIC_NVMICTRL_NMISENSE_SHIFT) /* Rising edge detection */ +# define EIC_NMICTRL_NMISENSE_FALL (2 << EIC_NVMICTRL_NMISENSE_SHIFT) /* Falling edge detection */ +# define EIC_NMICTRL_NMISENSE_BOTH (3 << EIC_NVMICTRL_NMISENSE_SHIFT) /* Both edge detection */ +# define EIC_NMICTRL_NMISENSE_HIGH (4 << EIC_NVMICTRL_NMISENSE_SHIFT) /* High level detection */ +# define EIC_NMICTRL_NMISENSE_LOW (5 << EIC_NVMICTRL_NMISENSE_SHIFT) /* Low level detection */ +#define EIC_NMICTRL_NMIFLTEN (1 << 3) /* Bit 3: Non-maskable interrupt filter enable */ + +/* Non-maskable interrupt flas status and clear register */ + +#define EIC_NMIFLAG_NMI (1 << 0) /* Non-maskable interrupt */ + +/* Event control, Interrupt enable clear, interrupt enable set register, interrupt flag + * status and clear, and external interrupt wakeup registers. + */ + +#define EIC_EXTINT_SHIFT (0) /* Bits 0-15: External interrupt n */ +#define EIC_EXTINT_MASK (0x3ffff << EIC_EXTINT_SHIFT) +//# define EIC_EXTINT(n) ((uint32_t)(n) << EIC_EXTINT_SHIFT) +# define EIC_EXTINT(n) (1 << (n)) +# define EIC_EXTINT_0 (1 << 0) /* Bit 0: External interrupt 0 */ +# define EIC_EXTINT_1 (1 << 1) /* Bit 1: External interrupt 1 */ +# define EIC_EXTINT_2 (1 << 2) /* Bit 2: External interrupt 2 */ +# define EIC_EXTINT_3 (1 << 3) /* Bit 3: External interrupt 3 */ +# define EIC_EXTINT_4 (1 << 4) /* Bit 4: External interrupt 4 */ +# define EIC_EXTINT_5 (1 << 5) /* Bit 5: External interrupt 5 */ +# define EIC_EXTINT_6 (1 << 6) /* Bit 6: External interrupt 6 */ +# define EIC_EXTINT_7 (1 << 7) /* Bit 7: External interrupt 7 */ +# define EIC_EXTINT_8 (1 << 8) /* Bit 8: External interrupt 8 */ +# define EIC_EXTINT_9 (1 << 9) /* Bit 9: External interrupt 9 */ +# define EIC_EXTINT_10 (1 << 10) /* Bit 10: External interrupt 10 */ +# define EIC_EXTINT_11 (1 << 11) /* Bit 11: External interrupt 11 */ +# define EIC_EXTINT_12 (1 << 12) /* Bit 12: External interrupt 12 */ +# define EIC_EXTINT_13 (1 << 13) /* Bit 13: External interrupt 13 */ +# define EIC_EXTINT_14 (1 << 14) /* Bit 14: External interrupt 14 */ +# define EIC_EXTINT_15 (1 << 15) /* Bit 15: External interrupt 15 */ +# define EIC_EXTINT_16 (1 << 16) /* Bit 16: External interrupt 16 */ +# define EIC_EXTINT_17 (1 << 17) /* Bit 17: External interrupt 17 */ + +#define EIC_EXTINT_ALL EIC_EXTINT_MASK + +/* Configuration 0 register */ + +#define EIC_CONFIG0_FILTEN(n) (0x8 << ((n) << 2)) /* Filter n enable, n=0-7 */ +#define EIC_CONFIG0_SENSE_SHIFT(n) ((n) << 2) /* Filter n input sense, n=0-7 */ +#define EIC_CONFIG0_SENSE_MASK(n) (7 << EIC_CONFIG0_SENSE_SHIFT(n)) +# define EIC_CONFIG0_SENSE_NONE(n) (0 << EIC_CONFIG0_SENSE_SHIFT(n)) /* No detection */ +# define EIC_CONFIG0_SENSE_RISE(n) (1 << EIC_CONFIG0_SENSE_SHIFT(n)) /* Rising edge detection */ +# define EIC_CONFIG0_SENSE_FALL(n) (2 << EIC_CONFIG0_SENSE_SHIFT(n)) /* Falling edge detection */ +# define EIC_CONFIG0_SENSE_BOTH(n) (3 << EIC_CONFIG0_SENSE_SHIFT(n)) /* Both edge detection */ +# define EIC_CONFIG0_SENSE_HIGH(n) (4 << EIC_CONFIG0_SENSE_SHIFT(n)) /* High level detection */ +# define EIC_CONFIG0_SENSE_LOW(n) (5 << EIC_CONFIG0_SENSE_SHIFT(n)) /* Low level detection */ + +/* Configuration 1 register */ + +#define EIC_CONFIG1_FILTEN(n) (0x8 << (((n) - 8) << 2)) /* Filter n enable, n=8-15 */ +#define EIC_CONFIG1_SENSE_SHIFT(n) (((n) - 8) << 2) /* Filter n input sense, n=8-17 */ +#define EIC_CONFIG1_SENSE_MASK(n) (7 << EIC_CONFIG1_SENSE_SHIFT(n)) +# define EIC_CONFIG1_SENSE_NONE(n) (0 << EIC_CONFIG1_SENSE_SHIFT(n)) /* No detection */ +# define EIC_CONFIG1_SENSE_RISE(n) (1 << EIC_CONFIG1_SENSE_SHIFT(n)) /* Rising edge detection */ +# define EIC_CONFIG1_SENSE_FALL(n) (2 << EIC_CONFIG1_SENSE_SHIFT(n)) /* Falling edge detection */ +# define EIC_CONFIG1_SENSE_BOTH(n) (3 << EIC_CONFIG1_SENSE_SHIFT(n)) /* Both edge detection */ +# define EIC_CONFIG1_SENSE_HIGH(n) (4 << EIC_CONFIG1_SENSE_SHIFT(n)) /* High level detection */ +# define EIC_CONFIG1_SENSE_LOW(n) (5 << EIC_CONFIG1_SENSE_SHIFT(n)) /* Low level detection */ + +/* Configuration 2 register */ + +#define EIC_CONFIG2_FILTEN(n) (0x8 << (((n) - 16) << 2)) /* Filter n enable, n=16-23 */ +#define EIC_CONFIG2_SENSE_SHIFT(n) (((n) - 16) << 2) /* Filter n input sense, n=16-23 */ +#define EIC_CONFIG2_SENSE_MASK(n) (7 << EIC_CONFIG2_SENSE_SHIFT(n)) +# define EIC_CONFIG2_SENSE_NONE(n) (0 << EIC_CONFIG2_SENSE_SHIFT(n)) /* No detection */ +# define EIC_CONFIG2_SENSE_RISE(n) (1 << EIC_CONFIG2_SENSE_SHIFT(n)) /* Rising edge detection */ +# define EIC_CONFIG2_SENSE_FALL(n) (2 << EIC_CONFIG2_SENSE_SHIFT(n)) /* Falling edge detection */ +# define EIC_CONFIG2_SENSE_BOTH(n) (3 << EIC_CONFIG2_SENSE_SHIFT(n)) /* Both edge detection */ +# define EIC_CONFIG2_SENSE_HIGH(n) (4 << EIC_CONFIG2_SENSE_SHIFT(n)) /* High level detection */ +# define EIC_CONFIG2_SENSE_LOW(n) (5 << EIC_CONFIG2_SENSE_SHIFT(n)) /* Low level detection */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +/******************************************************************************************** + * Public Data + ********************************************************************************************/ + +/******************************************************************************************** + * Public Functions + ********************************************************************************************/ + +#endif /* CONFIG_ARCH_FAMILY_SAMD21 */ +#endif /* __ARCH_ARM_SRC_SAMDL_CHIP_SAMD_EIC_H */ diff --git a/arch/arm/src/samdl/sam_eic.c b/arch/arm/src/samdl/sam_eic.c new file mode 100644 index 00000000000..e6661548384 --- /dev/null +++ b/arch/arm/src/samdl/sam_eic.c @@ -0,0 +1,211 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_eic.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Matt Thompson + * + * References: + * 1. "Microchip SAM D21E / SAM D21G / SAM D21J Datasheet" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_arch.h" + +#include "sam_config.h" + +#include "sam_pm.h" +#include "sam_gclk.h" +#include "sam_periphclks.h" +#include "sam_eic.h" +#include "sam_port.h" + +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int sam_eic_isr(int irq, FAR void *context, FAR void *arg) +{ + uint32_t intflag; + int bit; + + /* Get the pending interrupt flag register */ + + intflag = getreg32(SAM_EIC_INTFLAG); + + /* Dispatch the IRQ to the SAM_IRQ_EXTINTn handlers */ + + for(bit=0;bit> bit & 0x1) + { + irq_dispatch(SAM_IRQ_EXTINT0 + bit, context); + } + } + + /* Clear the pending interrupt flags */ + + putreg32(EIC_EXTINT_ALL, SAM_EIC_INTFLAG); + + return 0; +} + +static void sam_eic_syncwait(void) +{ + while ((getreg8(SAM_EIC_STATUS) & EIC_STATUS_SYNCBUSY) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void sam_eic_dumpregs(void) +{ + irqinfo("EIC:\n"); + irqinfo(" CTRLA: %02x\n", getreg8(SAM_EIC_CTRLA)); + irqinfo(" STATUS: %02x\n", getreg8(SAM_EIC_STATUS)); + irqinfo(" NMICTRL: %02x\n", getreg8(SAM_EIC_NMICTRL)); + irqinfo(" NMIFLAG: %02x\n", getreg8(SAM_EIC_NMIFLAG)); + irqinfo(" EVCTRL: %08x\n", getreg32(SAM_EIC_EVCTRL)); + irqinfo(" INTENCLR: %08x\n", getreg32(SAM_EIC_INTENCLR)); + irqinfo(" INTENSET: %08x\n", getreg32(SAM_EIC_INTENSET)); + irqinfo(" INTFLAG: %08x\n", getreg32(SAM_EIC_INTFLAG)); + irqinfo(" WAKEUP: %08x\n", getreg32(SAM_EIC_WAKEUP)); + irqinfo(" CONFIG0: %08x\n", getreg32(SAM_EIC_CONFIG0)); + irqinfo(" CONFIG1: %08x\n", getreg32(SAM_EIC_CONFIG1)); + irqinfo(" CONFIG2: %08x\n", getreg32(SAM_EIC_CONFIG2)); +} + +/**************************************************************************** + * Name: sam_eic_initialize + * + * Description: + * Configure the external interrupt controller. + * + ****************************************************************************/ + +int sam_eic_initialize(uint8_t gclkgen) +{ + uint16_t regval; + + sam_eic_enableperiph(); + + regval = GCLK_CLKCTRL_ID_EIC | GCLK_CLKCTRL_GEN(gclkgen) | GCLK_CLKCTRL_CLKEN; + putreg16(regval, SAM_GCLK_CLKCTRL); + + putreg8(EIC_CTRLA_ENABLE, SAM_EIC_CTRLA); + sam_eic_syncwait(); + + irq_attach(SAM_IRQ_EIC, sam_eic_isr, NULL); + + sam_eic_dumpregs(); + + up_enable_irq(SAM_IRQ_EIC); + + return OK; +} + +int sam_eic_irq_enable(int irq) +{ + uint32_t config; + int eirq = irq - SAM_IRQ_EXTINT0; + + config = getreg32(SAM_EIC_CONFIG0); + config |= EIC_CONFIG0_FILTEN(eirq) | EIC_CONFIG0_SENSE_FALL(eirq); + putreg32(config, SAM_EIC_CONFIG0); + + putreg32(EIC_EXTINT(eirq), SAM_EIC_INTENSET); + sam_eic_dumpregs(); + return OK; +} + +int sam_eic_config(uint8_t eirq, port_pinset_t pinset) +{ + uint32_t reg; + uint32_t val; + uint32_t config; + + /* Determine which of the CONFIG[0:2] registers to write to */ + + if(eirq < 8) + { + reg = SAM_EIC_CONFIG0; + + val = EIC_CONFIG0_SENSE_BOTH(eirq); + if(pinset & PORT_INT_RISING) + val = EIC_CONFIG0_SENSE_RISE(eirq); + if(pinset & PORT_INT_FALLING) + val = EIC_CONFIG0_SENSE_FALL(eirq); + val |= EIC_CONFIG0_FILTEN(eirq); + } + else if(eirq < 16) + { + reg = SAM_EIC_CONFIG1; + val = EIC_CONFIG1_FILTEN(eirq) | EIC_CONFIG1_SENSE_FALL(eirq); + } + else + { + reg = SAM_EIC_CONFIG2; + val = EIC_CONFIG2_FILTEN(eirq) | EIC_CONFIG2_SENSE_FALL(eirq); + } + + /* Write the new config to the CONFIGn register */ + + config = getreg32(reg); + config |= val; + putreg32(config, reg); + + /* Enable interrupt generation for this pin */ + + putreg32(EIC_EXTINT(eirq), SAM_EIC_INTENSET); + + sam_eic_dumpregs(); + + return OK; +} diff --git a/arch/arm/src/samdl/sam_eic.h b/arch/arm/src/samdl/sam_eic.h new file mode 100644 index 00000000000..b149d182ea2 --- /dev/null +++ b/arch/arm/src/samdl/sam_eic.h @@ -0,0 +1,109 @@ +/**************************************************************************** + * arch/arm/src/samdl/sam_eic.h + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Matt Thompson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMDL_SAM_EIC_H +#define __ARCH_ARM_SRC_SAMDL_SAM_EIC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sam_config.h" +#include "sam_port.h" + +#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21) +# include "chip/samd_eic.h" +#elif defined(CONFIG_ARCH_FAMILY_SAML21) +# include "chip/saml_eic.h" +#else +# error Unrecognized SAMD/L architecture +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_eic_configure + * + * Description: + * Configure the EIC + * + * Input Parameters: + * gclkgen - GCLK Generator + * + * Returned Value: + * None + * + ****************************************************************************/ + +int sam_eic_initialize(uint8_t gclkgen); +int sam_eic_config(uint8_t eirq, port_pinset_t pinset); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ARCH_ARM_SRC_SAMDL_SAM_EIC_H */ diff --git a/arch/arm/src/samdl/sam_port.c b/arch/arm/src/samdl/sam_port.c index b757de5c581..534ecef49cd 100644 --- a/arch/arm/src/samdl/sam_port.c +++ b/arch/arm/src/samdl/sam_port.c @@ -57,6 +57,7 @@ #include "chip.h" #include "sam_port.h" +#include "sam_eic.h" /**************************************************************************** * Private Data @@ -189,7 +190,27 @@ static inline void sam_configinput(uintptr_t base, port_pinset_t pinset) static inline void sam_configinterrupt(uintptr_t base, port_pinset_t pinset) { -#warning Missing logic + uint32_t func; + uint32_t regval; + int pin; + + pin = (pinset & PORT_PIN_MASK) >> PORT_PIN_SHIFT; + + regval = (PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_PMUXEN | PORT_WRCONFIG_INEN); + regval |= PORT_WRCONFIG_PINMASK(pin); + + func = (pinset & PORT_FUNC_MASK) >> PORT_FUNC_SHIFT; + regval |= (func << PORT_WRCONFIG_PMUX_SHIFT); + + putreg32(regval, base + SAM_PORT_WRCONFIG_OFFSET); + + /* Configure the interrupt edge sensitivity in CONFIGn register of the EIC */ + + sam_eic_config(pin, pinset); + +#ifdef CONFIG_DEBUG_GPIO_INFO + sam_dumpport(pinset, "extint"); +#endif } /**************************************************************************** @@ -531,7 +552,8 @@ int sam_dumpport(uint32_t pinset, const char *msg) /* Get the base address associated with the PIO port */ - pin = sam_portpin(pinset); + //pin = sam_portpin(pinset); + pin = (pinset & PORT_PIN_MASK) >> PORT_PIN_SHIFT; port = (pinset & PORT_MASK) >> PORT_SHIFT; base = SAM_PORTN_BASE(port);