git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3783 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2012-01-10 18:14:24 +00:00
parent a40e2315db
commit 8824a54e5e
12 changed files with 293 additions and 119 deletions

View File

@ -87,7 +87,7 @@ static void rtc_lld_serve_interrupt(RTCDriver *rtcp) {
static void rtc_lld_wait_write(void) { static void rtc_lld_wait_write(void) {
/* Waits registers write completion.*/ /* 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 * @notapi
*/ */
void rtc_lld_init(void){ 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 /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling
clocking on APB1, because these values only update when APB1 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.*/ /* Write preload register only if its value differs.*/
if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + (uint32_t)RTC->PRLL)) { if (STM32_RTCCLK != (((uint32_t)(RTC->PRLH)) << 16) +
((uint32_t)RTC->PRLL) + 1) {
rtc_lld_wait_write();
/* Enters configuration mode and writes PRLx registers then leaves the /* Enters configuration mode and writes PRLx registers then leaves the
configuration mode.*/ configuration mode.*/
rtc_lld_wait_write();
RTC->CRL |= RTC_CRL_CNF; RTC->CRL |= RTC_CRL_CNF;
RTC->PRLH = (uint16_t)(preload >> 16); RTC->PRLH = (uint16_t)((STM32_RTCCLK - 1) >> 16);
RTC->PRLL = (uint16_t)(preload & 0xFFFF); RTC->PRLL = (uint16_t)((STM32_RTCCLK - 1) & 0xFFFF);
RTC->CRL &= ~RTC_CRL_CNF; RTC->CRL &= ~RTC_CRL_CNF;
} }
@ -209,7 +165,6 @@ void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec) {
(void)rtcp; (void)rtcp;
rtc_lld_wait_write(); rtc_lld_wait_write();
RTC->CRL |= RTC_CRL_CNF; RTC->CRL |= RTC_CRL_CNF;
RTC->CNTH = (uint16_t)(timespec->tv_sec >> 16); RTC->CNTH = (uint16_t)(timespec->tv_sec >> 16);
RTC->CNTL = (uint16_t)(timespec->tv_sec & 0xFFFF); 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; uint32_t time_frac;
READ_REGISTERS: /* The read is repeated until we are able to do it twice and obtain the
timespec->tv_sec = ((uint32_t)(RTC->CNTH) << 16) + RTC->CNTL; same result.*/
time_frac = (((uint32_t)RTC->DIVH) << 16) + (uint32_t)RTC->DIVL; 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 timespec->tv_msec = (uint16_t)(((STM32_RTCCLK - 1 - time_frac) * 1000) /
* we must reread both values. */ STM32_RTCCLK);
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);
} }
/** /**
@ -260,10 +213,10 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
(void)rtcp; (void)rtcp;
(void)alarm; (void)alarm;
rtc_lld_wait_write();
/* Enters configuration mode and writes ALRHx registers then leaves the /* Enters configuration mode and writes ALRHx registers then leaves the
configuration mode.*/ configuration mode.*/
rtc_lld_wait_write();
RTC->CRL |= RTC_CRL_CNF; RTC->CRL |= RTC_CRL_CNF;
if (alarmspec != NULL) { if (alarmspec != NULL) {
RTC->ALRH = (uint16_t)(alarmspec->tv_sec >> 16); RTC->ALRH = (uint16_t)(alarmspec->tv_sec >> 16);
@ -315,17 +268,14 @@ void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) {
rtcp->callback = callback; rtcp->callback = callback;
/* Interrupts are enabled only after setting up the callback, this /* Interrupts are enabled only after setting up the callback, this
way there is no need to check for the NULL callback pointer inside way there is no need to check for the NULL callback pointer inside
the IRQ handler.*/ the IRQ handler.*/
rtc_lld_wait_write();
RTC->CRL &= ~(RTC_CRL_OWF | RTC_CRL_ALRF | RTC_CRL_SECF); 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)); nvicEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY));
RTC->CRH |= RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE; RTC->CRH |= RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE;
} }
else { else {
nvicDisableVector(RTC_IRQn); nvicDisableVector(RTC_IRQn);
rtc_lld_wait_write();
RTC->CRL = 0; RTC->CRL = 0;
RTC->CRH = 0; RTC->CRH = 0;
} }

