git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3783 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
a40e2315db
commit
8824a54e5e
|
@ -87,7 +87,7 @@ static void rtc_lld_serve_interrupt(RTCDriver *rtcp) {
|
|||
static void rtc_lld_wait_write(void) {
|
||||
|
||||
/* Waits registers write completion.*/
|
||||
while (!(RTC->CRL & RTC_CRL_RTOFF))
|
||||
while ((RTC->CRL & RTC_CRL_RTOFF) == 0)
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -122,50 +122,6 @@ CH_IRQ_HANDLER(RTC_IRQHandler) {
|
|||
* @notapi
|
||||
*/
|
||||
void rtc_lld_init(void){
|
||||
uint32_t preload;
|
||||
|
||||
rccEnableBKPInterface(FALSE);
|
||||
|
||||
/* Enables access to BKP registers.*/
|
||||
PWR->CR |= PWR_CR_DBP;
|
||||
|
||||
/* If the RTC is not enabled then performs a reset of the backup domain.*/
|
||||
if (!(RCC->BDCR & RCC_BDCR_RTCEN)) {
|
||||
RCC->BDCR = RCC_BDCR_BDRST;
|
||||
RCC->BDCR = 0;
|
||||
}
|
||||
|
||||
#if STM32_RTC == STM32_RTC_LSE
|
||||
#define RTC_CLK STM32_LSECLK
|
||||
if (!(RCC->BDCR & RCC_BDCR_LSEON)) {
|
||||
RCC->BDCR |= RCC_BDCR_LSEON;
|
||||
while (!(RCC->BDCR & RCC_BDCR_LSERDY))
|
||||
;
|
||||
}
|
||||
preload = STM32_LSECLK - 1;
|
||||
#elif STM32_RTC == STM32_RTC_LSI
|
||||
#define RTC_CLK STM32_LSICLK
|
||||
/* TODO: Move the LSI clock initialization in the HAL low level driver.*/
|
||||
RCC->CSR |= RCC_CSR_LSION;
|
||||
while (!(RCC->CSR & RCC_CSR_LSIRDY))
|
||||
;
|
||||
/* According to errata sheet we must wait additional 100 uS for
|
||||
stabilization.
|
||||
TODO: Change this code, software loops are not reliable.*/
|
||||
volatile uint32_t tmo = (STM32_SYSCLK / 1000000) * 100;
|
||||
while (tmo--)
|
||||
;
|
||||
preload = STM32_LSICLK - 1;
|
||||
#elif STM32_RTC == STM32_RTC_HSE
|
||||
#define RTC_CLK (STM32_HSECLK / 128)
|
||||
preload = (STM32_HSECLK / 128) - 1;
|
||||
#endif
|
||||
|
||||
/* Selects clock source (previously enabled and stabilized).*/
|
||||
RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTC;
|
||||
|
||||
/* RTC enabled regardless its previous status.*/
|
||||
RCC->BDCR |= RCC_BDCR_RTCEN;
|
||||
|
||||
/* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling
|
||||
clocking on APB1, because these values only update when APB1
|
||||
|
@ -175,15 +131,15 @@ void rtc_lld_init(void){
|
|||
;
|
||||
|
||||
/* Write preload register only if its value differs.*/
|
||||
if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + (uint32_t)RTC->PRLL)) {
|
||||
|
||||
rtc_lld_wait_write();
|
||||
if (STM32_RTCCLK != (((uint32_t)(RTC->PRLH)) << 16) +
|
||||
((uint32_t)RTC->PRLL) + 1) {
|
||||
|
||||
/* Enters configuration mode and writes PRLx registers then leaves the
|
||||
configuration mode.*/
|
||||
rtc_lld_wait_write();
|
||||
RTC->CRL |= RTC_CRL_CNF;
|
||||
RTC->PRLH = (uint16_t)(preload >> 16);
|
||||
RTC->PRLL = (uint16_t)(preload & 0xFFFF);
|
||||
RTC->PRLH = (uint16_t)((STM32_RTCCLK - 1) >> 16);
|
||||
RTC->PRLL = (uint16_t)((STM32_RTCCLK - 1) & 0xFFFF);
|
||||
RTC->CRL &= ~RTC_CRL_CNF;
|
||||
}
|
||||
|
||||
|
@ -209,7 +165,6 @@ void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec) {
|
|||
(void)rtcp;
|
||||
|
||||
rtc_lld_wait_write();
|
||||
|
||||
RTC->CRL |= RTC_CRL_CNF;
|
||||
RTC->CNTH = (uint16_t)(timespec->tv_sec >> 16);
|
||||
RTC->CNTL = (uint16_t)(timespec->tv_sec & 0xFFFF);
|
||||
|
@ -229,17 +184,15 @@ void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec) {
|
|||
|
||||
uint32_t time_frac;
|
||||
|
||||
READ_REGISTERS:
|
||||
/* The read is repeated until we are able to do it twice and obtain the
|
||||
same result.*/
|
||||
do {
|
||||
timespec->tv_sec = ((uint32_t)(RTC->CNTH) << 16) + RTC->CNTL;
|
||||
time_frac = (((uint32_t)RTC->DIVH) << 16) + (uint32_t)RTC->DIVL;
|
||||
} while ((timespec->tv_sec) != (((uint32_t)(RTC->CNTH) << 16) + RTC->CNTL));
|
||||
|
||||
/* If second counter updated between reading of integer and fractional parts
|
||||
* we must reread both values. */
|
||||
if((timespec->tv_sec) != (((uint32_t)(RTC->CNTH) << 16) + RTC->CNTL)){
|
||||
goto READ_REGISTERS;
|
||||
}
|
||||
|
||||
timespec->tv_msec = (uint16_t)(((RTC_CLK - 1 - time_frac) * 1000) / RTC_CLK);
|
||||
timespec->tv_msec = (uint16_t)(((STM32_RTCCLK - 1 - time_frac) * 1000) /
|
||||
STM32_RTCCLK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -260,10 +213,10 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
|
|||
(void)rtcp;
|
||||
(void)alarm;
|
||||
|
||||
rtc_lld_wait_write();
|
||||
|
||||
/* Enters configuration mode and writes ALRHx registers then leaves the
|
||||
configuration mode.*/
|
||||
rtc_lld_wait_write();
|
||||
RTC->CRL |= RTC_CRL_CNF;
|
||||
if (alarmspec != NULL) {
|
||||
RTC->ALRH = (uint16_t)(alarmspec->tv_sec >> 16);
|
||||
|
@ -317,15 +270,12 @@ void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) {
|
|||
/* Interrupts are enabled only after setting up the callback, this
|
||||
way there is no need to check for the NULL callback pointer inside
|
||||
the IRQ handler.*/
|
||||
rtc_lld_wait_write();
|
||||
RTC->CRL &= ~(RTC_CRL_OWF | RTC_CRL_ALRF | RTC_CRL_SECF);
|
||||
rtc_lld_wait_write();
|
||||
nvicEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY));
|
||||
RTC->CRH |= RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE;
|
||||
}
|
||||
else {
|
||||
nvicDisableVector(RTC_IRQn);
|
||||
rtc_lld_wait_write();
|
||||
RTC->CRL = 0;
|
||||
RTC->CRH = 0;
|
||||
}
|
||||
|
|
|
@ -61,9 +61,8 @@
|
|||
#error "RTC not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !(STM32_RTC == STM32_RTC_LSE) && !(STM32_RTC == STM32_RTC_LSI) && \
|
||||
!(STM32_RTC == STM32_RTC_HSE)
|
||||
#error "invalid source selected for RTC clock"
|
||||
#if STM32_RTCCLK == 0
|
||||
#error "RTC clock not enabled"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -41,6 +41,47 @@
|
|||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the backup domain.
|
||||
*/
|
||||
static void hal_lld_backup_domain_init(void) {
|
||||
|
||||
/* Backup domain access enabled during initialization.*/
|
||||
PWR->CR |= PWR_CR_DBP;
|
||||
|
||||
/* RTC clock initialization.*/
|
||||
#if STM32_RTCSEL == STM32_RTCSEL_NOCLOCK
|
||||
/* RTC clock not required, backup domain reset as initialization.*/
|
||||
RCC->BDCR = RCC_BDCR_BDRST;
|
||||
RCC->BDCR = 0;
|
||||
#else /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
|
||||
/* If the backup domain hasn't been initialized yet then proceed with
|
||||
initialization.*/
|
||||
if (!(RCC->BDCR & RCC_BDCR_LSEON)) {
|
||||
/* Backup domain reset.*/
|
||||
RCC->BDCR = RCC_BDCR_BDRST;
|
||||
RCC->BDCR = 0;
|
||||
|
||||
/* If enabled then the LSE is started.*/
|
||||
#if STM32_LSE_ENABLED
|
||||
RCC->BDCR |= RCC_BDCR_LSEON;
|
||||
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
|
||||
; /* Waits until LSE is stable. */
|
||||
#endif
|
||||
|
||||
/* Selects clock source.*/
|
||||
RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTCSEL;
|
||||
|
||||
/* RTC enabled regardless its previous status, this will also prevent
|
||||
successive initializations.*/
|
||||
RCC->BDCR |= RCC_BDCR_RTCEN;
|
||||
}
|
||||
#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
|
||||
|
||||
/* Backup domain access disabled for operations safety.*/
|
||||
PWR->CR &= ~PWR_CR_DBP;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
@ -70,13 +111,19 @@ void hal_lld_init(void) {
|
|||
/* DWT cycle counter enable.*/
|
||||
DWT_CTRL |= DWT_CTRL_CYCCNTENA;
|
||||
|
||||
/* PWR and BD clocks enabled.*/
|
||||
rccEnablePWRInterface(FALSE);
|
||||
rccEnableBKPInterface(FALSE);
|
||||
|
||||
/* Initializes the backup domain.*/
|
||||
hal_lld_backup_domain_init();
|
||||
|
||||
#if defined(STM32_DMA_REQUIRED)
|
||||
dmaInit();
|
||||
#endif
|
||||
|
||||
/* Programmable voltage detector enable.*/
|
||||
#if STM32_PVD_ENABLE
|
||||
rccEnablePWRInterface(FALSE);
|
||||
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
|
||||
#endif /* STM32_PVD_ENABLE */
|
||||
}
|
||||
|
@ -122,15 +169,6 @@ void stm32_clock_init(void) {
|
|||
; /* Waits until LSI is stable. */
|
||||
#endif
|
||||
|
||||
#if STM32_LSE_ENABLED
|
||||
/* LSE activation, have to unlock the register.*/
|
||||
PWR->CR |= PWR_CR_DBP;
|
||||
RCC->BDCR |= RCC_BDCR_LSEON;
|
||||
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
|
||||
; /* Waits until LSE is stable. */
|
||||
PWR->CR &= ~PWR_CR_DBP;
|
||||
#endif
|
||||
|
||||
#if STM32_ACTIVATE_PLL
|
||||
/* PLL activation.*/
|
||||
RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
|
||||
|
@ -193,15 +231,6 @@ void stm32_clock_init(void) {
|
|||
; /* Waits until LSI is stable. */
|
||||
#endif
|
||||
|
||||
#if STM32_LSE_ENABLED
|
||||
/* LSE activation, have to unlock the register.*/
|
||||
PWR->CR |= PWR_CR_DBP;
|
||||
RCC->BDCR |= RCC_BDCR_LSEON;
|
||||
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
|
||||
; /* Waits until LSE is stable. */
|
||||
PWR->CR &= ~PWR_CR_DBP;
|
||||
#endif
|
||||
|
||||
/* Settings of various dividers and multipliers in CFGR2.*/
|
||||
RCC->CFGR2 = STM32_PLL3MUL | STM32_PLL2MUL | STM32_PREDIV2 |
|
||||
STM32_PREDIV1 | STM32_PREDIV1SRC;
|
||||
|
|
|
@ -649,7 +649,8 @@
|
|||
#endif
|
||||
|
||||
#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \
|
||||
((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && (STM32_PLLSRC == STM32_PLLSRC_HSI))
|
||||
((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \
|
||||
(STM32_PLLSRC == STM32_PLLSRC_HSI))
|
||||
#error "HSI not enabled, required by STM32_MCOSEL"
|
||||
#endif
|
||||
|
||||
|
@ -870,6 +871,21 @@
|
|||
#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RTC clock.
|
||||
*/
|
||||
#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__)
|
||||
#define STM32_RTCCLK STM32_LSECLK
|
||||
#elif STM32_RTCSEL == STM32_RTCSEL_LSI
|
||||
#define STM32_RTCCLK STM32_LSICLK
|
||||
#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV
|
||||
#define STM32_RTCCLK (STM32_HSECLK / 128)
|
||||
#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK
|
||||
#define STM32_RTCCLK 0
|
||||
#else
|
||||
#error "invalid source selected for RTC clock"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC frequency.
|
||||
*/
|
||||
|
|
|
@ -982,7 +982,8 @@
|
|||
#endif
|
||||
|
||||
#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \
|
||||
((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && (STM32_PLLSRC == STM32_PLLSRC_HSI))
|
||||
((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \
|
||||
(STM32_PLLSRC == STM32_PLLSRC_HSI))
|
||||
#error "HSI not enabled, required by STM32_MCOSEL"
|
||||
#endif
|
||||
|
||||
|
@ -1204,6 +1205,21 @@
|
|||
#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RTC clock.
|
||||
*/
|
||||
#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__)
|
||||
#define STM32_RTCCLK STM32_LSECLK
|
||||
#elif STM32_RTCSEL == STM32_RTCSEL_LSI
|
||||
#define STM32_RTCCLK STM32_LSICLK
|
||||
#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV
|
||||
#define STM32_RTCCLK (STM32_HSECLK / 128)
|
||||
#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK
|
||||
#define STM32_RTCCLK 0
|
||||
#else
|
||||
#error "invalid source selected for RTC clock"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC frequency.
|
||||
*/
|
||||
|
|
|
@ -597,7 +597,8 @@
|
|||
#endif
|
||||
|
||||
#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \
|
||||
((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && (STM32_PLLSRC == STM32_PLLSRC_HSI))
|
||||
((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \
|
||||
(STM32_PLLSRC == STM32_PLLSRC_HSI))
|
||||
#error "HSI not enabled, required by STM32_MCOSEL"
|
||||
#endif
|
||||
|
||||
|
@ -956,6 +957,21 @@
|
|||
#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RTC clock.
|
||||
*/
|
||||
#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__)
|
||||
#define STM32_RTCCLK STM32_LSECLK
|
||||
#elif STM32_RTCSEL == STM32_RTCSEL_LSI
|
||||
#define STM32_RTCCLK STM32_LSICLK
|
||||
#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV
|
||||
#define STM32_RTCCLK (STM32_HSECLK / 128)
|
||||
#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK
|
||||
#define STM32_RTCCLK 0
|
||||
#else
|
||||
#error "invalid source selected for RTC clock"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC frequency.
|
||||
*/
|
||||
|
|
|
@ -41,6 +41,47 @@
|
|||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the backup domain.
|
||||
*/
|
||||
static void hal_lld_backup_domain_init(void) {
|
||||
|
||||
/* Backup domain access enabled during initialization.*/
|
||||
PWR->CR |= PWR_CR_DBP;
|
||||
|
||||
/* RTC clock initialization.*/
|
||||
#if STM32_RTCSEL == STM32_RTCSEL_NOCLOCK
|
||||
/* RTC clock not required, backup domain reset as initialization.*/
|
||||
RCC->BDCR = RCC_BDCR_BDRST;
|
||||
RCC->BDCR = 0;
|
||||
#else /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
|
||||
/* If the backup domain hasn't been initialized yet then proceed with
|
||||
initialization.*/
|
||||
if (!(RCC->BDCR & RCC_BDCR_LSEON)) {
|
||||
/* Backup domain reset.*/
|
||||
RCC->BDCR = RCC_BDCR_BDRST;
|
||||
RCC->BDCR = 0;
|
||||
|
||||
/* If enabled then the LSE is started.*/
|
||||
#if STM32_LSE_ENABLED
|
||||
RCC->BDCR |= RCC_BDCR_LSEON;
|
||||
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
|
||||
; /* Waits until LSE is stable. */
|
||||
#endif
|
||||
|
||||
/* Selects clock source.*/
|
||||
RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTCSEL;
|
||||
|
||||
/* RTC enabled regardless its previous status, this will also prevent
|
||||
successive initializations.*/
|
||||
RCC->BDCR |= RCC_BDCR_RTCEN;
|
||||
}
|
||||
#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
|
||||
|
||||
/* Backup domain access disabled for operations safety.*/
|
||||
PWR->CR &= ~PWR_CR_DBP;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
@ -74,13 +115,18 @@ void hal_lld_init(void) {
|
|||
/* DWT cycle counter enable.*/
|
||||
DWT_CTRL |= DWT_CTRL_CYCCNTENA;
|
||||
|
||||
/* PWR clock enabled.*/
|
||||
rccEnablePWRInterface(FALSE);
|
||||
|
||||
/* Initializes the backup domain.*/
|
||||
hal_lld_backup_domain_init();
|
||||
|
||||
#if defined(STM32_DMA_REQUIRED)
|
||||
dmaInit();
|
||||
#endif
|
||||
|
||||
/* Programmable voltage detector enable.*/
|
||||
#if STM32_PVD_ENABLE
|
||||
rccEnablePWRInterface(FALSE);
|
||||
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
|
||||
#endif /* STM32_PVD_ENABLE */
|
||||
}
|
||||
|
|
|
@ -1229,16 +1229,6 @@
|
|||
#error "invalid STM32_MCO2PRE value specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief HSE divider toward RTC clock.
|
||||
*/
|
||||
#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \
|
||||
defined(__DOXYGEN__)
|
||||
#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE)
|
||||
#else
|
||||
#error "invalid STM32_RTCPRE value specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RTC HSE divider setting.
|
||||
*/
|
||||
|
@ -1249,6 +1239,16 @@
|
|||
#error "invalid STM32_RTCPRE value specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief HSE divider toward RTC clock.
|
||||
*/
|
||||
#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \
|
||||
defined(__DOXYGEN__)
|
||||
#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE)
|
||||
#else
|
||||
#error "invalid STM32_RTCPRE value specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RTC clock.
|
||||
*/
|
||||
|
|
|
@ -41,6 +41,47 @@
|
|||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the backup domain.
|
||||
*/
|
||||
static void hal_lld_backup_domain_init(void) {
|
||||
|
||||
/* Backup domain access enabled during initialization.*/
|
||||
PWR->CR |= PWR_CR_DBP;
|
||||
|
||||
/* RTC clock initialization.*/
|
||||
#if STM32_RTCSEL == STM32_RTCSEL_NOCLOCK
|
||||
/* RTC clock not required, backup domain reset as initialization.*/
|
||||
RCC->BDCR = RCC_BDCR_BDRST;
|
||||
RCC->BDCR = 0;
|
||||
#else /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
|
||||
/* If the backup domain hasn't been initialized yet then proceed with
|
||||
initialization.*/
|
||||
if (!(RCC->BDCR & RCC_BDCR_LSEON)) {
|
||||
/* Backup domain reset.*/
|
||||
RCC->BDCR = RCC_BDCR_BDRST;
|
||||
RCC->BDCR = 0;
|
||||
|
||||
/* If enabled then the LSE is started.*/
|
||||
#if STM32_LSE_ENABLED
|
||||
RCC->BDCR |= RCC_BDCR_LSEON;
|
||||
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
|
||||
; /* Waits until LSE is stable. */
|
||||
#endif
|
||||
|
||||
/* Selects clock source.*/
|
||||
RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTCSEL;
|
||||
|
||||
/* RTC enabled regardless its previous status, this will also prevent
|
||||
successive initializations.*/
|
||||
RCC->BDCR |= RCC_BDCR_RTCEN;
|
||||
}
|
||||
#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
|
||||
|
||||
/* Backup domain access disabled for operations safety.*/
|
||||
PWR->CR &= ~PWR_CR_DBP;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
@ -74,13 +115,18 @@ void hal_lld_init(void) {
|
|||
/* DWT cycle counter enable.*/
|
||||
DWT_CTRL |= DWT_CTRL_CYCCNTENA;
|
||||
|
||||
/* PWR clock enabled.*/
|
||||
rccEnablePWRInterface(FALSE);
|
||||
|
||||
/* Initializes the backup domain.*/
|
||||
hal_lld_backup_domain_init();
|
||||
|
||||
#if defined(STM32_DMA_REQUIRED)
|
||||
dmaInit();
|
||||
#endif
|
||||
|
||||
/* Programmable voltage detector enable.*/
|
||||
#if STM32_PVD_ENABLE
|
||||
rccEnablePWRInterface(FALSE);
|
||||
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
|
||||
#endif /* STM32_PVD_ENABLE */
|
||||
}
|
||||
|
|
|
@ -1249,16 +1249,6 @@
|
|||
#error "invalid STM32_MCO2PRE value specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief HSE divider toward RTC clock.
|
||||
*/
|
||||
#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \
|
||||
defined(__DOXYGEN__)
|
||||
#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE)
|
||||
#else
|
||||
#error "invalid STM32_RTCPRE value specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RTC HSE divider setting.
|
||||
*/
|
||||
|
@ -1269,6 +1259,16 @@
|
|||
#error "invalid STM32_RTCPRE value specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief HSE divider toward RTC clock.
|
||||
*/
|
||||
#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \
|
||||
defined(__DOXYGEN__)
|
||||
#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE)
|
||||
#else
|
||||
#error "invalid STM32_RTCPRE value specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RTC clock.
|
||||
*/
|
||||
|
@ -1284,6 +1284,16 @@
|
|||
#error "invalid STM32_RTCSEL value specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RTC HSE divider setting.
|
||||
*/
|
||||
#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \
|
||||
defined(__DOXYGEN__)
|
||||
#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16)
|
||||
#else
|
||||
#error "invalid STM32_RTCPRE value specified"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 48MHz frequency.
|
||||
*/
|
||||
|
|
|
@ -41,6 +41,47 @@
|
|||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the backup domain.
|
||||
*/
|
||||
static void hal_lld_backup_domain_init(void) {
|
||||
|
||||
/* Backup domain access enabled during initialization.*/
|
||||
PWR->CR |= PWR_CR_DBP;
|
||||
|
||||
/* RTC clock initialization.*/
|
||||
#if STM32_RTCSEL == STM32_RTCSEL_NOCLOCK
|
||||
/* RTC clock not required, backup domain reset as initialization.*/
|
||||
RCC->BDCR = RCC_BDCR_BDRST;
|
||||
RCC->BDCR = 0;
|
||||
#else /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
|
||||
/* If the backup domain hasn't been initialized yet then proceed with
|
||||
initialization.*/
|
||||
if (!(RCC->BDCR & RCC_BDCR_LSEON)) {
|
||||
/* Backup domain reset.*/
|
||||
RCC->BDCR = RCC_BDCR_BDRST;
|
||||
RCC->BDCR = 0;
|
||||
|
||||
/* If enabled then the LSE is started.*/
|
||||
#if STM32_LSE_ENABLED
|
||||
RCC->BDCR |= RCC_BDCR_LSEON;
|
||||
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
|
||||
; /* Waits until LSE is stable. */
|
||||
#endif
|
||||
|
||||
/* Selects clock source.*/
|
||||
RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTCSEL;
|
||||
|
||||
/* RTC enabled regardless its previous status, this will also prevent
|
||||
successive initializations.*/
|
||||
RCC->BDCR |= RCC_BDCR_RTCEN;
|
||||
}
|
||||
#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
|
||||
|
||||
/* Backup domain access disabled for operations safety.*/
|
||||
PWR->CR &= ~PWR_CR_DBP;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
@ -71,13 +112,18 @@ void hal_lld_init(void) {
|
|||
/* DWT cycle counter enable.*/
|
||||
DWT_CTRL |= DWT_CTRL_CYCCNTENA;
|
||||
|
||||
/* PWR clock enabled.*/
|
||||
rccEnablePWRInterface(FALSE);
|
||||
|
||||
/* Initializes the backup domain.*/
|
||||
hal_lld_backup_domain_init();
|
||||
|
||||
#if defined(STM32_DMA_REQUIRED)
|
||||
dmaInit();
|
||||
#endif
|
||||
|
||||
/* Programmable voltage detector enable.*/
|
||||
#if STM32_PVD_ENABLE
|
||||
rccEnablePWRInterface(FALSE);
|
||||
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
|
||||
#endif /* STM32_PVD_ENABLE */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue