Skip to content

Commit 572b223

Browse files
committed
Merge pull request #129 from bcostm/master
[NUCLEO_F103RB] InterruptIn, Sleep, RTC added
2 parents 2fb9de9 + adce27f commit 572b223

File tree

5 files changed

+366
-6
lines changed

5 files changed

+366
-6
lines changed

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

Lines changed: 4 additions & 4 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
@@ -33,18 +33,18 @@
3333
#define DEVICE_SPI 1
3434
#define DEVICE_SPISLAVE 0
3535

36-
#define DEVICE_RTC 0
36+
#define DEVICE_RTC 1
3737

3838
#define DEVICE_PWMOUT 1
3939

40+
#define DEVICE_SLEEP 1
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: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
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+
42+
// Warning:
43+
// On this device we don't know if a rising or falling event occured.
44+
// In case both rise and fall events are set, only the FALL event will be reported.
45+
if (EXTI->FTSR & (uint32_t)(1 << channel)) {
46+
irq_handler(channel_ids[channel], IRQ_FALL);
47+
}
48+
else {
49+
irq_handler(channel_ids[channel], IRQ_RISE);
50+
}
51+
}
52+
53+
static void gpio_irq0(void) {handle_interrupt_in(0);}
54+
static void gpio_irq1(void) {handle_interrupt_in(1);}
55+
static void gpio_irq2(void) {handle_interrupt_in(2);}
56+
static void gpio_irq3(void) {handle_interrupt_in(3);}
57+
static void gpio_irq4(void) {handle_interrupt_in(4);}
58+
static void gpio_irq5(void) {handle_interrupt_in(5);}
59+
static void gpio_irq6(void) {handle_interrupt_in(6);}
60+
static void gpio_irq7(void) {handle_interrupt_in(7);}
61+
static void gpio_irq8(void) {handle_interrupt_in(8);}
62+
static void gpio_irq9(void) {handle_interrupt_in(9);}
63+
static void gpio_irq10(void) {handle_interrupt_in(10);}
64+
static void gpio_irq11(void) {handle_interrupt_in(11);}
65+
static void gpio_irq12(void) {handle_interrupt_in(12);}
66+
static void gpio_irq13(void) {handle_interrupt_in(13);}
67+
static void gpio_irq14(void) {handle_interrupt_in(14);}
68+
static void gpio_irq15(void) {handle_interrupt_in(15);}
69+
70+
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
71+
IRQn_Type irq_n = (IRQn_Type)0;
72+
uint32_t vector = 0;
73+
74+
if (pin == NC) return -1;
75+
76+
uint32_t pin_number = (uint32_t)pin;
77+
uint32_t pin_index = (pin_number & 0xF);
78+
uint32_t port_index = (pin_number >> 4);
79+
80+
// Select irq number and vector
81+
switch (pin_index) {
82+
case 0:
83+
irq_n = EXTI0_IRQn;
84+
vector = (uint32_t)&gpio_irq0;
85+
break;
86+
case 1:
87+
irq_n = EXTI1_IRQn;
88+
vector = (uint32_t)&gpio_irq1;
89+
break;
90+
case 2:
91+
irq_n = EXTI2_IRQn;
92+
vector = (uint32_t)&gpio_irq2;
93+
break;
94+
case 3:
95+
irq_n = EXTI3_IRQn;
96+
vector = (uint32_t)&gpio_irq3;
97+
break;
98+
case 4:
99+
irq_n = EXTI4_IRQn;
100+
vector = (uint32_t)&gpio_irq4;
101+
break;
102+
case 5:
103+
irq_n = EXTI9_5_IRQn;
104+
vector = (uint32_t)&gpio_irq5;
105+
break;
106+
case 6:
107+
irq_n = EXTI9_5_IRQn;
108+
vector = (uint32_t)&gpio_irq6;
109+
break;
110+
case 7:
111+
irq_n = EXTI9_5_IRQn;
112+
vector = (uint32_t)&gpio_irq7;
113+
break;
114+
case 8:
115+
irq_n = EXTI9_5_IRQn;
116+
vector = (uint32_t)&gpio_irq8;
117+
break;
118+
case 9:
119+
irq_n = EXTI9_5_IRQn;
120+
vector = (uint32_t)&gpio_irq9;
121+
break;
122+
case 10:
123+
irq_n = EXTI15_10_IRQn;
124+
vector = (uint32_t)&gpio_irq10;
125+
break;
126+
case 11:
127+
irq_n = EXTI15_10_IRQn;
128+
vector = (uint32_t)&gpio_irq11;
129+
break;
130+
case 12:
131+
irq_n = EXTI15_10_IRQn;
132+
vector = (uint32_t)&gpio_irq12;
133+
break;
134+
case 13:
135+
irq_n = EXTI15_10_IRQn;
136+
vector = (uint32_t)&gpio_irq13;
137+
break;
138+
case 14:
139+
irq_n = EXTI15_10_IRQn;
140+
vector = (uint32_t)&gpio_irq14;
141+
break;
142+
case 15:
143+
irq_n = EXTI15_10_IRQn;
144+
vector = (uint32_t)&gpio_irq15;
145+
break;
146+
default:
147+
return -1;
148+
}
149+
150+
// Enable GPIO and AFIO clocks
151+
RCC_APB2PeriphClockCmd((uint32_t)(RCC_APB2Periph_GPIOA << port_index), ENABLE);
152+
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
153+
154+
// Connect EXTI line to pin
155+
GPIO_EXTILineConfig(port_index, pin_index);
156+
157+
// Configure EXTI line
158+
EXTI_InitTypeDef EXTI_InitStructure;
159+
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index);
160+
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
161+
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
162+
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
163+
EXTI_Init(&EXTI_InitStructure);
164+
165+
// Enable and set EXTI interrupt to the lowest priority
166+
NVIC_InitTypeDef NVIC_InitStructure;
167+
NVIC_InitStructure.NVIC_IRQChannel = irq_n;
168+
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
169+
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
170+
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
171+
NVIC_Init(&NVIC_InitStructure);
172+
173+
NVIC_SetVector(irq_n, vector);
174+
NVIC_EnableIRQ(irq_n);
175+
176+
// Save for future use
177+
obj->ch = pin_index;
178+
obj->irq_n = irq_n;
179+
obj->event = EDGE_NONE;
180+
181+
channel_ids[obj->ch] = id;
182+
183+
irq_handler = handler;
184+
185+
return 0;
186+
}
187+
188+
void gpio_irq_free(gpio_irq_t *obj) {
189+
channel_ids[obj->ch] = 0;
190+
// Disable EXTI line
191+
EXTI_InitTypeDef EXTI_InitStructure;
192+
EXTI_StructInit(&EXTI_InitStructure);
193+
EXTI_Init(&EXTI_InitStructure);
194+
obj->event = EDGE_NONE;
195+
}
196+
197+
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
198+
EXTI_InitTypeDef EXTI_InitStructure;
199+
200+
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << obj->ch);
201+
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
202+
203+
if (event == IRQ_RISE) {
204+
if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) {
205+
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
206+
obj->event = EDGE_BOTH;
207+
}
208+
else { // NONE or RISE
209+
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
210+
obj->event = EDGE_RISE;
211+
}
212+
}
213+
214+
if (event == IRQ_FALL) {
215+
if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) {
216+
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
217+
obj->event = EDGE_BOTH;
218+
}
219+
else { // NONE or FALL
220+
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
221+
obj->event = EDGE_FALL;
222+
}
223+
}
224+
225+
if (enable) {
226+
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
227+
}
228+
else {
229+
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
230+
}
231+
232+
EXTI_Init(&EXTI_InitStructure);
233+
}
234+
235+
void gpio_irq_enable(gpio_irq_t *obj) {
236+
NVIC_EnableIRQ(obj->irq_n);
237+
}
238+
239+
void gpio_irq_disable(gpio_irq_t *obj) {
240+
NVIC_DisableIRQ(obj->irq_n);
241+
obj->event = EDGE_NONE;
242+
}

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 {
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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 "rtc_api.h"
17+
18+
static int rtc_inited = 0;
19+
20+
void rtc_init(void) {
21+
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // Enable PWR and Backup clock
22+
23+
PWR_BackupAccessCmd(ENABLE); // Allow access to Backup Domain
24+
25+
BKP_DeInit(); // Reset Backup Domain
26+
27+
// Enable LSE and wait till it's ready
28+
RCC_LSEConfig(RCC_LSE_ON);
29+
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {}
30+
31+
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select LSE as RTC Clock Source
32+
33+
RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock
34+
35+
RTC_WaitForSynchro(); // Wait for RTC registers synchronization
36+
37+
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
38+
39+
// Set RTC period to 1 sec
40+
// RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)
41+
RTC_SetPrescaler(32767);
42+
43+
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
44+
45+
rtc_inited = 1;
46+
}
47+
48+
void rtc_free(void) {
49+
RCC_DeInit(); // Resets the RCC clock configuration to the default reset state
50+
rtc_inited = 0;
51+
}
52+
53+
int rtc_isenabled(void) {
54+
return rtc_inited;
55+
}
56+
57+
time_t rtc_read(void) {
58+
return (time_t)RTC_GetCounter();
59+
}
60+
61+
void rtc_write(time_t t) {
62+
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
63+
RTC_SetCounter(t); // Change the current time
64+
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
65+
}

0 commit comments

Comments
 (0)