drivers: interrupt_controller: Add XMC4XXX ERU driver
In Infineon XMC4XXX SoCs, gpio interrupts are triggered via an Event Request Unit (ERU) module. A subset of the gpios are connected to the ERU. The ERU monitors edge triggers and creates a SR. This driver configures the ERU for a target port/pin combination for rising/falling edge events. Note that the ERU module does not generate SR based on the gpio level. Internally the ERU tracks the *status* of an event. The status is set on a positive edge and unset on a negative edge (or vice-versa depending on the configuration). The value of the status is used to implement a level triggered interrupt; The ISR checks the status flag and calls the callback function if the status is set. The ERU configurations for supported port/pin combinations are stored in a devicetree file dts/arm/infineon/xmc4xxx_x_x-intc.dtsi. The configurations are stored in the opaque array uint16 port_line_mapping[]. Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com>
This commit is contained in:
parent
a8a72c581e
commit
727e589448
12 changed files with 400 additions and 0 deletions
|
@ -9,6 +9,7 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include <infineon/xmc4500_F100x1024.dtsi>
|
||||
#include <infineon/xmc4500_F100x1024-intc.dtsi>
|
||||
#include "xmc45_relax_kit-pinctrl.dtsi"
|
||||
|
||||
/ {
|
||||
|
|
|
@ -31,6 +31,7 @@ zephyr_library_sources_ifdef(CONFIG_SWERV_PIC intc_swerv_pic.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ intc_vexriscv_litex.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NUCLEI_ECLIC intc_nuclei_eclic.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NXP_S32_EIRQ intc_eirq_nxp_s32.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_XMC4XXX_INTC intc_xmc4xxx.c)
|
||||
|
||||
if(CONFIG_INTEL_VTD_ICTL)
|
||||
zephyr_library_include_directories(${ZEPHYR_BASE}/arch/x86/include)
|
||||
|
|
|
@ -83,4 +83,6 @@ source "drivers/interrupt_controller/Kconfig.plic"
|
|||
|
||||
source "drivers/interrupt_controller/Kconfig.nxp_s32"
|
||||
|
||||
source "drivers/interrupt_controller/Kconfig.xmc4xxx"
|
||||
|
||||
endmenu
|
||||
|
|
12
drivers/interrupt_controller/Kconfig.xmc4xxx
Normal file
12
drivers/interrupt_controller/Kconfig.xmc4xxx
Normal file
|
@ -0,0 +1,12 @@
|
|||
# XMC4XXX INTC configuration
|
||||
|
||||
# Copyright (c) Schlumberger
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config XMC4XXX_INTC
|
||||
bool "Interrupt Controller Driver for XMC4XXX series devices"
|
||||
default y
|
||||
depends on DT_HAS_INFINEON_XMC4XXX_INTC_ENABLED
|
||||
help
|
||||
Enable interrupt controller driver for XMC4XXX series of devices. This is required for
|
||||
GPIO interrupt support.
|
227
drivers/interrupt_controller/intc_xmc4xxx.c
Normal file
227
drivers/interrupt_controller/intc_xmc4xxx.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Schlumberger
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT infineon_xmc4xxx_intc
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/dt-bindings/interrupt-controller/infineon-xmc4xxx-intc.h>
|
||||
#include <zephyr/irq.h>
|
||||
|
||||
#include <xmc_eru.h>
|
||||
|
||||
/* In Infineon XMC4XXX SoCs, gpio interrupts are triggered via an Event Request Unit (ERU) */
|
||||
/* module. A subset of the GPIOs are connected to the ERU. The ERU monitors edge triggers */
|
||||
/* and creates a SR. */
|
||||
|
||||
/* This driver configures the ERU for a target port/pin combination for rising/falling */
|
||||
/* edge events. Note that the ERU module does not generate SR based on the gpio level. */
|
||||
/* Internally the ERU tracks the *status* of an event. The status is set on a positive edge and */
|
||||
/* unset on a negative edge (or vice-versa depending on the configuration). The value of */
|
||||
/* the status is used to implement a level triggered interrupt; The ISR checks the status */
|
||||
/* flag and calls the callback function if the status is set. */
|
||||
|
||||
/* The ERU configurations for supported port/pin combinations are stored in a devicetree file */
|
||||
/* dts/arm/infineon/xmc4xxx_x_x-intc.dtsi. The configurations are stored in the opaque array */
|
||||
/* uint16 port_line_mapping[]. The bitfields for the opaque entries are defined in */
|
||||
/* dt-bindings/interrupt-controller/infineon-xmc4xxx-intc.h. */
|
||||
|
||||
struct isr_cb {
|
||||
/* if fn is NULL it implies the interrupt line has not been allocated */
|
||||
void (*fn)(const struct device *dev, int pin);
|
||||
void *data;
|
||||
enum gpio_int_mode mode;
|
||||
uint8_t port_id;
|
||||
uint8_t pin;
|
||||
};
|
||||
|
||||
#define MAX_ISR_NUM 8
|
||||
struct intc_xmc4xxx_data {
|
||||
struct isr_cb cb[MAX_ISR_NUM];
|
||||
};
|
||||
|
||||
#define NUM_ERUS 2
|
||||
struct intc_xmc4xxx_config {
|
||||
XMC_ERU_t *eru_regs[NUM_ERUS];
|
||||
};
|
||||
|
||||
static const uint16_t port_line_mapping[DT_INST_PROP_LEN(0, port_line_mapping)] =
|
||||
DT_INST_PROP(0, port_line_mapping);
|
||||
|
||||
int intc_xmc4xxx_gpio_enable_interrupt(int port_id, int pin, enum gpio_int_mode mode,
|
||||
enum gpio_int_trig trig,
|
||||
void (*fn)(const struct device *, int), void *user_data)
|
||||
{
|
||||
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||
struct intc_xmc4xxx_data *data = dev->data;
|
||||
const struct intc_xmc4xxx_config *config = dev->config;
|
||||
int ret = -ENOTSUP;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(port_line_mapping); i++) {
|
||||
XMC_ERU_ETL_CONFIG_t etl_config = {0};
|
||||
XMC_ERU_OGU_CONFIG_t isr_config = {0};
|
||||
XMC_ERU_ETL_EDGE_DETECTION_t trig_xmc;
|
||||
XMC_ERU_t *eru;
|
||||
int port_map, pin_map, line, eru_src, eru_ch;
|
||||
struct isr_cb *cb;
|
||||
|
||||
port_map = XMC4XXX_INTC_GET_PORT(port_line_mapping[i]);
|
||||
pin_map = XMC4XXX_INTC_GET_PIN(port_line_mapping[i]);
|
||||
|
||||
if (port_map != port_id || pin_map != pin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
line = XMC4XXX_INTC_GET_LINE(port_line_mapping[i]);
|
||||
cb = &data->cb[line];
|
||||
if (cb->fn) {
|
||||
/* It's already used. Continue search for available line */
|
||||
/* with same port/pin */
|
||||
ret = -EBUSY;
|
||||
continue;
|
||||
}
|
||||
|
||||
eru_src = XMC4XXX_INTC_GET_ERU_SRC(port_line_mapping[i]);
|
||||
eru_ch = line & 0x3;
|
||||
|
||||
if (trig == GPIO_INT_TRIG_HIGH) {
|
||||
trig_xmc = XMC_ERU_ETL_EDGE_DETECTION_RISING;
|
||||
} else if (trig == GPIO_INT_TRIG_LOW) {
|
||||
trig_xmc = XMC_ERU_ETL_EDGE_DETECTION_FALLING;
|
||||
} else if (trig == GPIO_INT_TRIG_BOTH) {
|
||||
trig_xmc = XMC_ERU_ETL_EDGE_DETECTION_BOTH;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cb->port_id = port_id;
|
||||
cb->pin = pin;
|
||||
cb->mode = mode;
|
||||
cb->fn = fn;
|
||||
cb->data = user_data;
|
||||
|
||||
/* setup the eru */
|
||||
etl_config.edge_detection = trig_xmc;
|
||||
etl_config.input_a = eru_src;
|
||||
etl_config.input_b = eru_src;
|
||||
etl_config.source = eru_src >> 2;
|
||||
etl_config.status_flag_mode = XMC_ERU_ETL_STATUS_FLAG_MODE_HWCTRL;
|
||||
etl_config.enable_output_trigger = 1;
|
||||
etl_config.output_trigger_channel = eru_ch;
|
||||
|
||||
eru = config->eru_regs[line >> 2];
|
||||
|
||||
XMC_ERU_ETL_Init(eru, eru_ch, &etl_config);
|
||||
|
||||
isr_config.service_request = XMC_ERU_OGU_SERVICE_REQUEST_ON_TRIGGER;
|
||||
XMC_ERU_OGU_Init(eru, eru_ch, &isr_config);
|
||||
|
||||
/* if the gpio level is already set then we must manually set the interrupt to */
|
||||
/* pending */
|
||||
if (mode == GPIO_INT_MODE_LEVEL) {
|
||||
ret = gpio_pin_get_raw(user_data, pin);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
#define NVIC_ISPR_BASE 0xe000e200u
|
||||
if ((ret == 0 && trig == GPIO_INT_TRIG_LOW) ||
|
||||
(ret == 1 && trig == GPIO_INT_TRIG_HIGH)) {
|
||||
eru->EXICON_b[eru_ch].FL = 1;
|
||||
/* put interrupt into pending state */
|
||||
*(uint32_t *)(NVIC_ISPR_BASE) |= BIT(line + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int intc_xmc4xxx_gpio_disable_interrupt(int port_id, int pin)
|
||||
{
|
||||
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||
const struct intc_xmc4xxx_config *config = dev->config;
|
||||
struct intc_xmc4xxx_data *data = dev->data;
|
||||
int eru_ch;
|
||||
|
||||
for (int line = 0; line < ARRAY_SIZE(data->cb); line++) {
|
||||
struct isr_cb *cb;
|
||||
|
||||
cb = &data->cb[line];
|
||||
eru_ch = line & 0x3;
|
||||
if (cb->fn && cb->port_id == port_id && cb->pin == pin) {
|
||||
XMC_ERU_t *eru = config->eru_regs[line >> 2];
|
||||
|
||||
cb->fn = NULL;
|
||||
/* disable the SR */
|
||||
eru->EXICON_b[eru_ch].PE = 0;
|
||||
/* unset the status flag */
|
||||
eru->EXICON_b[eru_ch].FL = 0;
|
||||
/* no need to clear other variables in cb*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void intc_xmc4xxx_isr(void *arg)
|
||||
{
|
||||
int line = (int)arg;
|
||||
const struct device *dev = DEVICE_DT_INST_GET(0);
|
||||
struct intc_xmc4xxx_data *data = dev->data;
|
||||
const struct intc_xmc4xxx_config *config = dev->config;
|
||||
struct isr_cb *cb = &data->cb[line];
|
||||
XMC_ERU_t *eru = config->eru_regs[line >> 2];
|
||||
int eru_ch = line & 0x3;
|
||||
|
||||
/* The callback function may actually disable the interrupt and set cb->fn = NULL */
|
||||
/* as is done in tests/drivers/gpio/gpio_api_1pin. Assume that the callback function */
|
||||
/* will NOT disable the interrupt and then enable another port/pin */
|
||||
/* in the same callback which could potentially set cb->fn again. */
|
||||
while (cb->fn) {
|
||||
cb->fn(cb->data, cb->pin);
|
||||
/* for level triggered interrupts we have to manually check the status. */
|
||||
if (cb->mode == GPIO_INT_MODE_LEVEL && eru->EXICON_b[eru_ch].FL == 1) {
|
||||
continue;
|
||||
}
|
||||
/* break for edge triggered interrupts */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define INTC_IRQ_CONNECT_ENABLE(name, line_number) \
|
||||
COND_CODE_1(DT_INST_IRQ_HAS_NAME(0, name), \
|
||||
(IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, name, irq), \
|
||||
DT_INST_IRQ_BY_NAME(0, name, priority), intc_xmc4xxx_isr, (void *)line_number, 0); \
|
||||
irq_enable(DT_INST_IRQ_BY_NAME(0, name, irq));), ())
|
||||
|
||||
static int intc_xmc4xxx_init(const struct device *dev)
|
||||
{
|
||||
/* connect irqs only if they defined by name in the dts */
|
||||
INTC_IRQ_CONNECT_ENABLE(eru0sr0, 0);
|
||||
INTC_IRQ_CONNECT_ENABLE(eru0sr1, 1);
|
||||
INTC_IRQ_CONNECT_ENABLE(eru0sr2, 2);
|
||||
INTC_IRQ_CONNECT_ENABLE(eru0sr3, 3);
|
||||
INTC_IRQ_CONNECT_ENABLE(eru1sr0, 4);
|
||||
INTC_IRQ_CONNECT_ENABLE(eru1sr1, 5);
|
||||
INTC_IRQ_CONNECT_ENABLE(eru1sr2, 6);
|
||||
INTC_IRQ_CONNECT_ENABLE(eru1sr3, 7);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct intc_xmc4xxx_data intc_xmc4xxx_data0;
|
||||
|
||||
struct intc_xmc4xxx_config intc_xmc4xxx_config0 = {
|
||||
.eru_regs = {
|
||||
(XMC_ERU_t *)DT_INST_REG_ADDR_BY_NAME(0, eru0),
|
||||
(XMC_ERU_t *)DT_INST_REG_ADDR_BY_NAME(0, eru1),
|
||||
},
|
||||
};
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, intc_xmc4xxx_init, NULL,
|
||||
&intc_xmc4xxx_data0, &intc_xmc4xxx_config0, PRE_KERNEL_1,
|
||||
CONFIG_INTC_INIT_PRIORITY, NULL);
|
44
dts/arm/infineon/xmc4500_F100x1024-intc.dtsi
Normal file
44
dts/arm/infineon/xmc4500_F100x1024-intc.dtsi
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Schlumberger
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/dt-bindings/interrupt-controller/infineon-xmc4xxx-intc.h>
|
||||
|
||||
&intc {
|
||||
port-line-mapping = <
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 1, 0, 0) /* ERU0_ETL0_INPUTA_P0_1 XMC_ERU_ETL_INPUT_A0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(2, 5, 2, 0) /* ERU0_ETL0_INPUTA_P2_5 XMC_ERU_ETL_INPUT_A2 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(3, 2, 1, 0) /* ERU0_ETL0_INPUTA_P3_2 XMC_ERU_ETL_INPUT_A1 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 0, 4, 0) /* ERU0_ETL0_INPUTB_P0_0 XMC_ERU_ETL_INPUT_B0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(2, 0, 7, 0) /* ERU0_ETL0_INPUTB_P2_0 XMC_ERU_ETL_INPUT_B3 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(2, 4, 6, 0) /* ERU0_ETL0_INPUTB_P2_4 XMC_ERU_ETL_INPUT_B2 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(3, 1, 5, 0) /* ERU0_ETL0_INPUTB_P3_1 XMC_ERU_ETL_INPUT_B1 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 10, 0, 1) /* ERU0_ETL1_INPUTA_P0_10 XMC_ERU_ETL_INPUT_A0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(2, 3, 2, 1) /* ERU0_ETL1_INPUTA_P2_3 XMC_ERU_ETL_INPUT_A2 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 9, 4, 1) /* ERU0_ETL1_INPUTB_P0_9 XMC_ERU_ETL_INPUT_B0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(2, 2, 6, 1) /* ERU0_ETL1_INPUTB_P2_2 XMC_ERU_ETL_INPUT_B2 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(2, 6, 7, 1) /* ERU0_ETL1_INPUTB_P2_6 XMC_ERU_ETL_INPUT_B3 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 8, 1, 2) /* ERU0_ETL2_INPUTA_P0_8 XMC_ERU_ETL_INPUT_A1 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(1, 5, 0, 2) /* ERU0_ETL2_INPUTA_P1_5 XMC_ERU_ETL_INPUT_A0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 12, 6, 2) /* ERU0_ETL2_INPUTB_P0_12 XMC_ERU_ETL_INPUT_B2 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 4, 7, 2) /* ERU0_ETL2_INPUTB_P0_4 XMC_ERU_ETL_INPUT_B3 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 7, 5, 2) /* ERU0_ETL2_INPUTB_P0_7 XMC_ERU_ETL_INPUT_B1 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(1, 4, 4, 2) /* ERU0_ETL2_INPUTB_P1_4 XMC_ERU_ETL_INPUT_B0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 11, 2, 3) /* ERU0_ETL3_INPUTA_P0_11 XMC_ERU_ETL_INPUT_A2 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(1, 1, 0, 3) /* ERU0_ETL3_INPUTA_P1_1 XMC_ERU_ETL_INPUT_A0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(3, 6, 1, 3) /* ERU0_ETL3_INPUTA_P3_6 XMC_ERU_ETL_INPUT_A1 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 2, 7, 3) /* ERU0_ETL3_INPUTB_P0_2 XMC_ERU_ETL_INPUT_B3 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 6, 6, 3) /* ERU0_ETL3_INPUTB_P0_6 XMC_ERU_ETL_INPUT_B2 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(1, 0, 4, 3) /* ERU0_ETL3_INPUTB_P1_0 XMC_ERU_ETL_INPUT_B0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(3, 5, 5, 3) /* ERU0_ETL3_INPUTB_P3_5 XMC_ERU_ETL_INPUT_B1 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(1, 5, 0, 4) /* ERU1_ETL0_INPUTA_P1_5 XMC_ERU_ETL_INPUT_A0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(2, 1, 4, 4) /* ERU1_ETL0_INPUTB_P2_1 XMC_ERU_ETL_INPUT_B0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(1, 15, 0, 5) /* ERU1_ETL1_INPUTA_P1_15 XMC_ERU_ETL_INPUT_A0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(2, 7, 4, 5) /* ERU1_ETL1_INPUTB_P2_7 XMC_ERU_ETL_INPUT_B0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(1, 3, 0, 6) /* ERU1_ETL2_INPUTA_P1_3 XMC_ERU_ETL_INPUT_A0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(1, 2, 4, 6) /* ERU1_ETL2_INPUTB_P1_2 XMC_ERU_ETL_INPUT_B0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 5, 0, 7) /* ERU1_ETL3_INPUTA_P0_5 XMC_ERU_ETL_INPUT_A0 */
|
||||
XMC4XXX_INTC_SET_LINE_MAP(0, 3, 4, 7) /* ERU1_ETL3_INPUTB_P0_3 XMC_ERU_ETL_INPUT_B0 */
|
||||
>;
|
||||
};
|
|
@ -51,6 +51,16 @@
|
|||
};
|
||||
|
||||
soc {
|
||||
intc: eru@40044000 {
|
||||
compatible = "infineon,xmc4xxx-intc";
|
||||
reg = <0x40044000 0xff>, <0x50004800 0xff>;
|
||||
/* naming order is intentional. eru1 maps to a lower address than eru0 */
|
||||
reg-names = "eru1", "eru0";
|
||||
interrupts = <1 1>, <2 1>, <3 1>, <4 1>, <5 1>, <6 1>, <7 1>, <8 1>;
|
||||
interrupt-names = "eru0sr0", "eru0sr1", "eru0sr2", "eru0sr3",
|
||||
"eru1sr0", "eru1sr1", "eru1sr2", "eru1sr3";
|
||||
};
|
||||
|
||||
pinctrl: pinctrl@48028000 {
|
||||
compatible = "infineon,xmc4xxx-pinctrl";
|
||||
#address-cells = <1>;
|
||||
|
|
22
dts/bindings/interrupt-controller/infineon,xmc4xxx-intc.yaml
Normal file
22
dts/bindings/interrupt-controller/infineon,xmc4xxx-intc.yaml
Normal file
|
@ -0,0 +1,22 @@
|
|||
description: Infineon XMC4XXX series Interrupt Controller
|
||||
|
||||
compatible: "infineon,xmc4xxx-intc"
|
||||
|
||||
include: base.yaml
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
port-line-mapping:
|
||||
type: array
|
||||
required: true
|
||||
description: |
|
||||
An array to store the Event Request Unit (ERU) configuration for a given port/pin
|
||||
combintation. The array elements are opaque fields set using the macro
|
||||
XMC4XXX_INTC_SET_LINE_MAP(port, pin, eru_src, line);
|
||||
eru_src defines where the specific port/pin combination is connected in the ERU.
|
||||
line defines the SR line that will be raised by the event.
|
||||
|
||||
interrupts:
|
||||
required: true
|
43
include/zephyr/drivers/interrupt_controller/intc_xmc4xxx.h
Normal file
43
include/zephyr/drivers/interrupt_controller/intc_xmc4xxx.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Schlumberger
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_XMC4XXX_INTC_H_
|
||||
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_XMC4XXX_INTC_H_
|
||||
|
||||
/**
|
||||
* @brief Enable interrupt for specific port_id and pin combination
|
||||
*
|
||||
* @param port_id Port index
|
||||
* @param pin pin Pin the port
|
||||
* @param mode Level or edge interrupt
|
||||
* @param trig Trigger edge type (falling, rising or both)
|
||||
* @param fn Callback function
|
||||
* @param user_data Parameter to the interrupt callback
|
||||
*
|
||||
* @retval 0 On success
|
||||
* @retval -ENOTSUP If the specific port_id/pin combination is not supported or
|
||||
* not defined in the dts
|
||||
* @retval -EBUSY If the interrupt line is already used by a different port_id/pin
|
||||
* @retval -EINVAL If the trigger combination is invalid
|
||||
*
|
||||
*/
|
||||
|
||||
int intc_xmc4xxx_gpio_enable_interrupt(int port_id, int pin, enum gpio_int_mode mode,
|
||||
enum gpio_int_trig trig, void(*fn)(const struct device*, int), void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Disable interrupt for specific port_id and pin combination
|
||||
*
|
||||
* @param port_id Port index
|
||||
* @param pin pin Pin the port
|
||||
* @retval 0 On susccess
|
||||
* @retval -EINVAL If the specific port_id and pin combination has no interrupt
|
||||
* enabled
|
||||
*/
|
||||
|
||||
int intc_xmc4xxx_gpio_disable_interrupt(int port_id, int pin);
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_XMC4XXX_INTC_H_ */
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Schlumberger
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_INFINEON_XMC4XXX_INTC_H_
|
||||
#define ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_INFINEON_XMC4XXX_INTC_H_
|
||||
|
||||
#define XMC4XXX_INTC_PORT_POS 0
|
||||
#define XMC4XXX_INTC_PORT_MASK 0xf
|
||||
|
||||
#define XMC4XXX_INTC_PIN_POS 4
|
||||
#define XMC4XXX_INTC_PIN_MASK 0xf
|
||||
|
||||
#define XMC4XXX_INTC_LINE_POS 8
|
||||
#define XMC4XXX_INTC_LINE_MASK 0x7
|
||||
|
||||
#define XMC4XXX_INTC_ERU_SRC_POS 11
|
||||
#define XMC4XXX_INTC_ERU_SRC_MASK 0x7
|
||||
|
||||
#define XMC4XXX_INTC_GET_PORT(mx) ((mx >> XMC4XXX_INTC_PORT_POS) & XMC4XXX_INTC_PORT_MASK)
|
||||
#define XMC4XXX_INTC_GET_PIN(mx) ((mx >> XMC4XXX_INTC_PIN_POS) & XMC4XXX_INTC_PIN_MASK)
|
||||
#define XMC4XXX_INTC_GET_LINE(mx) ((mx >> XMC4XXX_INTC_LINE_POS) & XMC4XXX_INTC_LINE_MASK)
|
||||
#define XMC4XXX_INTC_GET_ERU_SRC(mx) ((mx >> XMC4XXX_INTC_ERU_SRC_POS) & XMC4XXX_INTC_ERU_SRC_MASK)
|
||||
|
||||
#define XMC4XXX_INTC_SET_LINE_MAP(port, pin, eru_src, line) \
|
||||
((port) << XMC4XXX_INTC_PORT_POS | (pin) << XMC4XXX_INTC_PIN_POS | \
|
||||
(eru_src) << XMC4XXX_INTC_ERU_SRC_POS | (line) << XMC4XXX_INTC_LINE_POS)
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_INFINEON_XMC4XXX_INTC_H_ */
|
|
@ -19,4 +19,10 @@ config HAS_XMCLIB_FLASH
|
|||
bool
|
||||
help
|
||||
Enable XMCLIB Flash
|
||||
|
||||
config HAS_XMCLIB_ERU
|
||||
bool
|
||||
help
|
||||
Enable XMCLIB Event Request Unit (ERU) for GPIO interrupt support
|
||||
|
||||
endif # HAS_XMCLIB
|
||||
|
|
|
@ -14,5 +14,6 @@ config SOC_SERIES_XMC_4XXX
|
|||
select CPU_HAS_FPU
|
||||
select HAS_XMCLIB_UART
|
||||
select HAS_XMCLIB_FLASH
|
||||
select HAS_XMCLIB_ERU
|
||||
help
|
||||
Enable support for XMC 4xxx MCU series
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue