Loading...
/* * Copyright (c) 2020 Linaro Ltd. * Copyright (c) 2020 ATL Electronics * * SPDX-License-Identifier: Apache-2.0 */ /** @file * @brief Cypress PSoC-6 MCU family devicetree helper macros */ #ifndef _CYPRESS_PSOC6_DT_H_ #define _CYPRESS_PSOC6_DT_H_ #include <devicetree.h> /* * Devicetree macros related to interrupt * * The main "API" macro is CY_PSOC6_IRQ_CONFIG. It is an internal definition * used to configure the PSoC-6 interrupts in a generic way. This is necessary * because Cortex-M0+ can handle a limited number of interrupts and have * multiplexers in front of any NVIC interrupt line. * * The CY_PSOC6_IRQ_CONFIG expands from CY_PSOC6_DT_INST_NVIC_INSTALL, the * public API used by drivers. See below code fragment: * * static void <driver>_psoc6_isr(const struct device *dev) * { * ... * } * * #define <DRIVER>_PSOC6_INIT(n) \ * ... \ * static void <driver>_psoc6_irq_config(const struct device *port) \ * { \ * CY_PSOC6_DT_INST_NVIC_INSTALL(n, \ * <driver>_psoc6_isr); \ * }; \ * }; * * where: * n - driver instance number * isr - isr function to be called * * Cortex-M4 simple pass the parameter and constructs an usual NVIC * configuration code. * * The Cortex-M0+ must get from interrupt parent the interrupt line and * configure the interrupt channel to connect PSoC-6 peripheral interrupt to * Cortex-M0+ NVIC. The multiplexer is configured by CY_PSOC6_DT_NVIC_MUX_MAP * using the interrupt value from the interrupt parent. * * see cypress,psoc6-int-mux.yaml for devicetree documentation. */ #ifdef CONFIG_CPU_CORTEX_M0PLUS /* Cortex-M0+ * - install config only when exists an interrupt_parent property * - get peripheral irq using PROP_BY_INDEX, to avoid translation from * interrupt-parent node property. * - configure interrupt channel using the channel number register value from * interrupt-parent node. */ #define CY_PSOC6_DT_INST_NVIC_INSTALL(n, isr) \ IF_ENABLED(DT_INST_NODE_HAS_PROP(n, interrupt_parent),\ (CY_PSOC6_IRQ_CONFIG(n, isr))) #define CY_PSOC6_NVIC_MUX_IRQN(n) DT_IRQN(DT_INST_PHANDLE_BY_IDX(n,\ interrupt_parent, 0)) /* * DT_INST_PROP_BY_IDX should be used get interrupt and configure, instead * DT_INST_IRQN. The DT_INST_IRQN return IRQ number with level translation, * since it uses interrupt-parent, and the value at Cortex-M0 NVIC multiplexers * will be wrong. * * See multi-level-interrupt-handling. */ #define CY_PSOC6_NVIC_MUX_MAP(n) Cy_SysInt_SetInterruptSource( \ DT_IRQN(DT_INST_PHANDLE_BY_IDX(n,\ interrupt_parent, 0)), \ DT_INST_PROP_BY_IDX(n, interrupts, 0)) #else /* Cortex-M4 * - bypass config * - uses irq directly from peripheral devicetree definition * - no map/translations */ #define CY_PSOC6_DT_INST_NVIC_INSTALL(n, isr) CY_PSOC6_IRQ_CONFIG(n, isr) #define CY_PSOC6_NVIC_MUX_IRQN(n) DT_INST_IRQN(n) #define CY_PSOC6_NVIC_MUX_MAP(n) #endif #define CY_PSOC6_IRQ_CONFIG(n, isr) \ do { \ IRQ_CONNECT(CY_PSOC6_NVIC_MUX_IRQN(n), \ DT_INST_IRQ(n, priority), \ isr, DEVICE_DT_INST_GET(n), 0);\ CY_PSOC6_NVIC_MUX_MAP(n); \ irq_enable(CY_PSOC6_NVIC_MUX_IRQN(n)); \ } while (0) #endif /* _CYPRESS_PSOC6_SOC_DT_H_ */ |