Skip to content

Commit 88e03ef

Browse files
committed
GPI IRQ
- nvic vectors number correction - gpio irq HAL implementation
1 parent e83f110 commit 88e03ef

File tree

2 files changed

+173
-4
lines changed
  • libraries/mbed/targets

2 files changed

+173
-4
lines changed

libraries/mbed/targets/cmsis/TARGET_Freescale/TARGET_K64F/cmsis_nvic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#ifndef MBED_CMSIS_NVIC_H
88
#define MBED_CMSIS_NVIC_H
99

10-
#define NVIC_NUM_VECTORS (16 + 101) // CORE + MCU Peripherals
10+
#define NVIC_NUM_VECTORS (16 + 85) // CORE + MCU Peripherals
1111
#define NVIC_USER_IRQ_OFFSET 16
1212

1313
#include "cmsis.h"

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/gpio_irq_api.c

Lines changed: 172 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,189 @@
1717
#include "cmsis.h"
1818

1919
#include "gpio_irq_api.h"
20+
#include "fsl_gpio_driver.h"
21+
#include "fsl_gpio_hal.h"
22+
#include "fsl_port_hal.h"
2023
#include "error.h"
2124

22-
static void handle_interrupt_in(PORT_Type *port, int ch_base) {
25+
#define CHANNEL_NUM 160
2326

27+
static uint32_t channel_ids[CHANNEL_NUM] = {0};
28+
static gpio_irq_handler irq_handler;
29+
30+
#define IRQ_DISABLED (0)
31+
#define IRQ_RAISING_EDGE (9)
32+
#define IRQ_FALLING_EDGE (10)
33+
#define IRQ_EITHER_EDGE (11)
34+
35+
static void handle_interrupt_in(PortName port, int ch_base) {
36+
uint32_t i;
37+
38+
for (i = 0; i < 32; i++) {
39+
if (port_hal_read_pin_interrupt_flag(port, i)) {
40+
uint32_t id = channel_ids[ch_base + i];
41+
if (id == 0)
42+
continue;
43+
44+
gpio_irq_event event = IRQ_NONE;
45+
switch (BR_PORT_PCRn_IRQC(port, i)) {
46+
case IRQ_RAISING_EDGE:
47+
event = IRQ_RISE;
48+
break;
49+
50+
case IRQ_FALLING_EDGE:
51+
event = IRQ_FALL;
52+
break;
53+
54+
case IRQ_EITHER_EDGE:
55+
event = (gpio_hal_read_pin_input(port, i)) ? (IRQ_RISE) : (IRQ_FALL);
56+
break;
57+
}
58+
if (event != IRQ_NONE)
59+
irq_handler(id, event);
60+
}
61+
}
62+
port_hal_clear_port_interrupt_flag(port);
2463
}
2564

65+
void gpio_irqA(void) {handle_interrupt_in(PortA, 0);}
66+
void gpio_irqB(void) {handle_interrupt_in(PortB, 32);}
67+
void gpio_irqC(void) {handle_interrupt_in(PortC, 64);}
68+
void gpio_irqD(void) {handle_interrupt_in(PortD, 96);}
69+
void gpio_irqE(void) {handle_interrupt_in(PortE, 128);}
70+
2671
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
27-
return 1;
72+
if (pin == NC)
73+
return -1;
74+
75+
irq_handler = handler;
76+
77+
obj->port = pin >> GPIO_PORT_SHIFT;
78+
obj->pin = pin & 0x7F;
79+
80+
uint32_t ch_base, vector;
81+
IRQn_Type irq_n;
82+
switch (obj->port) {
83+
case PortA:
84+
ch_base = 0;
85+
irq_n = PORTA_IRQn;
86+
vector = (uint32_t)gpio_irqA;
87+
break;
88+
case PortB:
89+
ch_base = 32;
90+
irq_n = PORTB_IRQn;
91+
vector = (uint32_t)gpio_irqB;
92+
break;
93+
case PortC:
94+
ch_base = 64;
95+
irq_n = PORTC_IRQn;
96+
vector = (uint32_t)gpio_irqC;
97+
break;
98+
case PortD:
99+
ch_base = 96;
100+
irq_n = PORTD_IRQn;
101+
vector = (uint32_t)gpio_irqD;
102+
break;
103+
case PortE:
104+
ch_base = 128;
105+
irq_n = PORTE_IRQn;
106+
vector = (uint32_t)gpio_irqE;
107+
break;
108+
109+
default:
110+
error("gpio_irq only supported on port A-E.\n");
111+
break;
112+
}
113+
NVIC_SetVector(irq_n, vector);
114+
NVIC_EnableIRQ(irq_n);
115+
116+
obj->ch = ch_base + obj->pin;
117+
channel_ids[obj->ch] = id;
118+
119+
return 0;
28120
}
29121

