stm32f0: stm32f1: alarm: implement functionality to enable and disable the alarm with a time-out for resetting the host
This commit is contained in:
parent
40ba5323f3
commit
0542810d22
3 changed files with 134 additions and 35 deletions
|
@ -2,6 +2,11 @@
|
|||
|
||||
#include <time.h>
|
||||
|
||||
#define SECS_PER_DAY (24 * 60 * 60)
|
||||
|
||||
int rtc_init(struct tm *time);
|
||||
int rtc_get_time(struct tm *time);
|
||||
time_t rtc_time(void);
|
||||
|
||||
int alarm_enable(uint32_t timeout);
|
||||
int alarm_disable(void);
|
||||
|
|
|
@ -2,6 +2,22 @@
|
|||
#include <libopencm3/stm32/exti.h>
|
||||
#include <libopencm3/stm32/rtc.h>
|
||||
|
||||
#include <libopencm3/stm32/rcc.h>
|
||||
#include <libopencm3/stm32/gpio.h>
|
||||
#include <libopencm3/stm32/pwr.h>
|
||||
|
||||
#include <rtc.h>
|
||||
|
||||
static int reset = 0;
|
||||
|
||||
static uint8_t u8_to_bcd(uint8_t val)
|
||||
{
|
||||
uint32_t quot = (uint32_t)val / 10;
|
||||
uint32_t rem = val - quot * 10;
|
||||
|
||||
return (quot << 4) | rem;
|
||||
}
|
||||
|
||||
static inline uint32_t rtc_to_sec(uint32_t rtc)
|
||||
{
|
||||
uint32_t sec;
|
||||
|
@ -16,63 +32,114 @@ static inline uint32_t rtc_to_sec(uint32_t rtc)
|
|||
static inline uint32_t sec_to_rtc(uint32_t sec)
|
||||
{
|
||||
uint32_t rtc;
|
||||
uint32_t hour, min;
|
||||
uint8_t hour;
|
||||
uint8_t min;
|
||||
|
||||
sec %= SECS_PER_DAY;
|
||||
|
||||
hour = sec / 3600;
|
||||
min = (sec % 3600) / 60;
|
||||
sec = sec % 60;
|
||||
rtc = u8_to_bcd(hour) << 16;
|
||||
|
||||
rtc = ((hour / 10) << 20) | ((hour % 10) << 16);
|
||||
rtc |= ((min / 10) << 12) | ((min % 10) << 8);
|
||||
rtc |= ((sec / 10) << 4) | (sec % 10);
|
||||
sec -= hour * 3600;
|
||||
min = sec / 60;
|
||||
rtc |= u8_to_bcd(min) << 8;
|
||||
|
||||
sec -= min * 60;
|
||||
rtc |= u8_to_bcd(sec);
|
||||
|
||||
return rtc;
|
||||
}
|
||||
|
||||
void rtc_alarm_isr(void)
|
||||
static void rtc_enable_alarm_interrupt(void)
|
||||
{
|
||||
exti_enable_request(EXTI17);
|
||||
exti_set_trigger(EXTI17, EXTI_TRIGGER_RISING);
|
||||
|
||||
nvic_enable_irq(NVIC_RTC_IRQ);
|
||||
nvic_set_priority(NVIC_RTC_IRQ, 1);
|
||||
|
||||
RTC_CR |= RTC_CR_ALRAIE;
|
||||
}
|
||||
|
||||
static void rtc_disable_alarm_interrupt(void)
|
||||
{
|
||||
exti_disable_request(EXTI17);
|
||||
|
||||
nvic_disable_irq(NVIC_RTC_IRQ);
|
||||
|
||||
RTC_CR &= ~RTC_CR_ALRAIE;
|
||||
}
|
||||
|
||||
void rtc_isr(void)
|
||||
{
|
||||
uint32_t alarm_sec;
|
||||
|
||||
exti_reset_request(EXTI17);
|
||||
gpio_toggle(GPIOC, GPIO8);
|
||||
|
||||
pwr_disable_backup_domain_write_protect();
|
||||
rtc_unlock();
|
||||
|
||||
/* Disable the alarm. */
|
||||
RTC_CR &= ~RTC_CR_ALRAE;
|
||||
while (!(RTC_ISR & RTC_ISR_ALRAWF));
|
||||
RTC_ISR &= ~RTC_ISR_ALRAF;
|
||||
exti_reset_request(EXTI17);
|
||||
|
||||
/* Set the alarm time. */
|
||||
alarm_sec = rtc_to_sec(RTC_TR) + 10;
|
||||
RTC_ALRMAR = sec_to_rtc(alarm_sec);
|
||||
RTC_ALRMAR |= 0xc0000000;
|
||||
if (!reset) {
|
||||
reset = 1;
|
||||
gpio_set(GPIOA, GPIO1);
|
||||
|
||||
/* Enable the alarm. */
|
||||
EXTI_IMR |= EXTI17;
|
||||
exti_set_trigger(EXTI17, EXTI_TRIGGER_RISING);
|
||||
RTC_CR |= RTC_CR_ALRAE;
|
||||
/* Set the alarm time. */
|
||||
alarm_sec = rtc_to_sec(RTC_TR);
|
||||
(volatile void)RTC_DR;
|
||||
RTC_ALRMAR = sec_to_rtc(alarm_sec + 5) | 0xc0000000;
|
||||
|
||||
/* Enable the alarm. */
|
||||
RTC_CR |= RTC_CR_ALRAE;
|
||||
} else {
|
||||
reset = 0;
|
||||
gpio_clear(GPIOA, GPIO1);
|
||||
alarm_disable();
|
||||
}
|
||||
|
||||
rtc_lock();
|
||||
pwr_enable_backup_domain_write_protect();
|
||||
}
|
||||
|
||||
int alarm_init(void)
|
||||
int alarm_enable(uint32_t timeout)
|
||||
{
|
||||
uint32_t alarm_sec;
|
||||
|
||||
pwr_disable_backup_domain_write_protect();
|
||||
rtc_unlock();
|
||||
|
||||
/* Set the alarm time. */
|
||||
alarm_sec = rtc_to_sec(RTC_TR) + 10;
|
||||
RTC_ALRMAR = sec_to_rtc(alarm_sec);
|
||||
RTC_ALRMAR |= 0xc0000000;
|
||||
alarm_sec = rtc_to_sec(RTC_TR);
|
||||
(volatile void)RTC_DR;
|
||||
RTC_ALRMAR = sec_to_rtc(alarm_sec + timeout) | 0xc0000000;
|
||||
|
||||
RTC_CR |= RTC_CR_ALRAIE | RTC_CR_BYPSHAD;
|
||||
|
||||
nvic_enable_irq(NVIC_RTC_IRQ);
|
||||
EXTI_IMR |= EXTI17;
|
||||
exti_set_trigger(EXTI17, EXTI_TRIGGER_RISING);
|
||||
RTC_CR |= RTC_CR_ALRAE;
|
||||
rtc_enable_alarm_interrupt();
|
||||
|
||||
rtc_lock();
|
||||
pwr_enable_backup_domain_write_protect();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alarm_disable(void)
|
||||
{
|
||||
uint32_t alarm_sec;
|
||||
|
||||
gpio_set(GPIOC, GPIO8);
|
||||
|
||||
pwr_disable_backup_domain_write_protect();
|
||||
rtc_unlock();
|
||||
|
||||
RTC_CR &= ~RTC_CR_ALRAE;
|
||||
rtc_disable_alarm_interrupt();
|
||||
|
||||
rtc_lock();
|
||||
pwr_enable_backup_domain_write_protect();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,29 +1,56 @@
|
|||
#include <libopencm3/cm3/nvic.h>
|
||||
#include <libopencm3/stm32/exti.h>
|
||||
#include <libopencm3/stm32/gpio.h>
|
||||
#include <libopencm3/stm32/rtc.h>
|
||||
|
||||
#include <rtc.h>
|
||||
|
||||
static int reset = 0;
|
||||
|
||||
void rtc_alarm_isr(void)
|
||||
{
|
||||
exti_reset_request(EXTI17);
|
||||
|
||||
if (rtc_check_flag(RTC_ALR)) {
|
||||
rtc_clear_flag(RTC_ALR);
|
||||
|
||||
rtc_set_alarm_time(rtc_get_counter_val() + 10);
|
||||
rtc_disable_alarm();
|
||||
exti_reset_request(EXTI17);
|
||||
|
||||
EXTI_IMR |= EXTI17;
|
||||
exti_set_trigger(EXTI17, EXTI_TRIGGER_RISING);
|
||||
if (!reset) {
|
||||
reset = 1;
|
||||
gpio_set(GPIOA, GPIO1);
|
||||
|
||||
rtc_set_alarm_time(rtc_get_counter_val() + 5);
|
||||
rtc_enable_alarm();
|
||||
} else {
|
||||
reset = 0;
|
||||
gpio_set(GPIOA, GPIO1);
|
||||
alarm_disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int alarm_init(void)
|
||||
int alarm_enable(uint32_t timeout)
|
||||
{
|
||||
rtc_enable_alarm();
|
||||
rtc_set_alarm_time(rtc_get_counter_val() + 10);
|
||||
rtc_set_alarm_time(rtc_get_counter_val() + timeout);
|
||||
|
||||
exti_enable_request(EXTI17);
|
||||
exti_set_trigger(EXTI17, EXTI_TRIGGER_RISING);
|
||||
|
||||
nvic_enable_irq(NVIC_RTC_ALARM_IRQ);
|
||||
EXTI_IMR |= EXTI17;
|
||||
exti_set_trigger(EXTI17, EXTI_TRIGGER_RISING);
|
||||
nvic_set_priority(NVIC_RTC_ALARM_IRQ, 1);
|
||||
|
||||
rtc_interrupt_enable(RTC_ALR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alarm_disable(void)
|
||||
{
|
||||
exti_disable_request(EXTI17);
|
||||
nvic_disable_irq(NVIC_RTC_ALARM_IRQ);
|
||||
rtc_interrupt_disable(RTC_ALR);
|
||||
rtc_disable_alarm();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue