clock source auto detect

This commit is contained in:
olikraus 2017-05-25 16:25:58 +02:00
parent 5cbe4eed95
commit 818c67cd32
2 changed files with 149 additions and 22 deletions

View File

@ -343,9 +343,12 @@ void initDisplay(uint8_t is_por)
This must be executed only after POR reset.
*/
void initRTC(void)
/* write access must be activated before calling this function: PWR->CR |= PWR_CR_DBP; */
unsigned int initRTC(void)
{
unsigned int r = 0;
/* real time clock enable */
//enableRCCRTCWrite();
__disable_irq();
@ -353,36 +356,57 @@ void initRTC(void)
RTC->WPR = 0x0ca; /* disable RTC write protection */
RTC->WPR = 0x053;
/* externel 32K clock source */
/* try externel 32K clock source */
RCC->CSR |= RCC_CSR_LSEBYP; /* bypass oscillator */
/* externel 32K oscillator */
//RCC->CSR &= ~RCC_CSR_LSEBYP; /* no bypass oscillator */
//RCC->CSR &= ~RCC_CSR_LSEDRV_Msk /* lowest drive */
//RCC->CSR |= RCC_CSR_LSEDRV_0; /* medium low drive */
RCC->CSR |= RCC_CSR_LSEON; /* enable low speed external clock */
delay_micro_seconds(100000*5); /* LSE requires between 100ms to 200ms */
/*
if ( RCC->CSR & RCC_CSR_LSERDY )
display_Write("32K Clock Ready\n");
else
display_Write("32K Clock Error\n");
*/
RCC->CSR &= ~RCC_CSR_RTCSEL_Msk; /* no clock selection for RTC */
RCC->CSR |= RCC_CSR_RTCSEL_LSE; /* select LSE */
RCC->CSR |= RCC_CSR_RTCEN; /* enable RTC */
RTC->ISR = RTC_ISR_INIT; /* request RTC stop */
while((RTC->ISR & RTC_ISR_INITF)!=RTC_ISR_INITF) /* wait for stop */
;
RTC->PRER = 0x07f00ff; /* 1 Hz clock */
RTC->TR = 0;
RTC->ISR =~ RTC_ISR_INIT; /* start RTC */
if ( RCC->CSR & RCC_CSR_LSERDY )
{
r = 1;
}
else
{
RCC->CSR &= ~RCC_CSR_LSEON; /* disable external clock */
/* try externel 32K oscillator */
RCC->CSR &= ~RCC_CSR_LSEBYP; /* no bypass oscillator */
RCC->CSR &= ~RCC_CSR_LSEDRV_Msk; /* lowest drive */
RCC->CSR |= RCC_CSR_LSEDRV_0; /* medium low drive */
RCC->CSR |= RCC_CSR_LSEON; /* enable low speed external clock */
delay_micro_seconds(100000*6); /* LSE requires between 200ms and 400ms */
if ( RCC->CSR & RCC_CSR_LSERDY )
{
r = 2;
}
}
if ( r > 0 )
{
RCC->CSR &= ~RCC_CSR_RTCSEL_Msk; /* no clock selection for RTC */
RCC->CSR |= RCC_CSR_RTCSEL_LSE; /* select LSE */
RCC->CSR |= RCC_CSR_RTCEN; /* enable RTC */
RTC->ISR = RTC_ISR_INIT; /* request RTC stop */
while((RTC->ISR & RTC_ISR_INITF)!=RTC_ISR_INITF) /* wait for stop */
;
RTC->PRER = 0x07f00ff; /* 1 Hz clock */
RTC->TR = 0;
RTC->ISR =~ RTC_ISR_INIT; /* start RTC */
}
RTC->WPR = 0; /* enable RTC write protection */
RTC->WPR = 0;
__enable_irq();
return r;
}
/*=======================================================================*/

View File