30122
void gpio_irq_free(gpio_irq_t *obj) {
31-
123+
channel_ids[obj->ch] = 0;
32124
}
33125

34126
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
127+
port_interrupt_config_t irq_settings = kPortIntDisabled;
128+
129+
switch (BR_PORT_PCRn_IRQC(obj->port, obj->pin)) {
130+
case IRQ_DISABLED:
131+
if (enable)
132+
irq_settings = (event == IRQ_RISE) ? (kPortIntRisingEdge) : (kPortIntFallingEdge);
133+
break;
134+
135+
case IRQ_RAISING_EDGE:
136+
if (enable) {
137+
irq_settings = (event == IRQ_RISE) ? (kPortIntRisingEdge) : (kPortIntEitherEdge);
138+
} else {
139+
if (event == IRQ_FALL)
140+
irq_settings = kPortIntRisingEdge;
141+
}
142+
break;
143+
144+
case IRQ_FALLING_EDGE:
145+
if (enable) {
146+
irq_settings = (event == IRQ_FALL) ? (kPortIntFallingEdge) : (kPortIntEitherEdge);
147+
} else {
148+
if (event == IRQ_RISE)
149+
irq_settings = kPortIntFallingEdge;
150+
}
151+
break;
152+
153+
case IRQ_EITHER_EDGE:
154+
if (enable) {
155+
irq_settings = kPortIntEitherEdge;
156+
} else {
157+
irq_settings = (event == IRQ_RISE) ? (kPortIntFallingEdge) : (kPortIntRisingEdge);
158+
}
159+
break;
160+
}
161+
162+
// Interrupt configuration and clear interrupt
163+
port_hal_configure_pin_interrupt(obj->port, obj->pin, irq_settings);
164+
port_hal_clear_pin_interrupt_flag(obj->port, obj->pin);
165+
}
166+
167+
void gpio_irq_enable(gpio_irq_t *obj) {
168+
switch (obj->port) {
169+
case PortA:
170+
NVIC_EnableIRQ(PORTA_IRQn);
171+
break;
172+
case PortB:
173+
NVIC_EnableIRQ(PORTB_IRQn);
174+
break;
175+
case PortC:
176+
NVIC_EnableIRQ(PORTC_IRQn);
177+
break;
178+
case PortD:
179+
NVIC_EnableIRQ(PORTD_IRQn);
180+
break;
181+
case PortE:
182+
NVIC_EnableIRQ(PORTE_IRQn);
183+
break;
184+
}
185+
}
35186

187+
void gpio_irq_disable(gpio_irq_t *obj) {
188+
switch (obj->port) {
189+
case PortA:
190+
NVIC_DisableIRQ(PORTA_IRQn);
191+
break;
192+
case PortB:
193+
NVIC_DisableIRQ(PORTB_IRQn);
194+
break;
195+
case PortC:
196+
NVIC_DisableIRQ(PORTC_IRQn);
197+
break;
198+
case PortD:
199+
NVIC_DisableIRQ(PORTD_IRQn);
200+
break;
201+
case PortE:
202+
NVIC_DisableIRQ(PORTE_IRQn);
203+
break;
204+
}
36205
}

0 commit comments

Comments
 (0)