mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #129 from bcostm/master
[NUCLEO_F103RB] InterruptIn, Sleep, RTC addedpull/131/head^2
commit
572b22395f
|
@ -20,7 +20,7 @@
|
|||
#define DEVICE_PORTOUT 1
|
||||
#define DEVICE_PORTINOUT 1
|
||||
|
||||
#define DEVICE_INTERRUPTIN 0
|
||||
#define DEVICE_INTERRUPTIN 1
|
||||
|
||||
#define DEVICE_ANALOGIN 1
|
||||
#define DEVICE_ANALOGOUT 0
|
||||
|
@ -33,18 +33,18 @@
|
|||
#define DEVICE_SPI 1
|
||||
#define DEVICE_SPISLAVE 0
|
||||
|
||||
#define DEVICE_RTC 0
|
||||
#define DEVICE_RTC 1
|
||||
|
||||
#define DEVICE_PWMOUT 1
|
||||
|
||||
#define DEVICE_SLEEP 1
|
||||
|
||||
//=======================================
|
||||
|
||||
#define DEVICE_SEMIHOST 0
|
||||
#define DEVICE_LOCALFILESYSTEM 0
|
||||
#define DEVICE_ID_LENGTH 24
|
||||
|
||||
#define DEVICE_SLEEP 0
|
||||
|
||||
#define DEVICE_DEBUG_AWARENESS 0
|
||||
|
||||
#define DEVICE_STDIO_MESSAGES 1
|
||||
|
|
|
@ -0,0 +1,242 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file 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 OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "cmsis.h"
|
||||
|
||||
#include "gpio_irq_api.h"
|
||||
#include "error.h"
|
||||
|
||||
#define EDGE_NONE (0)
|
||||
#define EDGE_RISE (1)
|
||||
#define EDGE_FALL (2)
|
||||
#define EDGE_BOTH (3)
|
||||
|
||||
#define CHANNEL_NUM (16)
|
||||
|
||||
static uint32_t channel_ids[CHANNEL_NUM] = {0};
|
||||
|
||||
static gpio_irq_handler irq_handler;
|
||||
|
||||
static void handle_interrupt_in(uint32_t channel) {
|
||||
if (channel_ids[channel] == 0) return;
|
||||
|
||||
uint32_t exti_line = (uint32_t)(1 << channel);
|
||||
if (EXTI_GetITStatus(exti_line) != RESET)
|
||||
{
|
||||
EXTI_ClearITPendingBit(exti_line);
|
||||
}
|
||||
|
||||
// Warning:
|
||||
// On this device we don't know if a rising or falling event occured.
|
||||
// In case both rise and fall events are set, only the FALL event will be reported.
|
||||
if (EXTI->FTSR & (uint32_t)(1 << channel)) {
|
||||
irq_handler(channel_ids[channel], IRQ_FALL);
|
||||
}
|
||||
else {
|
||||
irq_handler(channel_ids[channel], IRQ_RISE);
|
||||
}
|
||||
}
|
||||
|
||||
static void gpio_irq0(void) {handle_interrupt_in(0);}
|
||||
static void gpio_irq1(void) {handle_interrupt_in(1);}
|
||||
static void gpio_irq2(void) {handle_interrupt_in(2);}
|
||||
static void gpio_irq3(void) {handle_interrupt_in(3);}
|
||||
static void gpio_irq4(void) {handle_interrupt_in(4);}
|
||||
static void gpio_irq5(void) {handle_interrupt_in(5);}
|
||||
static void gpio_irq6(void) {handle_interrupt_in(6);}
|
||||
static void gpio_irq7(void) {handle_interrupt_in(7);}
|
||||
static void gpio_irq8(void) {handle_interrupt_in(8);}
|
||||
static void gpio_irq9(void) {handle_interrupt_in(9);}
|
||||
static void gpio_irq10(void) {handle_interrupt_in(10);}
|
||||
static void gpio_irq11(void) {handle_interrupt_in(11);}
|
||||
static void gpio_irq12(void) {handle_interrupt_in(12);}
|
||||
static void gpio_irq13(void) {handle_interrupt_in(13);}
|
||||
static void gpio_irq14(void) {handle_interrupt_in(14);}
|
||||
static void gpio_irq15(void) {handle_interrupt_in(15);}
|
||||
|
||||
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
|
||||
IRQn_Type irq_n = (IRQn_Type)0;
|
||||
uint32_t vector = 0;
|
||||
|
||||
if (pin == NC) return -1;
|
||||
|
||||
uint32_t pin_number = (uint32_t)pin;
|
||||
uint32_t pin_index = (pin_number & 0xF);
|
||||
uint32_t port_index = (pin_number >> 4);
|
||||
|
||||
// Select irq number and vector
|
||||
switch (pin_index) {
|
||||
case 0:
|
||||
irq_n = EXTI0_IRQn;
|
||||
vector = (uint32_t)&gpio_irq0;
|
||||
break;
|
||||
case 1:
|
||||
irq_n = EXTI1_IRQn;
|
||||
vector = (uint32_t)&gpio_irq1;
|
||||
break;
|
||||
case 2:
|
||||
irq_n = EXTI2_IRQn;
|
||||
vector = (uint32_t)&gpio_irq2;
|
||||
break;
|
||||
case 3:
|
||||
irq_n = EXTI3_IRQn;
|
||||
vector = (uint32_t)&gpio_irq3;
|
||||
break;
|
||||
case 4:
|
||||
irq_n = EXTI4_IRQn;
|
||||
vector = (uint32_t)&gpio_irq4;
|
||||
break;
|
||||
case 5:
|
||||
irq_n = EXTI9_5_IRQn;
|
||||
vector = (uint32_t)&gpio_irq5;
|
||||
break;
|
||||
case 6:
|
||||
irq_n = EXTI9_5_IRQn;
|
||||
vector = (uint32_t)&gpio_irq6;
|
||||
break;
|
||||
case 7:
|
||||
irq_n = EXTI9_5_IRQn;
|
||||
vector = (uint32_t)&gpio_irq7;
|
||||
break;
|
||||
case 8:
|
||||
irq_n = EXTI9_5_IRQn;
|
||||
vector = (uint32_t)&gpio_irq8;
|
||||
break;
|
||||
case 9:
|
||||
irq_n = EXTI9_5_IRQn;
|
||||
vector = (uint32_t)&gpio_irq9;
|
||||
break;
|
||||
case 10:
|
||||
irq_n = EXTI15_10_IRQn;
|
||||
vector = (uint32_t)&gpio_irq10;
|
||||
break;
|
||||
case 11:
|
||||
irq_n = EXTI15_10_IRQn;
|
||||
vector = (uint32_t)&gpio_irq11;
|
||||
break;
|
||||
case 12:
|
||||
irq_n = EXTI15_10_IRQn;
|
||||
vector = (uint32_t)&gpio_irq12;
|
||||
break;
|
||||
case 13:
|
||||
irq_n = EXTI15_10_IRQn;
|
||||
vector = (uint32_t)&gpio_irq13;
|
||||
break;
|
||||
case 14:
|
||||
irq_n = EXTI15_10_IRQn;
|
||||
vector = (uint32_t)&gpio_irq14;
|
||||
break;
|
||||
case 15:
|
||||
irq_n = EXTI15_10_IRQn;
|
||||
vector = (uint32_t)&gpio_irq15;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Enable GPIO and AFIO clocks
|
||||
RCC_APB2PeriphClockCmd((uint32_t)(RCC_APB2Periph_GPIOA << port_index), ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
||||
|
||||
// Connect EXTI line to pin
|
||||
GPIO_EXTILineConfig(port_index, pin_index);
|
||||
|
||||
// Configure EXTI line
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index);
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
|
||||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
|
||||
// Enable and set EXTI interrupt to the lowest priority
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
NVIC_InitStructure.NVIC_IRQChannel = irq_n;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
NVIC_SetVector(irq_n, vector);
|
||||
NVIC_EnableIRQ(irq_n);
|
||||
|
||||
// Save for future use
|
||||
obj->ch = pin_index;
|
||||
obj->irq_n = irq_n;
|
||||
obj->event = EDGE_NONE;
|
||||
|
||||
channel_ids[obj->ch] = id;
|
||||
|
||||
irq_handler = handler;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_irq_free(gpio_irq_t *obj) {
|
||||
channel_ids[obj->ch] = 0;
|
||||
// Disable EXTI line
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
EXTI_StructInit(&EXTI_InitStructure);
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
obj->event = EDGE_NONE;
|
||||
}
|
||||
|
||||
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
|
||||
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << obj->ch);
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
|
||||
if (event == IRQ_RISE) {
|
||||
if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) {
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
|
||||
obj->event = EDGE_BOTH;
|
||||
}
|
||||
else { // NONE or RISE
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
|
||||
obj->event = EDGE_RISE;
|
||||
}
|
||||
}
|
||||
|
||||
if (event == IRQ_FALL) {
|
||||
if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) {
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
|
||||
obj->event = EDGE_BOTH;
|
||||
}
|
||||
else { // NONE or FALL
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
|
||||
obj->event = EDGE_FALL;
|
||||
}
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||||
}
|
||||
else {
|
||||
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
|
||||
}
|
||||
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
}
|
||||
|
||||
void gpio_irq_enable(gpio_irq_t *obj) {
|
||||
NVIC_EnableIRQ(obj->irq_n);
|
||||
}
|
||||
|
||||
void gpio_irq_disable(gpio_irq_t *obj) {
|
||||
NVIC_DisableIRQ(obj->irq_n);
|
||||
obj->event = EDGE_NONE;
|
||||
}
|
|
@ -26,9 +26,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct gpio_irq_s {
|
||||
uint32_t port;
|
||||
uint32_t pin;
|
||||
uint32_t ch;
|
||||
IRQn_Type irq_n;
|
||||
uint32_t event; // 0=none, 1=rise, 2=fall, 3=rise+fall
|
||||
};
|
||||
|
||||
struct port_s {
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file 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 OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "rtc_api.h"
|
||||
|
||||
static int rtc_inited = 0;
|
||||
|
||||
void rtc_init(void) {
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // Enable PWR and Backup clock
|
||||
|
||||
PWR_BackupAccessCmd(ENABLE); // Allow access to Backup Domain
|
||||
|
||||
BKP_DeInit(); // Reset Backup Domain
|
||||
|
||||
// Enable LSE and wait till it's ready
|
||||
RCC_LSEConfig(RCC_LSE_ON);
|
||||
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {}
|
||||
|
||||
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select LSE as RTC Clock Source
|
||||
|
||||
RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock
|
||||
|
||||
RTC_WaitForSynchro(); // Wait for RTC registers synchronization
|
||||
|
||||
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
|
||||
|
||||
// Set RTC period to 1 sec
|
||||
// RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)
|
||||
RTC_SetPrescaler(32767);
|
||||
|
||||
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
|
||||
|
||||
rtc_inited = 1;
|
||||
}
|
||||
|
||||
void rtc_free(void) {
|
||||
RCC_DeInit(); // Resets the RCC clock configuration to the default reset state
|
||||
rtc_inited = 0;
|
||||
}
|
||||
|
||||
int rtc_isenabled(void) {
|
||||
return rtc_inited;
|
||||
}
|
||||
|
||||
time_t rtc_read(void) {
|
||||
return (time_t)RTC_GetCounter();
|
||||
}
|
||||
|
||||
void rtc_write(time_t t) {
|
||||
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
|
||||
RTC_SetCounter(t); // Change the current time
|
||||
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file 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 OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "sleep_api.h"
|
||||
#include "cmsis.h"
|
||||
|
||||
static void SYSCLKConfig_STOP(void)
|
||||
{
|
||||
ErrorStatus HSEStartUpStatus;
|
||||
|
||||
RCC_HSEConfig(RCC_HSE_ON); // Enable HSE
|
||||
|
||||
HSEStartUpStatus = RCC_WaitForHSEStartUp(); // Wait till HSE is ready
|
||||
|
||||
if (HSEStartUpStatus == SUCCESS) {
|
||||
RCC_PLLCmd(ENABLE); // Enable PLL
|
||||
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {} // Wait till PLL is ready
|
||||
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock source
|
||||
while(RCC_GetSYSCLKSource() != 0x08) {} // Wait till PLL is used as system clock source
|
||||
}
|
||||
}
|
||||
|
||||
void sleep(void)
|
||||
{
|
||||
SCB->SCR = 0; // Normal sleep mode for ARM core
|
||||
__WFI();
|
||||
}
|
||||
|
||||
void deepsleep(void)
|
||||
{
|
||||
// Enable PWR clock
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
|
||||
|
||||
// Request to enter STOP mode with regulator in low power mode
|
||||
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
|
||||
|
||||
// At this stage the system has resumed from STOP mode.
|
||||
// Re-configure the system clock: enable HSE, PLL and select
|
||||
// PLL as system clock source (because HSE and PLL are disabled in STOP mode).
|
||||
SYSCLKConfig_STOP();
|
||||
}
|
Loading…
Reference in New Issue