Skip to content

Commit 956064b

Browse files
committed
[NUCLEO_F103RB] Add InterruptIn
1 parent da605b8 commit 956064b

File tree

4 files changed

+246
-5
lines changed

4 files changed

+246
-5
lines changed

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/device.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#define DEVICE_PORTOUT 1
2121
#define DEVICE_PORTINOUT 1
2222

23-
#define DEVICE_INTERRUPTIN 0
23+
#define DEVICE_INTERRUPTIN 1
2424

2525
#define DEVICE_ANALOGIN 1
2626
#define DEVICE_ANALOGOUT 0
@@ -37,14 +37,14 @@
3737

3838
#define DEVICE_PWMOUT 1
3939

40+
#define DEVICE_SLEEP 0
41+
4042
//=======================================
4143

4244
#define DEVICE_SEMIHOST 0
4345
#define DEVICE_LOCALFILESYSTEM 0
4446
#define DEVICE_ID_LENGTH 24
4547

46-
#define DEVICE_SLEEP 0
47-
4848
#define DEVICE_DEBUG_AWARENESS 0
4949

5050
#define DEVICE_STDIO_MESSAGES 1
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2013 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include <stddef.h>
17+
#include "cmsis.h"
18+
19+
#include "gpio_irq_api.h"
20+
#include "error.h"
21+
22+
#define EDGE_NONE (0)
23+
#define EDGE_RISE (1)
24+
#define EDGE_FALL (2)
25+
#define EDGE_BOTH (3)
26+
27+
#define CHANNEL_NUM (16)
28+
29+
static uint32_t channel_ids[CHANNEL_NUM] = {0};
30+
31+
static gpio_irq_handler irq_handler;
32+
33+
static void handle_interrupt_in(uint32_t channel) {
34+
if (channel_ids[channel] == 0) return;
35+
36+
uint32_t exti_line = (uint32_t)(1 << channel);
37+
if (EXTI_GetITStatus(exti_line) != RESET)
38+
{
39+
EXTI_ClearITPendingBit(exti_line);
40+
}
41+
// Check if it's a rising or a falling event
42+
if (EXTI->RTSR & (uint32_t)(1 << channel)) {
43+
irq_handler(channel_ids[channel], IRQ_RISE);
44+
}
45+
else {
46+
irq_handler(channel_ids[channel], IRQ_FALL);
47+
}
48+
}
49+
50+
static void gpio_irq0(void) {handle_interrupt_in(0);}
51+
static void gpio_irq1(void) {handle_interrupt_in(1);}
52+
static void gpio_irq2(void) {handle_interrupt_in(2);}
53+
static void gpio_irq3(void) {handle_interrupt_in(3);}
54+
static void gpio_irq4(void) {handle_interrupt_in(4);}
55+
static void gpio_irq5(void) {handle_interrupt_in(5);}
56+
static void gpio_irq6(void) {handle_interrupt_in(6);}
57+
static void gpio_irq7(void) {handle_interrupt_in(7);}
58+
static void gpio_irq8(void) {handle_interrupt_in(8);}
59+
static void gpio_irq9(void) {handle_interrupt_in(9);}
60+
static void gpio_irq10(void) {handle_interrupt_in(10);}
61+
static void gpio_irq11(void) {handle_interrupt_in(11);}
62+
static void gpio_irq12(void) {handle_interrupt_in(12);}
63+
static void gpio_irq13(void) {handle_interrupt_in(13);}
64+
static void gpio_irq14(void) {handle_interrupt_in(14);}
65+
static void gpio_irq15(void) {handle_interrupt_in(15);}
66+
67+
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
68+
IRQn_Type irq_n = (IRQn_Type)0;
69+
uint32_t vector = 0;
70+
71+
if (pin == NC) return -1;
72+
73+
uint32_t pin_number = (uint32_t)pin;
74+
uint32_t pin_index = (pin_number & 0xF);
75+
uint32_t port_index = (pin_number >> 4);
76+
77+
// Select irq number and vector
78+
switch (pin_index) {
79+
case 0:
80+
irq_n = EXTI0_IRQn;
81+
vector = (uint32_t)&gpio_irq0;
82+
break;
83+
case 1:
84+
irq_n = EXTI1_IRQn;
85+
vector = (uint32_t)&gpio_irq1;
86+
break;
87+
case 2:
88+
irq_n = EXTI2_IRQn;
89+
vector = (uint32_t)&gpio_irq2;
90+
break;
91+
case 3:
92+
irq_n = EXTI3_IRQn;
93+
vector = (uint32_t)&gpio_irq3;
94+
break;
95+
case 4:
96+
irq_n = EXTI4_IRQn;
97+
vector = (uint32_t)&gpio_irq4;
98+
break;
99+
case 5:
100+
irq_n = EXTI9_5_IRQn;
101+
vector = (uint32_t)&gpio_irq5;
102+
break;
103+
case 6:
104+
irq_n = EXTI9_5_IRQn;
105+
vector = (uint32_t)&gpio_irq6;
106+
break;
107+
case 7:
108+
irq_n = EXTI9_5_IRQn;
109+
vector = (uint32_t)&gpio_irq7;
110+
break;
111+
case 8:
112+
irq_n = EXTI9_5_IRQn;
113+
vector = (uint32_t)&gpio_irq8;
114+
break;
115+
case 9:
116+
irq_n = EXTI9_5_IRQn;
117+
vector = (uint32_t)&gpio_irq9;
118+
break;
119+
case 10:
120+
irq_n = EXTI15_10_IRQn;
121+
vector = (uint32_t)&gpio_irq10;
122+
break;
123+
case 11:
124+
irq_n = EXTI15_10_IRQn;
125+
vector = (uint32_t)&gpio_irq11;
126+
break;
127+
case 12:
128+
irq_n = EXTI15_10_IRQn;
129+
vector = (uint32_t)&gpio_irq12;
130+
break;
131+
case 13:
132+
irq_n = EXTI15_10_IRQn;
133+
vector = (uint32_t)&gpio_irq13;
134+
break;
135+
case 14:
136+
irq_n = EXTI15_10_IRQn;
137+
vector = (uint32_t)&gpio_irq14;
138+
break;
139+
case 15:
140+
irq_n = EXTI15_10_IRQn;
141+
vector = (uint32_t)&gpio_irq15;
142+
break;
143+
default:
144+
return -1;
145+
}
146+
147+
// Enable GPIO and AFIO clocks
148+
RCC_APB2PeriphClockCmd((uint32_t)(RCC_APB2Periph_GPIOA << port_index), ENABLE);
149+
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
150+
151+
// Connect EXTI line to pin
152+
GPIO_EXTILineConfig(port_index, pin_index);
153+
154+
// Configure EXTI line
155+
EXTI_InitTypeDef EXTI_InitStructure;
156+
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index);
157+
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
158+
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
159+
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
160+
EXTI_Init(&EXTI_InitStructure);
161+
162+
// Enable and set EXTI interrupt to the lowest priority
163+
NVIC_InitTypeDef NVIC_InitStructure;
164+
NVIC_InitStructure.NVIC_IRQChannel = irq_n;
165+
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
166+
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
167+
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
168+
NVIC_Init(&NVIC_InitStructure);
169+
170+
NVIC_SetVector(irq_n, vector);
171+
NVIC_EnableIRQ(irq_n);
172+
173+
// Save for future use
174+
obj->ch = pin_index;
175+
obj->irq_n = irq_n;
176+
obj->event = EDGE_NONE;
177+
178+
channel_ids[obj->ch] = id;
179+
180+
irq_handler = handler;
181+
182+
return 0;
183+
}
184+
185+
void gpio_irq_free(gpio_irq_t *obj) {
186+
channel_ids[obj->ch] = 0;
187+
// Disable EXTI line
188+
EXTI_InitTypeDef EXTI_InitStructure;
189+
EXTI_StructInit(&EXTI_InitStructure);
190+
EXTI_Init(&EXTI_InitStructure);
191+
obj->event = EDGE_NONE;
192+
}
193+
194+
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
195+
EXTI_InitTypeDef EXTI_InitStructure;
196+
197+
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << obj->ch);
198+
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
199+
200+
if (event == IRQ_RISE) {
201+
if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) {
202+
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
203+
obj->event = EDGE_BOTH;
204+
}
205+
else { // NONE or RISE
206+
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
207+
obj->event = EDGE_RISE;
208+
}
209+
}
210+
211+
if (event == IRQ_FALL) {
212+
if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) {
213+
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
214+
obj->event = EDGE_BOTH;
215+
}
216+
else { // NONE or FALL
217+
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
218+
obj->event = EDGE_FALL;
219+
}
220+
}
221+
222+
if (enable) {
223+
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
224+
}
225+
else {
226+
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
227+
}
228+
229+
EXTI_Init(&EXTI_InitStructure);
230+
}
231+
232+
void gpio_irq_enable(gpio_irq_t *obj) {
233+
NVIC_EnableIRQ(obj->irq_n);
234+
}
235+
236+
void gpio_irq_disable(gpio_irq_t *obj) {
237+
NVIC_DisableIRQ(obj->irq_n);
238+
obj->event = EDGE_NONE;
239+
}

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/i2c_api.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
170170
int timeout;
171171
int count;
172172

173+
if (length == 0) return 0;
174+
173175
/*
174176
// Wait until the bus is not busy anymore
175177
timeout = LONG_TIMEOUT;

libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F103RB/objects.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ extern "C" {
2626
#endif
2727

2828
struct gpio_irq_s {
29-
uint32_t port;
30-
uint32_t pin;
3129
uint32_t ch;
30+
IRQn_Type irq_n;
31+
uint32_t event; // 0=none, 1=rise, 2=fall, 3=rise+fall
3232
};
3333

3434
struct port_s {

0 commit comments

Comments
 (0)