Source code for the Trusted Boot Module.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
tbm-mcu/source/platform/stm32f0/alarm.c

143 lines
2.5 KiB

#include <libopencm3/cm3/nvic.h>
#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;
sec = (rtc & 0xf) + ((rtc >> 4) & 0xf) * 10;
sec += (((rtc >> 8) & 0xf) + ((rtc >> 12) & 0xf) * 10) * 60;
sec += (((rtc >> 16) & 0xf) + ((rtc >> 20) & 0xf) * 10) * 3600;
return sec;
}
static inline uint32_t sec_to_rtc(uint32_t sec)
{
uint32_t rtc;
uint8_t hour;
uint8_t min;
sec %= SECS_PER_DAY;
hour = sec / 3600;
rtc = u8_to_bcd(hour) << 16;
sec -= hour * 3600;
min = sec / 60;
rtc |= u8_to_bcd(min) << 8;
sec -= min * 60;
rtc |= u8_to_bcd(sec);
return rtc;
}
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;
gpio_toggle(GPIOC, GPIO8);
pwr_disable_backup_domain_write_protect();
rtc_unlock();
/* Disable the alarm. */
RTC_CR &= ~RTC_CR_ALRAE;
RTC_ISR &= ~RTC_ISR_ALRAF;
exti_reset_request(EXTI17);
if (!reset) {
reset = 1;
gpio_set(GPIOA, GPIO1);
/* 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_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);
(volatile void)RTC_DR;
RTC_ALRMAR = sec_to_rtc(alarm_sec + timeout) | 0xc0000000;
RTC_CR |= RTC_CR_ALRAE;
rtc_enable_alarm_interrupt();
rtc_lock();
pwr_enable_backup_domain_write_protect();
return 0;
}
int alarm_disable(void)
{
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;
}