nuttx/arch/arm/src/nrf52/nrf52_gpiote.h

166 lines
6.1 KiB
C
Raw Normal View History

/****************************************************************************
* arch/arm/src/nrf52/nrf52_gpiote.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_NRF52_NRF52_GPIOTE_H
#define __ARCH_ARM_SRC_NRF52_NRF52_GPIOTE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/irq.h>
#include "chip.h"
/****************************************************************************
* Public Types
****************************************************************************/
/* GPIOTE OUT task configuration */
enum nrf52_gpiote_outcfg_e
{
NRF52_GPIOTE_SET = 0,
NRF52_GPIOTE_CLEAR = 1,
NRF52_GPIOTE_TOGGLE = 2,
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
nrf52 GPIO/GPIOTE: better expose pin interrupt capability This change improves upon current support for pin interrupts. Before, a pin interrupt was handled (with nrf52_gpiote_setevent) using one of the eight available GPIOTE channels. Moreover, it didn't event let the user specify which channel to use (simply tried to get a free one). Also, it was buggy since it did not consider unsetting the callback. Besides GPIOTE channels, there is another way to deal with pin interrupts. The GPIO peripheral is capable of generating a PORT event (for the whole GPIO port) depending on the pin SENSE configuration (HIGH or LOW, or NONE) and GPIO DETECTMODE register (latching or non-latching). This change then renames nrf52_gpiote_setevent into nrf52_gpiote_set_ch_event, maintaining functionality of original function, but now allows specifying channel (and correctly handles unsetting the callback). Then, a new nrf52_gpiote_set_pin_event is added, which allows to set a callback for a given pin. During initialization, interrupt for the PORT event is enabled and handled in such way that for each pin whose corresponding bit in LATCH register (indicates the result of pin SENSEing) the callback for this pin will be invoked. This mechanism means that every pin can get an ISR. It also avoids using GPIOTE channels for this purpose which carry higher current consumption. This new per-pin callback mechanism has some added memory requirement so it can be disabled and its default is dependant on DEFAULT_SMALL. When disabled, a callback for the PORT event can be set directly with nrf52_gpiote_set_port_event There was only one use of nrf52_gpio_setevent() which was migrated into nrf52_gpio_set_ch_event() passing channel zero.
2020-11-07 21:12:47 +01:00
* Name: nrf52_gpiote_set_ch_event
*
* Description:
nrf52 GPIO/GPIOTE: better expose pin interrupt capability This change improves upon current support for pin interrupts. Before, a pin interrupt was handled (with nrf52_gpiote_setevent) using one of the eight available GPIOTE channels. Moreover, it didn't event let the user specify which channel to use (simply tried to get a free one). Also, it was buggy since it did not consider unsetting the callback. Besides GPIOTE channels, there is another way to deal with pin interrupts. The GPIO peripheral is capable of generating a PORT event (for the whole GPIO port) depending on the pin SENSE configuration (HIGH or LOW, or NONE) and GPIO DETECTMODE register (latching or non-latching). This change then renames nrf52_gpiote_setevent into nrf52_gpiote_set_ch_event, maintaining functionality of original function, but now allows specifying channel (and correctly handles unsetting the callback). Then, a new nrf52_gpiote_set_pin_event is added, which allows to set a callback for a given pin. During initialization, interrupt for the PORT event is enabled and handled in such way that for each pin whose corresponding bit in LATCH register (indicates the result of pin SENSEing) the callback for this pin will be invoked. This mechanism means that every pin can get an ISR. It also avoids using GPIOTE channels for this purpose which carry higher current consumption. This new per-pin callback mechanism has some added memory requirement so it can be disabled and its default is dependant on DEFAULT_SMALL. When disabled, a callback for the PORT event can be set directly with nrf52_gpiote_set_port_event There was only one use of nrf52_gpio_setevent() which was migrated into nrf52_gpio_set_ch_event() passing channel zero.
2020-11-07 21:12:47 +01:00
* Configures a GPIOTE channel in EVENT mode, assigns it to a given pin
* and sets a handler for the corresponding channel events.
*
* Input Parameters:
nrf52 GPIO/GPIOTE: better expose pin interrupt capability This change improves upon current support for pin interrupts. Before, a pin interrupt was handled (with nrf52_gpiote_setevent) using one of the eight available GPIOTE channels. Moreover, it didn't event let the user specify which channel to use (simply tried to get a free one). Also, it was buggy since it did not consider unsetting the callback. Besides GPIOTE channels, there is another way to deal with pin interrupts. The GPIO peripheral is capable of generating a PORT event (for the whole GPIO port) depending on the pin SENSE configuration (HIGH or LOW, or NONE) and GPIO DETECTMODE register (latching or non-latching). This change then renames nrf52_gpiote_setevent into nrf52_gpiote_set_ch_event, maintaining functionality of original function, but now allows specifying channel (and correctly handles unsetting the callback). Then, a new nrf52_gpiote_set_pin_event is added, which allows to set a callback for a given pin. During initialization, interrupt for the PORT event is enabled and handled in such way that for each pin whose corresponding bit in LATCH register (indicates the result of pin SENSEing) the callback for this pin will be invoked. This mechanism means that every pin can get an ISR. It also avoids using GPIOTE channels for this purpose which carry higher current consumption. This new per-pin callback mechanism has some added memory requirement so it can be disabled and its default is dependant on DEFAULT_SMALL. When disabled, a callback for the PORT event can be set directly with nrf52_gpiote_set_port_event There was only one use of nrf52_gpio_setevent() which was migrated into nrf52_gpio_set_ch_event() passing channel zero.
2020-11-07 21:12:47 +01:00
* - 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
* nature of the failure.
*
****************************************************************************/
nrf52 GPIO/GPIOTE: better expose pin interrupt capability This change improves upon current support for pin interrupts. Before, a pin interrupt was handled (with nrf52_gpiote_setevent) using one of the eight available GPIOTE channels. Moreover, it didn't event let the user specify which channel to use (simply tried to get a free one). Also, it was buggy since it did not consider unsetting the callback. Besides GPIOTE channels, there is another way to deal with pin interrupts. The GPIO peripheral is capable of generating a PORT event (for the whole GPIO port) depending on the pin SENSE configuration (HIGH or LOW, or NONE) and GPIO DETECTMODE register (latching or non-latching). This change then renames nrf52_gpiote_setevent into nrf52_gpiote_set_ch_event, maintaining functionality of original function, but now allows specifying channel (and correctly handles unsetting the callback). Then, a new nrf52_gpiote_set_pin_event is added, which allows to set a callback for a given pin. During initialization, interrupt for the PORT event is enabled and handled in such way that for each pin whose corresponding bit in LATCH register (indicates the result of pin SENSEing) the callback for this pin will be invoked. This mechanism means that every pin can get an ISR. It also avoids using GPIOTE channels for this purpose which carry higher current consumption. This new per-pin callback mechanism has some added memory requirement so it can be disabled and its default is dependant on DEFAULT_SMALL. When disabled, a callback for the PORT event can be set directly with nrf52_gpiote_set_port_event There was only one use of nrf52_gpio_setevent() which was migrated into nrf52_gpio_set_ch_event() passing channel zero.
2020-11-07 21:12:47 +01:00
void nrf52_gpiote_set_ch_event(uint32_t pinset, int channel,
bool risingedge, bool fallingedge,
xcpt_t func, FAR void *arg);
nrf52 GPIO/GPIOTE: better expose pin interrupt capability This change improves upon current support for pin interrupts. Before, a pin interrupt was handled (with nrf52_gpiote_setevent) using one of the eight available GPIOTE channels. Moreover, it didn't event let the user specify which channel to use (simply tried to get a free one). Also, it was buggy since it did not consider unsetting the callback. Besides GPIOTE channels, there is another way to deal with pin interrupts. The GPIO peripheral is capable of generating a PORT event (for the whole GPIO port) depending on the pin SENSE configuration (HIGH or LOW, or NONE) and GPIO DETECTMODE register (latching or non-latching). This change then renames nrf52_gpiote_setevent into nrf52_gpiote_set_ch_event, maintaining functionality of original function, but now allows specifying channel (and correctly handles unsetting the callback). Then, a new nrf52_gpiote_set_pin_event is added, which allows to set a callback for a given pin. During initialization, interrupt for the PORT event is enabled and handled in such way that for each pin whose corresponding bit in LATCH register (indicates the result of pin SENSEing) the callback for this pin will be invoked. This mechanism means that every pin can get an ISR. It also avoids using GPIOTE channels for this purpose which carry higher current consumption. This new per-pin callback mechanism has some added memory requirement so it can be disabled and its default is dependant on DEFAULT_SMALL. When disabled, a callback for the PORT event can be set directly with nrf52_gpiote_set_port_event There was only one use of nrf52_gpio_setevent() which was migrated into nrf52_gpio_set_ch_event() passing channel zero.
2020-11-07 21:12:47 +01:00
#ifdef CONFIG_NRF52_PER_PIN_INTERRUPTS
/****************************************************************************
nrf52 GPIO/GPIOTE: better expose pin interrupt capability This change improves upon current support for pin interrupts. Before, a pin interrupt was handled (with nrf52_gpiote_setevent) using one of the eight available GPIOTE channels. Moreover, it didn't event let the user specify which channel to use (simply tried to get a free one). Also, it was buggy since it did not consider unsetting the callback. Besides GPIOTE channels, there is another way to deal with pin interrupts. The GPIO peripheral is capable of generating a PORT event (for the whole GPIO port) depending on the pin SENSE configuration (HIGH or LOW, or NONE) and GPIO DETECTMODE register (latching or non-latching). This change then renames nrf52_gpiote_setevent into nrf52_gpiote_set_ch_event, maintaining functionality of original function, but now allows specifying channel (and correctly handles unsetting the callback). Then, a new nrf52_gpiote_set_pin_event is added, which allows to set a callback for a given pin. During initialization, interrupt for the PORT event is enabled and handled in such way that for each pin whose corresponding bit in LATCH register (indicates the result of pin SENSEing) the callback for this pin will be invoked. This mechanism means that every pin can get an ISR. It also avoids using GPIOTE channels for this purpose which carry higher current consumption. This new per-pin callback mechanism has some added memory requirement so it can be disabled and its default is dependant on DEFAULT_SMALL. When disabled, a callback for the PORT event can be set directly with nrf52_gpiote_set_port_event There was only one use of nrf52_gpio_setevent() which was migrated into nrf52_gpio_set_ch_event() passing channel zero.
2020-11-07 21:12:47 +01:00
* 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_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).
* Note that a pin can only be either in TASK or EVENT mode (set by
* nrf52_gpiosetevent with event set to true). Also, once set to TASK mode,
* pin control is only possible via tasks on the via nrf52_gpio_write and
* will automatically set the output mode.
* Finally, a given pin should only be assigned to a given channel.
*
* Input Parameters:
* - pinset: gpio pin configuration (only port + pin is important here)
* - channel: the GPIOTE channel used to control the given pin
* - output_high: set pin initially to output HIGH or LOW.
* - outcfg: configure pin behavior one OUT task is triggered
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure indicating the
* nature of the failure.
*
****************************************************************************/
nrf52 GPIO/GPIOTE: better expose pin interrupt capability This change improves upon current support for pin interrupts. Before, a pin interrupt was handled (with nrf52_gpiote_setevent) using one of the eight available GPIOTE channels. Moreover, it didn't event let the user specify which channel to use (simply tried to get a free one). Also, it was buggy since it did not consider unsetting the callback. Besides GPIOTE channels, there is another way to deal with pin interrupts. The GPIO peripheral is capable of generating a PORT event (for the whole GPIO port) depending on the pin SENSE configuration (HIGH or LOW, or NONE) and GPIO DETECTMODE register (latching or non-latching). This change then renames nrf52_gpiote_setevent into nrf52_gpiote_set_ch_event, maintaining functionality of original function, but now allows specifying channel (and correctly handles unsetting the callback). Then, a new nrf52_gpiote_set_pin_event is added, which allows to set a callback for a given pin. During initialization, interrupt for the PORT event is enabled and handled in such way that for each pin whose corresponding bit in LATCH register (indicates the result of pin SENSEing) the callback for this pin will be invoked. This mechanism means that every pin can get an ISR. It also avoids using GPIOTE channels for this purpose which carry higher current consumption. This new per-pin callback mechanism has some added memory requirement so it can be disabled and its default is dependant on DEFAULT_SMALL. When disabled, a callback for the PORT event can be set directly with nrf52_gpiote_set_port_event There was only one use of nrf52_gpio_setevent() which was migrated into nrf52_gpio_set_ch_event() passing channel zero.
2020-11-07 21:12:47 +01:00
void nrf52_gpio_set_task(uint32_t pinset, int channel,
bool output_high, enum nrf52_gpiote_outcfg_e outcfg);
/****************************************************************************
* Name: nrf52_gpiote_init
*
* Description:
* Initialize GPIOTE
*
****************************************************************************/
int nrf52_gpiote_init(void);
#endif /* __ARCH_ARM_SRC_NRF52_NRF52_GPIOTE_H */