mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-14 07:35:21 +00:00
This adds interrupt support to the SAM0 GPIO driver. This is heavily inspired by @nzmichaelh work in #5715. The primary difference from that implementation is that here the External Interrupt Controller (EIC) is separated out into an interrupt controller driver that is less tightly coupled to the GPIO API. Instead it implements more of a conversion from the EIC's own odd multiplexing to a more traditional port and pin mask IRQ-like callback. Unfortunately, through the EIC on the SAMD2x are relatively well behaved in terms of pin to EIC line mappings, other chips that share the peripheral interface are not. So the EIC driver implements a per-line lookup to the pin and port pair using definitions extracted from the ASF headers. The EIC driver still makes some assumptions about how it will be used: mostly it assumes exactly one callback per port. This should be fine as the only intended user is the GPIO driver itself. This has been tested with some simple programs and with tests/drivers/gpio/gpio_basic_api on a SAMD21 breakout and an adafruit_trinket_m0 board. Signed-off-by: Derek Hageman <hageman@inthat.cloud>
85 lines
2.2 KiB
C
85 lines
2.2 KiB
C
/*
|
|
* Copyright (c) 2019 Derek Hageman <hageman@inthat.cloud>
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
|
|
#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_SAM0_EIC_H_
|
|
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_SAM0_EIC_H_
|
|
|
|
#include <zephyr/types.h>
|
|
|
|
/* callback for EIC interrupt */
|
|
typedef void (*sam0_eic_callback_t)(u32_t pins, void *data);
|
|
|
|
/**
|
|
* @brief EIC trigger condition
|
|
*/
|
|
enum sam0_eic_trigger {
|
|
/* Rising edge */
|
|
SAM0_EIC_RISING,
|
|
/* Falling edge */
|
|
SAM0_EIC_FALLING,
|
|
/* Both edges */
|
|
SAM0_EIC_BOTH,
|
|
/* High level detection */
|
|
SAM0_EIC_HIGH,
|
|
/* Low level detection */
|
|
SAM0_EIC_LOW,
|
|
};
|
|
|
|
/**
|
|
* @brief Acquire an EIC interrupt for specific port and pin combination
|
|
*
|
|
* This acquires the EIC interrupt for a specific port and pin combination,
|
|
* or returns an error if the required line is not available. Only a single
|
|
* callback per port is supported and supplying a different one will
|
|
* change it for all lines on that port.
|
|
*
|
|
* @param port port index (A=0, etc)
|
|
* @param pin pin in the port
|
|
* @param trigger trigger condition
|
|
* @param cb interrupt callback
|
|
* @param data parameter to the interrupt callback
|
|
*/
|
|
int sam0_eic_acquire(int port, int pin, enum sam0_eic_trigger trigger,
|
|
bool filter, sam0_eic_callback_t cb, void *data);
|
|
|
|
/**
|
|
* @brief Release the EIC interrupt for a specific port and pin combination
|
|
*
|
|
* Release the EIC configuration for a specific port and pin combination.
|
|
* No effect if that combination does not currently hold the associated
|
|
* EIC line.
|
|
*
|
|
* @param port port index (A=0, etc)
|
|
* @param pin pin in the port
|
|
*/
|
|
int sam0_eic_release(int port, int pin);
|
|
|
|
/**
|
|
* @brief Enable the EIC interrupt for a specific port and pin combination
|
|
*
|
|
* @param port port index (A=0, etc)
|
|
* @param pin pin in the port
|
|
*/
|
|
int sam0_eic_enable_interrupt(int port, int pin);
|
|
|
|
/**
|
|
* @brief Disable the EIC interrupt for a specific port and pin combination
|
|
*
|
|
* @param port port index (A=0, etc)
|
|
* @param pin pin in the port
|
|
*/
|
|
int sam0_eic_disable_interrupt(int port, int pin);
|
|
|
|
/**
|
|
* @brief Test if there is an EIC interrupt pending for a port
|
|
*
|
|
* @param port port index (A=0, etc)
|
|
*/
|
|
u32_t sam0_eic_interrupt_pending(int por);
|
|
|
|
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_SAM0_EIC_H_ */
|