From 818c67cd32dc4aef6ca6721320361d62b6831269 Mon Sep 17 00:00:00 2001 From: olikraus Date: Thu, 25 May 2017 16:25:58 +0200 Subject: [PATCH] clock source auto detect --- sys/arm/stm32l031x6/clock/main.c | 68 ++++++++++++------ sys/arm/stm32l031x6/u8x8_test/main.c | 103 +++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 22 deletions(-) diff --git a/sys/arm/stm32l031x6/clock/main.c b/sys/arm/stm32l031x6/clock/main.c index 59c185b6..ef333626 100644 --- a/sys/arm/stm32l031x6/clock/main.c +++ b/sys/arm/stm32l031x6/clock/main.c @@ -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; } /*=======================================================================*/ diff --git a/sys/arm/stm32l031x6/u8x8_test/main.c b/sys/arm/stm32l031x6/u8x8_test/main.c index 26481943..84c5bec6 100644 --- a/sys/arm/stm32l031x6/u8x8_test/main.c +++ b/sys/arm/stm32l031x6/u8x8_test/main.c @@ -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(;;) {