@ -78,8 +78,107 @@ void setHSIClock()
;
}
/*
Enable several power regions: PWR, GPIOA
Enable write access to RTC
This must be executed after each reset.
*/
void startUp(void)
{
RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
RCC->APB1ENR |= RCC_APB1ENR_PWREN; /* enable power interface */
PWR->CR |= PWR_CR_DBP; /* activate write access to RCC->CSR and RTC */
//PWR_CSR_Backup = PWR->CSR; /* create a backup of the original PWR_CSR register for later analysis */
PWR->CR |= PWR_CR_CSBF; /* clear the standby flag in the PWR_CSR register, but luckily we have a copy */
PWR->CR |= PWR_CR_CWUF; /* also clear the WUF flag in PWR_CSR */
/* PA0, TAMP2, button input */
GPIOA->MODER &= ~GPIO_MODER_MODE0; /* clear mode for PA0 */
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD0; /* no pullup/pulldown for PA0 */
GPIOA->PUPDR |= GPIO_PUPDR_PUPD0_0; /* pullup for PA0 */
/* PA2, TAMP3, button input */
GPIOA->MODER &= ~GPIO_MODER_MODE2; /* clear mode for PA2 */
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD2; /* no pullup/pulldown for PA2 */
GPIOA->PUPDR |= GPIO_PUPDR_PUPD2_0; /* pullup for PA2 */
}
/* write access must be activated before calling this function: PWR->CR |= PWR_CR_DBP; */
unsigned int initRTC(void)
{
unsigned int r = 0;
/* real time clock enable */
//enableRCCRTCWrite();
__disable_irq();
RTC->WPR = 0x0ca; /* disable RTC write protection */
RTC->WPR = 0x053;
/* try externel 32K clock source */
RCC->CSR |= RCC_CSR_LSEBYP; /* bypass oscillator */
RCC->CSR |= RCC_CSR_LSEON; /* enable low speed external clock */
delay_micro_seconds(100000*5); /* LSE requires between 100ms to 200ms */
if ( RCC->CSR & RCC_CSR_LSERDY )
{
r = 1;
}
else
{
RCC->CSR &= ~RCC_CSR_LSEON; /* disable external clock */
/* try externel 32K oscillator */
RCC->CSR &= ~RCC_CSR_LSEBYP; /* no bypass oscillator */
RCC->CSR &= ~RCC_CSR_LSEDRV_Msk; /* lowest drive */
RCC->CSR |= RCC_CSR_LSEDRV_0; /* medium low drive */
RCC->CSR |= RCC_CSR_LSEON; /* enable low speed external clock */
delay_micro_seconds(100000*6); /* LSE requires between 200ms and 400ms */
if ( RCC->CSR & RCC_CSR_LSERDY )
{
r = 2;
}
}
if ( r > 0 )
{
RCC->CSR &= ~RCC_CSR_RTCSEL_Msk; /* no clock selection for RTC */
RCC->CSR |= RCC_CSR_RTCSEL_LSE; /* select LSE */
RCC->CSR |= RCC_CSR_RTCEN; /* enable RTC */
RTC->ISR = RTC_ISR_INIT; /* request RTC stop */
while((RTC->ISR & RTC_ISR_INITF)!=RTC_ISR_INITF) /* wait for stop */
;
RTC->PRER = 0x07f00ff; /* 1 Hz clock */
RTC->TR = 0;
RTC->ISR =~ RTC_ISR_INIT; /* start RTC */
}
RTC->WPR = 0; /* enable RTC write protection */
RTC->WPR = 0;
__enable_irq();
return r;
}
int main()
{
unsigned int rtcState;
setHSIClock();
SystemCoreClockUpdate(); /* Update SystemCoreClock() */
//SystemCoreClock = 32000000UL;
@ -106,12 +205,16 @@ int main()
//u8g2_InitDisplay(&u8g2);
//u8g2_SetPowerSave(&u8g2, 0);
startUp();
rtcState = initRTC();
u8x8_Setup(&u8x8, u8x8_d_ssd1306_128x64_noname, u8x8_cad_ssd13xx_i2c, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_stm32l0);
u8x8_InitDisplay(&u8x8);
u8x8_ClearDisplay(&u8x8);
u8x8_SetPowerSave(&u8x8, 0);
u8x8_SetFont(&u8x8, u8x8_font_amstrad_cpc_extended_r);
u8x8_DrawString(&u8x8, 0,0, "Hello World!");
u8x8_DrawGlyph(&u8x8, 0,1, rtcState+'0');
for(;;)
{