gadget-flash-extractor/rtc.c
Daniele Lacamera 7bbae2db46 Initial import
2019-05-24 09:26:55 +02:00

102 lines
2.5 KiB
C

/*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
* this software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Daniele Lacamera
*
*
*/
#include <stdint.h>
#include "system.h"
#include <unicore-mx/stm32/gpio.h>
#include <unicore-mx/stm32/rcc.h>
#include <unicore-mx/cm3/nvic.h>
#define RTC_CR (*(volatile uint32_t *)(RTC_BASE + 0x08))
#define RTC_ISR (*(volatile uint32_t *)(RTC_BASE + 0x0c))
#define RTC_PRER (*(volatile uint32_t *)(RTC_BASE + 0x10))
#define RTC_WUTR (*(volatile uint32_t *)(RTC_BASE + 0x14))
#define RTC_WPR (*(volatile uint32_t *)(RTC_BASE + 0x24))
#define RTC_CR_WUP (0x03 << 21)
#define RTC_CR_WUTIE (1 << 14)
#define RTC_CR_WUTE (1 << 10)
#define RTC_ISR_WUTF (1 << 10)
#define RTC_ISR_WUTWF (1 << 2)
static void rtc_unlock(void)
{
RTC_WPR = 0xca;
RTC_WPR = 0x53;
}
static void rtc_lock(void)
{
RTC_WPR = 0xb0;
}
void rtc_start(void)
{
rtc_unlock();
RTC_CR |= RTC_CR_WUTIE |RTC_CR_WUTE;
while (((RTC_ISR) & (RTC_ISR_WUTWF)))
;
rtc_lock();
}
void rtc_init(void)
{
uint32_t reg;
/* Enable Power controller */
APB1_CLOCK_ER |= PWR_APB1_CLOCK_ER_VAL;
POW_CR |= POW_CR_DPB;
RCC_BACKUP |= RCC_BACKUP_RTCEN;
RCC_CSR |= RCC_CSR_LSION;
while (!(RCC_CSR & RCC_CSR_LSIRDY))
;
RCC_BACKUP |= (RCC_BACKUP_RTCSEL_LSI << RCC_BACKUP_RTCSEL_SHIFT);
EXTI_IMR |= (1 << 22);
EXTI_EMR |= (1 << 22);
EXTI_RTSR |= (1 << 22);
rtc_unlock();
RTC_CR &= ~RTC_CR_WUTE;
DMB();
while (!((RTC_ISR) & (RTC_ISR_WUTWF)))
;
RTC_CR |= 0x05;
reg = RTC_PRER & (~ (0x7F << 16));
RTC_PRER = reg | (127 << 16);
DMB();
reg = RTC_PRER & (~ (0x7FFF));
RTC_PRER = reg | 249;
RTC_WUTR = 3600 - 111;
RTC_CR |= RTC_CR_WUP;
RTC_ISR &= ~RTC_ISR_WUTF;
rtc_lock();
}
void isr_rtc(void)
{
rtc_unlock();
nvic_irq_clear(NVIC_RTC_IRQ);
nvic_irq_disable(NVIC_RTC_IRQ);
RTC_ISR &= ~RTC_ISR_WUTF;
RTC_CR &= ~(RTC_CR_WUTIE | RTC_CR_WUTE);
rtc_lock();
}