Skip to content

Commit 541f7bf

Browse files
giulcioffifacchinm
authored andcommitted
RP2040: Add gpio interrupt support
1 parent 168fc5d commit 541f7bf

File tree

1 file changed

+104
-1
lines changed
  • targets/TARGET_RASPBERRYPI/TARGET_RP2040

1 file changed

+104
-1
lines changed

targets/TARGET_RASPBERRYPI/TARGET_RP2040/gpio_api.c

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
#include "mbed_assert.h"
22
#include "hal/gpio_api.h"
3+
#include "gpio_irq_api.h"
34
#include "pinmap.h"
45
#include "mbed_error.h"
56

7+
#define GPIO_PIN_COUNT 30
8+
9+
static gpio_irq_handler m_irq_handler;
10+
static uint32_t m_channel_ids[GPIO_PIN_COUNT] = {0};
11+
static uint32_t m_pico_events[GPIO_PIN_COUNT] = {0};
12+
613
void gpio_write(gpio_t *obj, int value)
714
{
815
gpio_put(obj->pin, value);
@@ -16,16 +23,37 @@ int gpio_read(gpio_t *obj)
1623
void gpio_init(gpio_t *obj, PinName pin)
1724
{
1825
obj->pin = pin;
26+
27+
if (pin == (PinName)NC) {
28+
return;
29+
}
30+
1931
_gpio_init(obj->pin);
2032
}
2133

34+
static uint32_t gpio_convert_event(gpio_irq_event event)
35+
{
36+
uint32_t irq_event = 0;
37+
38+
if (event == IRQ_RISE) {
39+
irq_event = GPIO_IRQ_EDGE_RISE;
40+
} else if (event == IRQ_FALL) {
41+
irq_event = GPIO_IRQ_EDGE_FALL;
42+
}
43+
44+
return irq_event;
45+
}
46+
2247
void gpio_mode(gpio_t *obj, PinMode mode)
2348
{
49+
MBED_ASSERT(obj->pin != (PinName)NC);
50+
2451
gpio_set_pulls(obj->pin, mode == PullUp, mode == PullDown);
2552
}
2653

2754
void gpio_dir(gpio_t *obj, PinDirection direction)
2855
{
56+
MBED_ASSERT(obj->pin != (PinName)NC);
2957
obj->direction = direction;
3058
if (direction == PIN_OUTPUT) {
3159
gpio_set_dir(obj->pin, GPIO_OUT);
@@ -37,4 +65,79 @@ void gpio_dir(gpio_t *obj, PinDirection direction)
3765

3866
int gpio_is_connected(const gpio_t *obj) {
3967
return (obj->pin == NC ? 0 : 1);
40-
}
68+
}
69+
70+
71+
/***********
72+
GPIO IRQ
73+
***********/
74+
75+
#if DEVICE_INTERRUPTIN
76+
77+
static void _gpio_irq(uint gpio, uint32_t events)
78+
{
79+
gpio_irq_event ev;
80+
if (events == GPIO_IRQ_EDGE_RISE) {
81+
ev = IRQ_RISE;
82+
} else if (events == GPIO_IRQ_EDGE_FALL) {
83+
ev = IRQ_FALL;
84+
} else {
85+
ev = IRQ_NONE;
86+
}
87+
m_irq_handler(m_channel_ids[gpio], ev);
88+
}
89+
90+
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
91+
{
92+
if (pin == NC) {
93+
return -1;
94+
}
95+
MBED_ASSERT((uint32_t)pin < GPIO_PIN_COUNT);
96+
97+
m_channel_ids[pin] = id;
98+
m_irq_handler = handler;
99+
100+
obj->irq_n = IO_IRQ_BANK0;
101+
obj->pin = pin;
102+
obj->irq_index = id;
103+
104+
return 0;
105+
}
106+
107+
108+
void gpio_irq_free(gpio_irq_t *obj)
109+
{
110+
gpio_irq_disable(obj);
111+
obj->irq_n = 0;
112+
obj->pin = 0;
113+
obj->irq_index = 0;
114+
}
115+
116+
117+
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
118+
{
119+
uint32_t irq_event = gpio_convert_event(event);
120+
121+
if (enable) {
122+
m_pico_events[obj->pin] |= irq_event;
123+
obj->event = irq_event;
124+
gpio_irq_enable(obj);
125+
}
126+
}
127+
128+
129+
void gpio_irq_enable(gpio_irq_t *obj)
130+
{
131+
gpio_set_irq_enabled_with_callback(obj->pin, obj->event, true, _gpio_irq);
132+
}
133+
134+
135+
void gpio_irq_disable(gpio_irq_t *obj)
136+
{
137+
gpio_set_irq_enabled(obj->pin, m_pico_events[obj->pin], false);
138+
139+
obj->event = 0;
140+
m_pico_events[obj->pin] = 0;
141+
}
142+
143+
#endif

0 commit comments

Comments
 (0)