diff --git a/arch/arm/src/nrf52/Kconfig b/arch/arm/src/nrf52/Kconfig index b104a5e0f77..3cdb76891b8 100644 --- a/arch/arm/src/nrf52/Kconfig +++ b/arch/arm/src/nrf52/Kconfig @@ -386,6 +386,24 @@ config NRF52_PROGMEM menu "GPIO Interrupt Configuration" +config NRF52_PER_PIN_INTERRUPTS + bool "Per-pin interrupt callbacks" + default n if DEFAULT_SMALL + default y if !DEFAULT_SMALL + depends on NRF52_GPIOTE + ---help--- + The GPIOTE peripheral supports a limited number of channels which can + be set to EVENT mode and thus generate interrupts on pin state changes. + Another mechanism offered by the GPIO/GPIOTE peripherals is the PORT + event. This event is generated from a signal shared by all pins in + the GPIO port. + + This option enables the ability to set per-pin callbacks that will + be invoked from the main GPIOTE ISR when a PORT event is generated. + As this involves extra storage to store each callback, this option can + be disabled to save space. In such case, it is possible to set a callback + for the whole PORT event directly. + endmenu # GPIO Interrupt Configuration menu "PWM configuration" diff --git a/arch/arm/src/nrf52/hardware/nrf52_gpio.h b/arch/arm/src/nrf52/hardware/nrf52_gpio.h index d14eaa408e3..57ab7717dde 100644 --- a/arch/arm/src/nrf52/hardware/nrf52_gpio.h +++ b/arch/arm/src/nrf52/hardware/nrf52_gpio.h @@ -57,6 +57,8 @@ # define NRF52_GPIO_NPORTS 1 #endif +#define NRF52_GPIO_NPINS 32 + /* Register offsets *****************************************************************/ #define NRF52_GPIO_OUT_OFFSET 0x0504 /* Write GPIO port */ @@ -95,6 +97,9 @@ /* Register bit definitions *********************************************************/ +#define GPIO_DETECTMODE_DEFAULT (0) +#define GPIO_DETECTMODE_LDETECT (1) + #define GPIO_CNF_DIR (1 << 0) /* Bit 0: Pin direction */ #define GPIO_CNF_INPUT (1 << 1) /* Bit 1: Input buffer disconnect */ #define GPIO_CNF_PULL_SHIFT (2) @@ -102,5 +107,20 @@ # define GPIO_CNF_PULL_DISABLED (0 << GPIO_CNF_PULL_SHIFT) # define GPIO_CNF_PULL_DOWN (1 << GPIO_CNF_PULL_SHIFT) # define GPIO_CNF_PULL_UP (3 << GPIO_CNF_PULL_SHIFT) +#define GPIO_CNF_DRIVE_SHIFT (8) +#define GPIO_CNF_DRIVE_MASK (0x7 << GPIO_CNF_DRIVE_SHIFT) +# define GPIO_CNF_DRIVE_S0S1 (0 << GPIO_CNF_DRIVE_SHIFT) +# define GPIO_CNF_DRIVE_H0S1 (1 << GPIO_CNF_DRIVE_SHIFT) +# define GPIO_CNF_DRIVE_S0H1 (2 << GPIO_CNF_DRIVE_SHIFT) +# define GPIO_CNF_DRIVE_H0H1 (3 << GPIO_CNF_DRIVE_SHIFT) +# define GPIO_CNF_DRIVE_D0S1 (4 << GPIO_CNF_DRIVE_SHIFT) +# define GPIO_CNF_DRIVE_D0H1 (5 << GPIO_CNF_DRIVE_SHIFT) +# define GPIO_CNF_DRIVE_S0D1 (6 << GPIO_CNF_DRIVE_SHIFT) +# define GPIO_CNF_DRIVE_H0D1 (7 << GPIO_CNF_DRIVE_SHIFT) +#define GPIO_CNF_SENSE_SHIFT (16) +#define GPIO_CNF_SENSE_MASK (0x3 << GPIO_CNF_SENSE_SHIFT) +# define GPIO_CNF_SENSE_DISABLED (0 << GPIO_CNF_SENSE_SHIFT) +# define GPIO_CNF_SENSE_HIGH (2 << GPIO_CNF_SENSE_SHIFT) +# define GPIO_CNF_SENSE_LOW (3 << GPIO_CNF_SENSE_SHIFT) #endif /* __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_GPIO_H */ diff --git a/arch/arm/src/nrf52/hardware/nrf52_gpiote.h b/arch/arm/src/nrf52/hardware/nrf52_gpiote.h index e4fb92bd48f..37a8d20d2b4 100644 --- a/arch/arm/src/nrf52/hardware/nrf52_gpiote.h +++ b/arch/arm/src/nrf52/hardware/nrf52_gpiote.h @@ -67,7 +67,8 @@ #define GPIOTE_INT_IN_MASK (0xff << GPIOTE_INT_IN_SHIFT) # define GPIOTE_INT_IN(i) ((1 << (i + GPIOTE_INT_IN_SHIFT)) & GPIOTE_INT_IN_MASK) -#define GPIOTE_INT_PORT 31 /* Bit 31: Enable interrupt for event PORT */ +#define GPIOTE_INT_PORT_SHIFT 31 /* Bit 31: Enable interrupt for event PORT */ +#define GPIOTE_INT_PORT (1 << GPIOTE_INT_PORT_SHIFT) /* CONFIG Register */ diff --git a/arch/arm/src/nrf52/nrf52_gpio.c b/arch/arm/src/nrf52/nrf52_gpio.c index 3b6311361cb..6aaff7fc9bf 100644 --- a/arch/arm/src/nrf52/nrf52_gpio.c +++ b/arch/arm/src/nrf52/nrf52_gpio.c @@ -144,22 +144,54 @@ static inline void nrf52_gpio_mode(nrf52_pinset_t cfgset, mode = cfgset & GPIO_MODE_MASK; regval = getreg32(offset); - regval &= GPIO_CNF_PULL_MASK; + regval &= ~GPIO_CNF_PULL_MASK; if (mode == GPIO_PULLUP) { - regval &= GPIO_CNF_PULL_MASK; regval |= GPIO_CNF_PULL_UP; } else if (mode == GPIO_PULLDOWN) { - regval &= GPIO_CNF_PULL_MASK; regval |= GPIO_CNF_PULL_DOWN; } putreg32(regval, offset); } +/**************************************************************************** + * Name: nrf52_gpio_sense + * + * Description: + * Set SENSE configuration for an input pin + * + ****************************************************************************/ + +static inline void nrf52_gpio_sense(nrf52_pinset_t cfgset, + unsigned int port, unsigned int pin) +{ + uint32_t mode; + uint32_t regval; + uint32_t offset; + + mode = cfgset & GPIO_SENSE_MASK; + + offset = nrf52_gpio_regget(port, NRF52_GPIO_PIN_CNF_OFFSET(pin)); + regval = getreg32(offset); + + regval &= ~GPIO_CNF_SENSE_MASK; + + if (mode == GPIO_SENSE_HIGH) + { + regval |= GPIO_CNF_SENSE_HIGH; + } + else + { + regval |= GPIO_CNF_SENSE_LOW; + } + + putreg32(regval, offset); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -204,7 +236,8 @@ int nrf52_gpio_config(nrf52_pinset_t cfgset) switch (cfgset & GPIO_FUNC_MASK) { case GPIO_INPUT: /* GPIO input pin */ - break; /* Already configured */ + nrf52_gpio_sense(cfgset, port, pin); + break; case GPIO_OUTPUT: /* GPIO outpout pin */ nrf52_gpio_output(cfgset, port, pin); @@ -313,3 +346,20 @@ bool nrf52_gpio_read(nrf52_pinset_t pinset) return (regval >> pin) & 1UL; } + +/**************************************************************************** + * Name: nrf52_gpio_detectmode + * + * Description: + * Set DETECTMODE to either default or latched + * + ****************************************************************************/ + +void nrf52_gpio_detectmode(int port, enum nrf52_gpio_detectmode_e mode) +{ + uint32_t offset = nrf52_gpio_regget(port, NRF52_GPIO_DETECTMODE_OFFSET); + + putreg32(mode == NRF52_GPIO_DETECTMODE_DETECT ? + GPIO_DETECTMODE_DEFAULT : + GPIO_DETECTMODE_LDETECT, offset); +} diff --git a/arch/arm/src/nrf52/nrf52_gpio.h b/arch/arm/src/nrf52/nrf52_gpio.h index 85fe0d01873..31bd8082103 100644 --- a/arch/arm/src/nrf52/nrf52_gpio.h +++ b/arch/arm/src/nrf52/nrf52_gpio.h @@ -187,6 +187,12 @@ typedef uint32_t nrf52_pinset_t; +enum nrf52_gpio_detectmode_e +{ + NRF52_GPIO_DETECTMODE_DETECT, + NRF52_GPIO_DETECTMODE_LDETECT, +}; + /************************************************************************************ * Public Data ************************************************************************************/ diff --git a/arch/arm/src/nrf52/nrf52_gpiote.c b/arch/arm/src/nrf52/nrf52_gpiote.c index 62cf57cfebd..777b131adf1 100644 --- a/arch/arm/src/nrf52/nrf52_gpiote.c +++ b/arch/arm/src/nrf52/nrf52_gpiote.c @@ -61,9 +61,21 @@ struct nrf52_gpiote_callback_s * Private Data ****************************************************************************/ -/* Interrupt handlers attached to each GPIOTE */ +/* Callbacks attached to each GPIOTE channel */ -static struct nrf52_gpiote_callback_s g_gpiote_callbacks[GPIOTE_CHANNELS]; +static struct nrf52_gpiote_callback_s g_gpiote_ch_callbacks[GPIOTE_CHANNELS]; + +#ifdef CONFIG_NRF52_PER_PIN_INTERRUPTS +/* Callbacks attached to each GPIO pin */ + +static struct nrf52_gpiote_callback_s + g_gpiote_pin_callbacks[NRF52_GPIO_NPORTS][NRF52_GPIO_NPINS]; +#else +/* Callback for the PORT event */ + +static struct nrf52_gpiote_callback_s + g_gpiote_port_callback[NRF52_GPIO_NPORTS]; +#endif /**************************************************************************** * Private Functions @@ -108,6 +120,9 @@ static int nrf52_gpiote_isr(int irq, FAR void *context, FAR void *arg) uint32_t regval = 0; int ret = OK; int i = 0; +#ifdef CONFIG_NRF52_PER_PIN_INTERRUPTS + int j = 0; +#endif /* Scan all GPIOTE channels */ @@ -115,7 +130,7 @@ static int nrf52_gpiote_isr(int irq, FAR void *context, FAR void *arg) { /* Only if callback is registered */ - if (g_gpiote_callbacks[i].callback != NULL) + if (g_gpiote_ch_callbacks[i].callback != NULL) { /* Get input event register */ @@ -124,8 +139,8 @@ static int nrf52_gpiote_isr(int irq, FAR void *context, FAR void *arg) { /* Execute callback */ - xcpt_t callback = g_gpiote_callbacks[i].callback; - FAR void *cbarg = g_gpiote_callbacks[i].arg; + xcpt_t callback = g_gpiote_ch_callbacks[i].callback; + FAR void *cbarg = g_gpiote_ch_callbacks[i].arg; ret = callback(irq, context, cbarg); /* Clear event */ @@ -135,6 +150,76 @@ static int nrf52_gpiote_isr(int irq, FAR void *context, FAR void *arg) } } + /* Check for PORT event */ + + regval = nrf52_gpiote_getreg(NRF52_GPIOTE_EVENTS_PORT_OFFSET); + if (regval) + { + uint32_t addr = 0; + + /* Ack PORT event */ + + nrf52_gpiote_putreg(NRF52_GPIOTE_EVENTS_PORT_OFFSET, 0); + + /* For each GPIO port, get LATCH register */ + + for (i = 0; i < NRF52_GPIO_NPORTS; i++) + { + switch (i) + { + case 0: + addr = NRF52_GPIO_P0_BASE + NRF52_GPIO_LATCH_OFFSET; + break; +#ifdef CONFIG_NRF52_HAVE_PORT1 + case 1: + addr = NRF52_GPIO_P1_BASE + NRF52_GPIO_LATCH_OFFSET; + break; +#endif + } + + /* Retrieve LATCH register */ + + regval = getreg32(addr); + + /* Clear LATCH register (this may set PORT again) */ + + putreg32(0xffffffff, addr); + +#ifdef CONFIG_NRF52_PER_PIN_INTERRUPTS + /* Check for pins with DETECT bit high in LATCH register + * and dispatch callback if set + */ + + for (j = 0; j < NRF52_GPIO_NPINS && regval; j++) + { + if (regval & (1 << j) && g_gpiote_pin_callbacks[i][j].callback) + { + /* Run callback */ + + xcpt_t callback = g_gpiote_pin_callbacks[i][j].callback; + FAR void *cbarg = g_gpiote_pin_callbacks[i][j].arg; + + ret = callback(irq, context, cbarg); + + /* Mark bit is as "visited", we can stop looping sooner + * this way + */ + + regval &= ~(1 << j); + } + } +#else + if (g_gpiote_port_callback[i].callback) + { + xcpt_t callback = g_gpiote_port_callback[i].callback; + FAR void *cbarg = g_gpiote_port_callback[i].arg; + + ret = callback(irq, context, cbarg); + } +#endif + } + } + return ret; } @@ -142,11 +227,126 @@ static int nrf52_gpiote_isr(int irq, FAR void *context, FAR void *arg) * Public Functions ****************************************************************************/ +#ifdef CONFIG_NRF52_PER_PIN_INTERRUPTS /**************************************************************************** - * Name: nrf52_gpiosetevent + * Name: nrf52_gpiote_set_pin_event * * Description: - * Sets/clears GPIO based event and interrupt triggers. + * Sets/clears a handler for a given pin for the GPIO PORT event. This + * will mean edge-sensitive or level-sensitive according to GPIO detect + * mode configuration for the port (see nrf52_gpio_detectmode()). Pin + * will be sensitive to high/low according to GPIO_SENSE_LOW/HIGH + * (set via nrf52_gpio_config()). + * + * The passed handler will be invoked from the main ISR for the PORT + * event and will take care of clearing the LATCH register. + * + * Input Parameters: + * - pinset: GPIO pin configuration + * - func: When non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +void nrf52_gpiote_set_pin_event(uint32_t pinset, xcpt_t func, FAR void *arg) +{ + int pin = 0; + int port = 0; + irqstate_t flags; + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; +#ifdef CONFIG_NRF52_HAVE_PORT1 + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; +#endif + + flags = enter_critical_section(); + + g_gpiote_pin_callbacks[port][pin].callback = func; + g_gpiote_pin_callbacks[port][pin].arg = arg; + + leave_critical_section(flags); +} +#else +/**************************************************************************** + * Name: nrf52_gpiote_set_port_event + * + * Description: + * Sets/clears the handler for the GPIO PORT event. + * + * The passed handler will be invoked from the main ISR for the PORT + * event and will take care of clearing the LATCH register. + * + * Input Parameters: + * - pinset: GPIO port will be extracted from this parameter + * - func: When non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +void nrf52_gpiote_set_port_event(uint32_t pinset, xcpt_t func, FAR void *arg) +{ + int port = 0; + irqstate_t flags; + +#ifdef CONFIG_NRF52_HAVE_PORT1 + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; +#endif + + flags = enter_critical_section(); + + g_gpiote_port_callback[port].callback = func; + g_gpiote_port_callback[port].arg = arg; + + if (func) + { + /* Enable the ISR */ + + nrf52_gpiote_putreg(NRF52_GPIOTE_INTENSET_OFFSET, GPIOTE_INT_PORT); + } + else + { +#if NRF52_GPIO_NPORTS > 1 + /* Check if we can disable the ISR */ + + int i; + + for (i = 0; i < NRF52_GPIO_NPORTS; i++) + { + if (g_gpiote_port_callback[port].callback) + { + break; + } + } + + if (i == NRF52_GPIO_NPORTS) + { + nrf52_gpiote_putreg(NRF52_GPIOTE_INTENCLR_OFFSET, GPIOTE_INT_PORT); + } +#else + /* Disable the ISR */ + + nrf52_gpiote_putreg(NRF52_GPIOTE_INTENCLR_OFFSET, GPIOTE_INT_PORT); +#endif + } + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: nrf52_gpiote_set_ch_event + * + * Description: + * Configures a GPIOTE channel in EVENT mode, assigns it to a given pin + * and sets a handler for the corresponding channel events. * * Input Parameters: * - pinset: GPIO pin configuration @@ -162,122 +362,90 @@ static int nrf52_gpiote_isr(int irq, FAR void *context, FAR void *arg) * ****************************************************************************/ -int nrf52_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, - bool event, xcpt_t func, FAR void *arg) +void nrf52_gpiote_set_ch_event(uint32_t pinset, int channel, + bool risingedge, bool fallingedge, + xcpt_t func, FAR void *arg) { - int ret = OK; - int i = 0; int pin = 0; #ifdef CONFIG_NRF52_HAVE_PORT1 int port = 0; #endif uint32_t regval = 0; - bool found = false; irqstate_t flags; - /* Find available GPIOTE channel */ - - flags = enter_critical_section(); - - for (i = 0; i < GPIOTE_CHANNELS; i += 1) - { - if (g_gpiote_callbacks[i].callback == NULL) - { - found = true; - break; - } - } - - leave_critical_section(flags); - - /* Return error if there is no free channel */ - - if (found == false) - { - ret = -ENODEV; - goto errout; - } + DEBUGASSERT(channel < GPIOTE_CHANNELS); /* NOTE: GPIOTE module has priority over GPIO module * so GPIO configuration will be ignored */ - /* Select GPIOTE pin */ + flags = enter_critical_section(); - pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; - regval = (pin << GPIOTE_CONFIG_PSEL_SHIFT); + if (func) + { + /* Select EVENT mode */ + + regval |= GPIOTE_CONFIG_MODE_EV; + + /* Select GPIOTE pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + regval |= (pin << GPIOTE_CONFIG_PSEL_SHIFT); #ifdef CONFIG_NRF52_HAVE_PORT1 - port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; - regval |= (port << GPIOTE_CONFIG_PORT_SHIFT); + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + regval |= (port << GPIOTE_CONFIG_PORT_SHIFT); #endif - /* Select EVENT mode */ + /* Select polarity */ - if (event || func) - { - regval &= ~GPIOTE_CONFIG_MODE_MASK; - regval |= GPIOTE_CONFIG_MODE_EV; - } + if (risingedge == true && fallingedge == true) + { + regval |= GPIOTE_CONFIG_POL_TG; + } + else if (risingedge == true) + { + regval |= GPIOTE_CONFIG_POL_LTH; + } + else if (fallingedge == true) + { + regval |= GPIOTE_CONFIG_POL_HTL; + } - /* Select polarity */ + /* Enable callback for channel */ - if (risingedge == true && fallingedge == true) - { - regval |= GPIOTE_CONFIG_POL_TG; + g_gpiote_ch_callbacks[channel].callback = func; + g_gpiote_ch_callbacks[channel].arg = arg; + + /* Enable interrupt for given event */ + + nrf52_gpiote_putreg(NRF52_GPIOTE_INTENSET_OFFSET, + GPIOTE_INT_IN(channel)); } - else if (risingedge == true) + else { - regval |= GPIOTE_CONFIG_POL_LTH; - } - else if (fallingedge == true) - { - regval |= GPIOTE_CONFIG_POL_HTL; + /* Leave register as zero (disabled mode) */ + + /* Disable interrupt for given event */ + + nrf52_gpiote_putreg(NRF52_GPIOTE_INTENCLR_OFFSET, + GPIOTE_INT_IN(channel)); + + /* Remove callback configuration */ + + g_gpiote_ch_callbacks[channel].callback = NULL; + g_gpiote_ch_callbacks[channel].arg = NULL; } /* Write CONFIG register */ - nrf52_gpiote_putreg(NRF52_GPIOTE_CONFIG_OFFSET(i), regval); + nrf52_gpiote_putreg(NRF52_GPIOTE_CONFIG_OFFSET(channel), regval); - /* Enable interrupt for given event */ - - nrf52_gpiote_putreg(NRF52_GPIOTE_INTENSET_OFFSET, GPIOTE_INT_IN(i)); - - /* Connect callback */ - - g_gpiote_callbacks[i].callback = func; - g_gpiote_callbacks[i].arg = arg; - -errout: - return ret; + leave_critical_section(flags); } /**************************************************************************** - * Name: nrf52_gpiote_init - * - * Description: - * Initialize GPIOTE - * - ****************************************************************************/ - -int nrf52_gpiote_init(void) -{ - /* Reset GPIOTE data */ - - memset(&g_gpiote_callbacks, - 0, - sizeof(struct nrf52_gpiote_callback_s)*GPIOTE_CHANNELS); - - /* Attach GPIOTE interrupt handler */ - - irq_attach(NRF52_IRQ_GPIOTE, nrf52_gpiote_isr, NULL); - up_enable_irq(NRF52_IRQ_GPIOTE); - - return OK; -} - -/**************************************************************************** - * Name: nrf52_gpiotaskset + * Name: nrf52_gpio_set_task * * Description: * Configure GPIO in TASK mode (to be controlled via tasks). @@ -299,8 +467,9 @@ int nrf52_gpiote_init(void) * ****************************************************************************/ -int nrf52_gpiotaskset(uint32_t pinset, int channel, - bool output_high, enum nrf52_gpiote_outcfg_e outcfg) +void nrf52_gpiote_set_task(uint32_t pinset, int channel, + bool output_high, + enum nrf52_gpiote_outcfg_e outcfg) { uint32_t regval; int pin; @@ -351,6 +520,36 @@ int nrf52_gpiotaskset(uint32_t pinset, int channel, /* Write register */ nrf52_gpiote_putreg(NRF52_GPIOTE_CONFIG_OFFSET(channel), regval); +} + +/**************************************************************************** + * Name: nrf52_gpiote_init + * + * Description: + * Initialize GPIOTE + * + ****************************************************************************/ + +int nrf52_gpiote_init(void) +{ + /* Reset GPIOTE data */ + + memset(&g_gpiote_ch_callbacks, 0, sizeof(g_gpiote_ch_callbacks)); + +#ifdef CONFIG_NRF52_PER_PIN_INTERRUPTS + memset(&g_gpiote_pin_callbacks, 0, sizeof(g_gpiote_pin_callbacks)); + + /* Enable PORT event interrupt */ + + nrf52_gpiote_putreg(NRF52_GPIOTE_INTENSET_OFFSET, GPIOTE_INT_PORT); +#else + memset(&g_gpiote_port_callback, 0, sizeof(g_gpiote_port_callback)); +#endif + + /* Attach GPIOTE interrupt handler */ + + irq_attach(NRF52_IRQ_GPIOTE, nrf52_gpiote_isr, NULL); + up_enable_irq(NRF52_IRQ_GPIOTE); return OK; } diff --git a/arch/arm/src/nrf52/nrf52_gpiote.h b/arch/arm/src/nrf52/nrf52_gpiote.h index 108112145d3..75a7a8e0805 100644 --- a/arch/arm/src/nrf52/nrf52_gpiote.h +++ b/arch/arm/src/nrf52/nrf52_gpiote.h @@ -49,17 +49,19 @@ enum nrf52_gpiote_outcfg_e ****************************************************************************/ /**************************************************************************** - * Name: nrf52_gpiosetevent + * Name: nrf52_gpiote_set_ch_event * * Description: - * Sets/clears GPIO based event and interrupt triggers. + * Configures a GPIOTE channel in EVENT mode, assigns it to a given pin + * and sets a handler for the corresponding channel events. * * Input Parameters: - * - pinset: gpio pin configuration - * - rising/falling edge: enables - * - event: generate event when set - * - func: when non-NULL, generate interrupt - * - arg: Argument passed to the interrupt callback + * - pinset: GPIO pin configuration + * - risingedge: Enables interrupt on rising edges + * - fallingedge: Enables interrupt on falling edges + * - event: Generate event when set + * - func: When non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback * * Returned Value: * Zero (OK) on success; a negated errno value on failure indicating the @@ -67,11 +69,65 @@ enum nrf52_gpiote_outcfg_e * ****************************************************************************/ -int nrf52_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, - bool event, xcpt_t func, FAR void *arg); +void nrf52_gpiote_set_ch_event(uint32_t pinset, int channel, + bool risingedge, bool fallingedge, + xcpt_t func, FAR void *arg); + +#ifdef CONFIG_NRF52_PER_PIN_INTERRUPTS +/**************************************************************************** + * Name: nrf52_gpiote_set_pin_event + * + * Description: + * Sets/clears a handler for a given pin for the GPIO PORT event. This + * will mean edge-sensitive or level-sensitive according to GPIO detect + * mode configuration for the port (see nrf52_gpio_detectmode()). Pin + * will be sensitive to high/low according to GPIO_SENSE_LOW/HIGH + * (set via nrf52_gpio_config()). + * + * The passed handler will be invoked from the main ISR for the PORT + * event and will take care of clearing the LATCH register. + * + * Input Parameters: + * - pinset: GPIO pin configuration + * - func: When non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +void nrf52_gpiote_set_pin_event(uint32_t pinset, xcpt_t func, FAR void *arg); +#else /**************************************************************************** - * Name: nrf52_gpiotaskset + * Name: nrf52_gpiote_set_port_event + * + * Description: + * Sets/clears the handler for the GPIO PORT event. + * + * The passed handler will be invoked from the main ISR for the PORT + * event and will take care of clearing the LATCH register. + * + * Input Parameters: + * - pinset: GPIO port will be extracted from this parameter + * - func: When non-NULL, generate interrupt + * - arg: Argument passed to the interrupt callback + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure indicating the + * nature of the failure. + * + ****************************************************************************/ + +void nrf52_gpiote_set_port_event(uint32_t pinset, xcpt_t func, + FAR void *arg); + +#endif + +/**************************************************************************** + * Name: nrf52_gpio_set_task * * Description: * Configure GPIO in TASK mode (to be controlled via tasks). @@ -93,8 +149,8 @@ int nrf52_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge, * ****************************************************************************/ -int nrf52_gpiotaskset(uint32_t pinset, int channel, bool output_high, - enum nrf52_gpiote_outcfg_e outcfg); +void nrf52_gpio_set_task(uint32_t pinset, int channel, + bool output_high, enum nrf52_gpiote_outcfg_e outcfg); /**************************************************************************** * Name: nrf52_gpiote_init diff --git a/boards/arm/nrf52/nrf52840-dk/src/nrf52_sx127x.c b/boards/arm/nrf52/nrf52840-dk/src/nrf52_sx127x.c index 61a640e5957..0625a8b0535 100644 --- a/boards/arm/nrf52/nrf52840-dk/src/nrf52_sx127x.c +++ b/boards/arm/nrf52/nrf52840-dk/src/nrf52_sx127x.c @@ -88,7 +88,7 @@ static int sx127x_irq0_attach(xcpt_t isr, FAR void *arg) /* IRQ on rising edge */ - nrf52_gpiosetevent(GPIO_SX127X_DIO0, true, false, false, isr, arg); + nrf52_gpiote_set_ch_event(GPIO_SX127X_DIO0, 0, true, false, isr, arg); return OK; }