View File

@ -61,9 +61,8 @@
#error "RTC not present in the selected device" #error "RTC not present in the selected device"
#endif #endif
#if !(STM32_RTC == STM32_RTC_LSE) && !(STM32_RTC == STM32_RTC_LSI) && \ #if STM32_RTCCLK == 0
!(STM32_RTC == STM32_RTC_HSE) #error "RTC clock not enabled"
#error "invalid source selected for RTC clock"
#endif #endif
/*===========================================================================*/ /*===========================================================================*/

View File

@ -41,6 +41,47 @@
/* Driver local functions. */ /* 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. */ /* Driver interrupt handlers. */
/*===========================================================================*/ /*===========================================================================*/
@ -70,13 +111,19 @@ void hal_lld_init(void) {
/* DWT cycle counter enable.*/ /* DWT cycle counter enable.*/
DWT_CTRL |= DWT_CTRL_CYCCNTENA; 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) #if defined(STM32_DMA_REQUIRED)
dmaInit(); dmaInit();
#endif #endif
/* Programmable voltage detector enable.*/ /* Programmable voltage detector enable.*/
#if STM32_PVD_ENABLE #if STM32_PVD_ENABLE
rccEnablePWRInterface(FALSE);
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
#endif /* STM32_PVD_ENABLE */ #endif /* STM32_PVD_ENABLE */
} }
@ -122,15 +169,6 @@ void stm32_clock_init(void) {
; /* Waits until LSI is stable. */ ; /* Waits until LSI is stable. */
#endif #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 #if STM32_ACTIVATE_PLL
/* PLL activation.*/ /* PLL activation.*/
RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC; RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
@ -193,15 +231,6 @@ void stm32_clock_init(void) {
; /* Waits until LSI is stable. */ ; /* Waits until LSI is stable. */
#endif #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.*/ /* Settings of various dividers and multipliers in CFGR2.*/
RCC->CFGR2 = STM32_PLL3MUL | STM32_PLL2MUL | STM32_PREDIV2 | RCC->CFGR2 = STM32_PLL3MUL | STM32_PLL2MUL | STM32_PREDIV2 |
STM32_PREDIV1 | STM32_PREDIV1SRC; STM32_PREDIV1 | STM32_PREDIV1SRC;

View File

@ -648,8 +648,9 @@
#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" #error "HSI not enabled, required by STM32_SW and STM32_PLLSRC"
#endif #endif
#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ #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" #error "HSI not enabled, required by STM32_MCOSEL"
#endif #endif
@ -870,6 +871,21 @@
#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" #error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)"
#endif #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. * @brief ADC frequency.
*/ */

View File

@ -981,8 +981,9 @@
#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" #error "HSI not enabled, required by STM32_SW and STM32_PLLSRC"
#endif #endif
#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ #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" #error "HSI not enabled, required by STM32_MCOSEL"
#endif #endif
@ -1204,6 +1205,21 @@
#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" #error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)"
#endif #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. * @brief ADC frequency.
*/ */

View File

@ -596,8 +596,9 @@
#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" #error "HSI not enabled, required by STM32_SW and STM32_PLLSRC"
#endif #endif
#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ #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" #error "HSI not enabled, required by STM32_MCOSEL"
#endif #endif
@ -956,6 +957,21 @@
#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" #error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)"
#endif #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. * @brief ADC frequency.
*/ */

View File

@ -41,6 +41,47 @@
/* Driver local functions. */ /* 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. */ /* Driver interrupt handlers. */
/*===========================================================================*/ /*===========================================================================*/
@ -74,13 +115,18 @@ void hal_lld_init(void) {
/* DWT cycle counter enable.*/ /* DWT cycle counter enable.*/
DWT_CTRL |= DWT_CTRL_CYCCNTENA; DWT_CTRL |= DWT_CTRL_CYCCNTENA;
/* PWR clock enabled.*/
rccEnablePWRInterface(FALSE);
/* Initializes the backup domain.*/
hal_lld_backup_domain_init();
#if defined(STM32_DMA_REQUIRED) #if defined(STM32_DMA_REQUIRED)
dmaInit(); dmaInit();
#endif #endif
/* Programmable voltage detector enable.*/ /* Programmable voltage detector enable.*/
#if STM32_PVD_ENABLE #if STM32_PVD_ENABLE
rccEnablePWRInterface(FALSE);
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
#endif /* STM32_PVD_ENABLE */ #endif /* STM32_PVD_ENABLE */
} }

View File

@ -1229,16 +1229,6 @@
#error "invalid STM32_MCO2PRE value specified" #error "invalid STM32_MCO2PRE value specified"
#endif #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. * @brief RTC HSE divider setting.
*/ */
@ -1249,6 +1239,16 @@
#error "invalid STM32_RTCPRE value specified" #error "invalid STM32_RTCPRE value specified"
#endif #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. * @brief RTC clock.
*/ */

View File

@ -41,6 +41,47 @@
/* Driver local functions. */ /* 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. */ /* Driver interrupt handlers. */
/*===========================================================================*/ /*===========================================================================*/
@ -74,13 +115,18 @@ void hal_lld_init(void) {
/* DWT cycle counter enable.*/ /* DWT cycle counter enable.*/
DWT_CTRL |= DWT_CTRL_CYCCNTENA; DWT_CTRL |= DWT_CTRL_CYCCNTENA;
/* PWR clock enabled.*/
rccEnablePWRInterface(FALSE);
/* Initializes the backup domain.*/
hal_lld_backup_domain_init();
#if defined(STM32_DMA_REQUIRED) #if defined(STM32_DMA_REQUIRED)
dmaInit(); dmaInit();
#endif #endif
/* Programmable voltage detector enable.*/ /* Programmable voltage detector enable.*/
#if STM32_PVD_ENABLE #if STM32_PVD_ENABLE
rccEnablePWRInterface(FALSE);
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
#endif /* STM32_PVD_ENABLE */ #endif /* STM32_PVD_ENABLE */
} }

