📄 init_intrinfo.c
字号:
/* * $QNXLicenseC: * Copyright 2007, QNX Software Systems. * * Licensed under the Apache License, Version 2.0 (the "License"). You * may not reproduce, modify or distribute this software 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 OF ANY KIND, either express or implied. * * This file may contain contributions from others, either as * contributors under the License or as licensors under other terms. * Please review this entire file for other proprietary rights or license * notices, as well as the QNX Development Suite License Guide at * http://licensing.qnx.com/license-guide/ for other information. * $ *//* * MC9328MX21 interrupt controller support. */#include "startup.h"#include <arm/mx1.h>#include <arm/mx21.h>extern struct callout_rtn interrupt_id_mx21_gpio;extern struct callout_rtn interrupt_eoi_mx21_gpio;extern struct callout_rtn interrupt_mask_mx21_gpio;extern struct callout_rtn interrupt_unmask_mx21_gpio;static paddr_t mx21_aitc_base = MX21_AITC_BASE;static paddr_t mx21_gpio_base = MX21_GPIO_BASE;const static struct startup_intrinfo intrs[] = { { _NTO_INTR_CLASS_EXTERNAL, // vector base 64, // number of vectors _NTO_INTR_SPARE, // cascade vector 0, // CPU vector base 0, // CPU vector stride 0, // flags { INTR_GENFLAG_LOAD_SYSPAGE, 0, &interrupt_id_aitc }, { INTR_GENFLAG_LOAD_SYSPAGE | INTR_GENFLAG_LOAD_INTRMASK, 0, &interrupt_eoi_aitc }, &interrupt_mask_aitc, // mask callout &interrupt_unmask_aitc, // unmask callout 0, // config callout &mx21_aitc_base, }, // GPIO interrupt (Port A to Port F) (64-256) { 64, // vector base 192, // number of vectors 8, // cascade vector 0, // CPU vector base 0, // CPU vector stride 0, // flags { 0, 0, &interrupt_id_mx21_gpio }, { INTR_GENFLAG_LOAD_INTRMASK, 0, &interrupt_eoi_mx21_gpio }, &interrupt_mask_mx21_gpio, // mask callout &interrupt_unmask_mx21_gpio, // unmask callout 0, // config callout &mx21_gpio_base, },};#define GPIOINTR_SENSITIVE_MASK 0x03 /* Sensitive Mask */#define GPIOINTR_POSITIVE_EDGE 0x00 /* Positive Edge Sensitive */#define GPIOINTR_NEGATIVE_EDGE 0x01 /* Negative Edge Sensitive */#define GPIOINTR_POSITIVE_LEVEL 0x02 /* Positive Level Sensitive */#define GPIOINTR_NEGATIVE_LEVEL 0x03 /* Negative Level Sensitive */#define AITC_INTCNTL_FIDIS (1 << 21) /* Fast Interrupt Disable */#define AITC_INTCNTL_MD (1 << 16) /* Interrupt Vector Low */static void init_gpio_intr(void);void init_intrinfo(){ int i; /* * Disable Fast Interrupt * Interrupt Vector Locate at Low Memory */ out32(mx21_aitc_base + MX1_AITC_INTCNTL, AITC_INTCNTL_FIDIS | AITC_INTCNTL_MD); /* * Disable all interrupts */ out32(mx21_aitc_base + MX1_AITC_INTENABLEH, 0); out32(mx21_aitc_base + MX1_AITC_INTENABLEL, 0); /* * All interrupt sources generate normal interrupt */ out32(mx21_aitc_base + MX1_AITC_INTTYPEH, 0); out32(mx21_aitc_base + MX1_AITC_INTTYPEL, 0); /* * Only disable level 0 normal interrupt */ out32(mx21_aitc_base + MX1_AITC_NIMASK, 0); /* * Set all interrupt priority as highest normal interrupt */ for (i = MX1_AITC_NIPRIORITY7; i <= MX1_AITC_NIPRIORITY0; i += 4) out32(mx21_aitc_base + i, 0xFFFFFFFF); /* * Configure GPIO interrupts */ init_gpio_intr(); add_interrupt_array(intrs, sizeof(intrs));}static void config_one(unsigned base, int pin, unsigned sensitivity){ unsigned tmp, icr; /* * Configure GPIO In Use Register */ tmp = in32(base + MX1_GPIO_GIUS) | (1 << pin); out32(base + MX1_GPIO_GIUS, tmp); /* * Configure GPIO pin as input */ tmp = in32(base + MX1_GPIO_DDIR) & (~(1 << pin)); out32(base + MX1_GPIO_DDIR, tmp); /* * Pull up enable */ tmp = in32(base + MX1_GPIO_PUEN) & (~(1 << pin)); out32(base + MX1_GPIO_PUEN, tmp); /* * Configure Sensitivity */ if (pin > 15) { icr = MX1_GPIO_INTCR2; pin -= 16; } else icr = MX1_GPIO_INTCR1; pin <<= 1; tmp = in32(base + icr); tmp &= ~(GPIOINTR_SENSITIVE_MASK << pin); tmp |= sensitivity << pin; out32(base + icr, tmp);}static void init_gpio_intr(void){ uint32_t port; /* * Mask off all GPIO interrupts, and clear status */ for (port = MX21_PORTA_BASE; port <= MX21_PORTF_BASE; port += (MX21_PORTB_BASE - MX21_PORTA_BASE)) { out32(port + MX1_GPIO_INTMR, 0); out32(port + MX1_GPIO_INTSR, 0xFFFFFFFF); } out32(MX21_PORTE_BASE + MX1_GPIO_INTMR, 0); out32(MX21_PORTE_BASE + MX1_GPIO_INTSR, 0xFFFFFFFF);#define MX21_PMASK_PA (1 << 0)#define MX21_PMASK_PB (1 << 1)#define MX21_PMASK_PC (1 << 2)#define MX21_PMASK_PD (1 << 3)#define MX21_PMASK_PE (1 << 4)#define MX21_PMASK_PF (1 << 5) /* * Only PortE interrupts are used */ out32(MX21_PORT_MASK, MX21_PMASK_PC | MX21_PMASK_PE); /* * Port C8 : Negative Level Sensitive, for USB * Port E11 : Positive Level Sensitive, for Ethernet */ config_one(MX21_PORTC_BASE, 8, GPIOINTR_NEGATIVE_LEVEL); config_one(MX21_PORTE_BASE, 11, GPIOINTR_POSITIVE_LEVEL); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -