From e1526bb2c84b315c72a089dbb50447183d4b1685 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 2 Dec 2020 13:40:04 +0100 Subject: msp430fr5994lp: add 16MHz HFXT clock source support --- src/arch/msp430fr5994lp/Kconfig | 6 +++++ src/arch/msp430fr5994lp/Makefile.inc | 8 ++++++ src/arch/msp430fr5994lp/arch.cc | 42 ++++++++++++++++++++++++++++++-- src/arch/msp430fr5994lp/driver/stdout.cc | 9 +++++++ 4 files changed, 63 insertions(+), 2 deletions(-) (limited to 'src/arch/msp430fr5994lp') diff --git a/src/arch/msp430fr5994lp/Kconfig b/src/arch/msp430fr5994lp/Kconfig index e240c2b..60f0d6c 100644 --- a/src/arch/msp430fr5994lp/Kconfig +++ b/src/arch/msp430fr5994lp/Kconfig @@ -34,3 +34,9 @@ select meta_driver_uptime config arch_msp430fr5994lp_large_mode bool "Large Memory Model (20bit pointers, 256kB FRAM)" + +config arch_msp430fr5994lp_hfxt_16mhz +bool "Use external 16MHz HFXT for system clock" +help + System clock source defaults to DCO, HFXT is unpopulated by default. + Enable this option if your board contains a 16MHz crystal on HFXT. diff --git a/src/arch/msp430fr5994lp/Makefile.inc b/src/arch/msp430fr5994lp/Makefile.inc index 9f0ef89..f6ca67e 100644 --- a/src/arch/msp430fr5994lp/Makefile.inc +++ b/src/arch/msp430fr5994lp/Makefile.inc @@ -77,6 +77,10 @@ ifeq (${timer_s}, 1) CONFIG_arch_msp430fr5994lp_driver_uptime = y endif +ifeq (${with_hfxt}, 1) + CONFIG_arch_msp430fr5994lp_hfxt_16mhz = y +endif + # Kconfig ifdef CONFIG_arch_msp430fr5994lp_driver_adc @@ -109,6 +113,10 @@ ifdef CONFIG_arch_msp430fr5994lp_driver_uptime CXX_TARGETS += src/arch/msp430fr5994lp/driver/uptime.cc endif +ifdef CONFIG_arch_msp430fr5994lp_hfxt_16mhz + COMMON_FLAGS += -DWITH_HFXT_16MHZ +endif + ifneq ($(findstring timed_resistive_load,${arch_drivers}), ) CXX_TARGETS += src/arch/msp430fr5994lp/driver/timed_resistive_load.cc diff --git a/src/arch/msp430fr5994lp/arch.cc b/src/arch/msp430fr5994lp/arch.cc index 4edab89..b247da3 100644 --- a/src/arch/msp430fr5994lp/arch.cc +++ b/src/arch/msp430fr5994lp/arch.cc @@ -56,15 +56,53 @@ void Arch::setup(void) // enable LXFT for RTC CSCTL0_H = CSKEY >> 8; CSCTL4 &= ~LFXTOFF; - while (SFRIFG1 & OFIFG) { + while (CSCTL5 & LFXTOFFG) { CSCTL5 &= ~LFXTOFFG; - SFRIFG1 &= ~OFIFG; } + SFRIFG1 &= ~OFIFG; CSCTL0_H = 0; __delay_cycles(1000000); #endif +#ifdef WITH_HFXT_16MHZ + PJSEL0 |= BIT6 | BIT7; + CSCTL0_H = CSKEY >> 8; + + // set HFFREQ to 8-16 MHz (HFFREQ=10) + CSCTL4 = HFXTDRIVE_0 | HFFREQ_2 | (CSCTL4 & 0x0f); + + // enable HFXT for SMCLK + while (CSCTL5 & HFXTOFFG) { + CSCTL5 &= ~HFXTOFFG; + } + SFRIFG1 &= ~OFIFG; + CSCTL0_H = 0; + + // wait for it to stabilize + __delay_cycles(1000000); + + // set MCLK and SMCLK to HFXT + CSCTL0_H = CSKEY >> 8; +#if F_CPU == 16000000UL + CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; +#elif F_CPU == 8000000UL + CSCTL3 = DIVA__1 | DIVS__2 | DIVM__2; +#elif F_CPU == 4000000UL + CSCTL3 = DIVA__1 | DIVS__4 | DIVM__4; +#elif F_CPU == 1000000UL + CSCTL3 = DIVA__1 | DIVS__16 | DIVM__16; +#endif + // SELA__LFXTCLK falls back to VLOCLK if LFXT is not available, but set + // LFXT_FAULT (LFXTOFFG) in the process. We don't want that. +#if defined(WITH_LOOP) || F_CPU == 32768UL + CSCTL2 = SELA__LFXTCLK | SELS__HFXTCLK | SELM__HFXTCLK; +#else + CSCTL2 = SELA__VLOCLK | SELS__HFXTCLK | SELM__HFXTCLK; +#endif + CSCTL0_H = 0; +#endif + #ifdef TIMER_US #if F_CPU == 16000000UL TA0CTL = TASSEL__SMCLK | ID__8 | MC__CONTINUOUS; // /8 diff --git a/src/arch/msp430fr5994lp/driver/stdout.cc b/src/arch/msp430fr5994lp/driver/stdout.cc index f3c219a..ccac54b 100644 --- a/src/arch/msp430fr5994lp/driver/stdout.cc +++ b/src/arch/msp430fr5994lp/driver/stdout.cc @@ -51,6 +51,15 @@ void StandardOutput::setup() UCA0CTLW0 &= ~UCSWRST; +#if 0 + if (CSCTL5 & LFXTOFFG) { + kout << "! LFXT fault" << endl; + } + if (CSCTL5 & HFXTOFFG) { + kout << "! HFXT fault" << endl; + } +#endif + //UCA0IE |= UCRXIE; } -- cgit v1.2.3