View File

@ -1249,16 +1249,6 @@
#error "invalid STM32_MCO2PRE value specified" #error "invalid STM32_MCO2PRE value specified"
#endif #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. * @brief RTC HSE divider setting.
*/ */
@ -1269,6 +1259,16 @@
#error "invalid STM32_RTCPRE value specified" #error "invalid STM32_RTCPRE value specified"
#endif #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. * @brief RTC clock.
*/ */
@ -1284,6 +1284,16 @@
#error "invalid STM32_RTCSEL value specified" #error "invalid STM32_RTCSEL value specified"
#endif #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. * @brief 48MHz frequency.
*/ */

View File

@ -41,6 +41,47 @@
/* Driver local functions. */ /* 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. */ /* Driver interrupt handlers. */
/*===========================================================================*/ /*===========================================================================*/
@ -71,13 +112,18 @@ void hal_lld_init(void) {
/* DWT cycle counter enable.*/ /* DWT cycle counter enable.*/
DWT_CTRL |= DWT_CTRL_CYCCNTENA; DWT_CTRL |= DWT_CTRL_CYCCNTENA;
/* PWR clock enabled.*/
rccEnablePWRInterface(FALSE);
/* Initializes the backup domain.*/
hal_lld_backup_domain_init();
#if defined(STM32_DMA_REQUIRED) #if defined(STM32_DMA_REQUIRED)
dmaInit(); dmaInit();
#endif #endif
/* Programmable voltage detector enable.*/ /* Programmable voltage detector enable.*/
#if STM32_PVD_ENABLE #if STM32_PVD_ENABLE
rccEnablePWRInterface(FALSE);
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
#endif /* STM32_PVD_ENABLE */ #endif /* STM32_PVD_ENABLE */
} }

View File

@ -125,7 +125,7 @@ struct Thread {
#if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__) #if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__)
/** /**
* @brief Thread consumed time in ticks. * @brief Thread consumed time in ticks.
* @note This field can overflow. * @note This field can overflow.
*/ */
volatile systime_t p_time; volatile systime_t p_time;
#endif #endif