mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
stm32f1: implement RTT driver
This commit is contained in:
parent
09cb367ac2
commit
a16d326bf0
@ -286,5 +286,20 @@
|
||||
#define SPI_0_MISO_PORT_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPAEN)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Real time counter configuration
|
||||
* @{
|
||||
*/
|
||||
#define RTT_NUMOF (1U)
|
||||
#define RTT_IRQ_PRIO 1
|
||||
|
||||
#define RTT_DEV RTC
|
||||
#define RTT_IRQ RTC_IRQn
|
||||
#define RTT_ISR isr_rtc
|
||||
#define RTT_MAX_VALUE (0xffffffff)
|
||||
#define RTT_FREQUENCY (1) /* in Hz */
|
||||
#define RTT_PRESCALER (0x7fff) /* run with 1 Hz */
|
||||
/** @} */
|
||||
|
||||
#endif /* __PERIPH_CONF_H */
|
||||
/** @} */
|
||||
|
180
cpu/stm32f1/periph/rtt.c
Normal file
180
cpu/stm32f1/periph/rtt.c
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_stm32f1
|
||||
* @{
|
||||
*
|
||||
* @file rtt.c
|
||||
* @brief Low-level RTT driver implementation
|
||||
*
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "sched.h"
|
||||
#include "thread.h"
|
||||
#include "periph/rtt.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
/* guard file in case no RTT device was specified */
|
||||
#if RTT_NUMOF
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define RTT_FLAG_RTOFF ((uint16_t)0x0020) /**< RTC Operation OFF flag */
|
||||
#define RTT_FLAG_RSF ((uint16_t)0x0008) /**< Registers Synchronized flag */
|
||||
#define RTT_FLAG_OW ((uint16_t)0x0004) /**< Overflow flag */
|
||||
#define RTT_FLAG_ALR ((uint16_t)0x0002) /**< Alarm flag */
|
||||
#define RTT_FLAG_SEC ((uint16_t)0x0001) /**< Second flag */
|
||||
|
||||
inline void _rtt_enter_config_mode(void);
|
||||
inline void _rtt_leave_config_mode(void);
|
||||
|
||||
/*
|
||||
* callback and argument for an active alarm
|
||||
*/
|
||||
static rtt_alarm_cb_t alarm_cb;
|
||||
static void *alarm_arg;
|
||||
|
||||
void rtt_init(void)
|
||||
{
|
||||
rtt_poweron();
|
||||
|
||||
/* configure interrupt */
|
||||
NVIC_SetPriority(RTT_IRQ, RTT_IRQ_PRIO);
|
||||
NVIC_EnableIRQ(RTT_IRQ);
|
||||
|
||||
/* clear RSF flag */
|
||||
RTT_DEV->CRL &= ~(RTT_FLAG_RSF);
|
||||
|
||||
_rtt_enter_config_mode();
|
||||
|
||||
/* Reset RTC counter MSB word */
|
||||
RTT_DEV->CNTH = 0x0000;
|
||||
/* Set RTC counter LSB word */
|
||||
RTT_DEV->CNTL = 0x0000;
|
||||
/* set prescaler */
|
||||
RTT_DEV->PRLH = ((RTT_PRESCALER>>16)&0x000f);
|
||||
RTT_DEV->PRLL = (RTT_PRESCALER&0xffff);
|
||||
|
||||
_rtt_leave_config_mode();
|
||||
}
|
||||
|
||||
uint32_t rtt_get_counter(void)
|
||||
{
|
||||
/* wait for syncronization */
|
||||
while (!(RTT_DEV->CRL & RTT_FLAG_RSF));
|
||||
|
||||
return (((uint32_t)RTT_DEV->CNTH << 16 ) | (uint32_t)(RTT_DEV->CNTL));
|
||||
}
|
||||
|
||||
void rtt_set_counter(uint32_t counter)
|
||||
{
|
||||
_rtt_enter_config_mode();
|
||||
|
||||
/* Set RTC counter MSB word */
|
||||
RTT_DEV->CNTH = counter >> 16;
|
||||
/* Set RTC counter LSB word */
|
||||
RTT_DEV->CNTL = (counter & 0xffff);
|
||||
|
||||
_rtt_leave_config_mode();
|
||||
}
|
||||
|
||||
uint32_t rtt_get_alarm(void)
|
||||
{
|
||||
/* wait for syncronization */
|
||||
while (!(RTT_DEV->CRL & RTT_FLAG_RSF));
|
||||
|
||||
return (((uint32_t)RTT_DEV->ALRH << 16 ) | (uint32_t)(RTT_DEV->ALRL));
|
||||
}
|
||||
|
||||
void rtt_set_alarm(uint32_t alarm, rtt_alarm_cb_t cb, void *arg)
|
||||
{
|
||||
_rtt_enter_config_mode();
|
||||
|
||||
/* Set the alarm MSB word */
|
||||
RTT_DEV->ALRH = alarm >> 16;
|
||||
/* Set the alarm LSB word */
|
||||
RTT_DEV->ALRL = (alarm & 0xffff);
|
||||
|
||||
/* Enable alarm interrupt */
|
||||
RTT_DEV->CRH |= RTC_CRH_ALRIE;
|
||||
|
||||
_rtt_leave_config_mode();
|
||||
|
||||
alarm_cb = cb;
|
||||
alarm_arg = arg;
|
||||
}
|
||||
|
||||
void rtt_clear_alarm(void)
|
||||
{
|
||||
_rtt_enter_config_mode();
|
||||
|
||||
/* Disable alarm interrupt */
|
||||
RTT_DEV->CRH &= ~RTC_CRH_ALRIE;
|
||||
/* Set the ALARM MSB word to reset value */
|
||||
RTT_DEV->ALRH = 0xffff;
|
||||
/* Set the ALARM LSB word to reset value */
|
||||
RTT_DEV->ALRL = 0xffff;
|
||||
|
||||
_rtt_leave_config_mode();
|
||||
}
|
||||
|
||||
void rtt_poweron(void)
|
||||
{
|
||||
RCC->APB1ENR |= (RCC_APB1ENR_BKPEN|RCC_APB1ENR_PWREN); /* enable BKP and PWR, Clock */
|
||||
/* RTC clock source configuration */
|
||||
PWR->CR |= PWR_CR_DBP; /* Allow access to BKP Domain */
|
||||
RCC->BDCR |= RCC_BDCR_LSEON; /* Enable LSE OSC */
|
||||
while(!(RCC->BDCR & RCC_BDCR_LSERDY)); /* Wait till LSE is ready */
|
||||
RCC->BDCR |= RCC_BDCR_RTCSEL_LSE; /* Select the RTC Clock Source */
|
||||
RCC->BDCR |= RCC_BDCR_RTCEN; /* enable RTC */
|
||||
}
|
||||
|
||||
void rtt_poweroff(void)
|
||||
{
|
||||
PWR->CR |= PWR_CR_DBP; /* Allow access to BKP Domain */
|
||||
RCC->BDCR &= ~RCC_BDCR_RTCEN; /* disable RTC */
|
||||
RCC->APB1ENR &= ~(RCC_APB1ENR_BKPEN|RCC_APB1ENR_PWREN); /* disable BKP and PWR, Clock */
|
||||
}
|
||||
|
||||
inline void _rtt_enter_config_mode(void)
|
||||
{
|
||||
/* Loop until RTOFF flag is set */
|
||||
while (!(RTT_DEV->CRL & RTT_FLAG_RTOFF));
|
||||
/* enter configuration mode */
|
||||
RTT_DEV->CRL |= RTC_CRL_CNF;
|
||||
}
|
||||
|
||||
inline void _rtt_leave_config_mode(void)
|
||||
{
|
||||
/* leave configuration mode */
|
||||
RTT_DEV->CRL &= ~RTC_CRL_CNF;
|
||||
/* Loop until RTOFF flag is set */
|
||||
while (!(RTT_DEV->CRL & RTT_FLAG_RTOFF));
|
||||
}
|
||||
|
||||
__attribute__((naked)) void RTT_ISR(void)
|
||||
{
|
||||
ISR_ENTER();
|
||||
|
||||
if (RTT_DEV->CRL & RTC_CRL_ALRF) {
|
||||
RTT_DEV->CRL &= ~(RTC_CRL_ALRF);
|
||||
alarm_cb(alarm_arg);
|
||||
}
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
ISR_EXIT();
|
||||
}
|
||||
|
||||
#endif /* RTT_NUMOF */
|
Loading…
Reference in New Issue
Block a user