Repository: incubator-mynewt-core Updated Branches: refs/heads/develop ac1496259 -> a9d943b70
No jira ticket: nrf51 bsps should use #define for RTC The nrf51 code should have used a #define for the os tick timer as opposed to always using RTC0. I updated the code to use a #define and also RTC1 as RTC0 may need to be used exclusively for the BLE stack (not sure about that). Also, added a clock start function to hal_system.c as I am not sure of ordering in regards to when hal_bsp_init() will be called and when the clocks were started by os_tick_init(). The new function checks to see if the desired clock has already been started and if it has, do nothing. Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/a9d943b7 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/a9d943b7 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/a9d943b7 Branch: refs/heads/develop Commit: a9d943b70ebbff5de1dc0ee5df358e5c741a8656 Parents: b02a2ea Author: William San Filippo <[email protected]> Authored: Tue Jan 3 15:18:31 2017 -0800 Committer: William San Filippo <[email protected]> Committed: Tue Jan 3 15:21:30 2017 -0800 ---------------------------------------------------------------------- hw/bsp/nrf51-arduino_101/src/hal_bsp.c | 4 ++ hw/bsp/nrf51-blenano/src/hal_bsp.c | 4 ++ hw/bsp/nrf51dk-16kbram/src/hal_bsp.c | 4 ++ hw/bsp/nrf51dk/src/hal_bsp.c | 4 ++ hw/hal/include/hal/hal_system.h | 3 + hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c | 84 +++++++-------------------- hw/mcu/nordic/nrf51xxx/src/hal_system.c | 63 ++++++++++++++++++++ 7 files changed, 104 insertions(+), 62 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9d943b7/hw/bsp/nrf51-arduino_101/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51-arduino_101/src/hal_bsp.c b/hw/bsp/nrf51-arduino_101/src/hal_bsp.c index 0133981..df33be2 100644 --- a/hw/bsp/nrf51-arduino_101/src/hal_bsp.c +++ b/hw/bsp/nrf51-arduino_101/src/hal_bsp.c @@ -23,6 +23,7 @@ #include <nrf51.h> #include <mcu/nrf51_hal.h> #include <hal/hal_bsp.h> +#include "hal/hal_system.h" #include "bsp/bsp.h" #include "os/os_cputime.h" #include "syscfg/syscfg.h" @@ -131,6 +132,9 @@ hal_bsp_init(void) { int rc; + /* Make sure system clocks have started */ + hal_system_clock_start(); + #if MYNEWT_VAL(UART_0) rc = os_dev_create((struct os_dev *) &os_bsp_uart0, "uart0", OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&os_bsp_uart0_cfg); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9d943b7/hw/bsp/nrf51-blenano/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51-blenano/src/hal_bsp.c b/hw/bsp/nrf51-blenano/src/hal_bsp.c index 8350f9f..c85ece2 100644 --- a/hw/bsp/nrf51-blenano/src/hal_bsp.c +++ b/hw/bsp/nrf51-blenano/src/hal_bsp.c @@ -20,6 +20,7 @@ #include <stdint.h> #include <stddef.h> #include <assert.h> +#include "hal/hal_system.h" #include "bsp/bsp.h" #include <nrf51.h> #include "mcu/nrf51_hal.h" @@ -132,6 +133,9 @@ hal_bsp_init(void) (void)rc; + /* Make sure system clocks have started */ + hal_system_clock_start(); + #if MYNEWT_VAL(UART_0) rc = os_dev_create((struct os_dev *) &os_bsp_uart0, "uart0", OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&os_bsp_uart0_cfg); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9d943b7/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c b/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c index bb60993..63b6d94 100644 --- a/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c +++ b/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c @@ -22,6 +22,7 @@ #include <assert.h> #include "syscfg/syscfg.h" #include "hal/hal_bsp.h" +#include "hal/hal_system.h" #include "mcu/nrf51_hal.h" #include "bsp/bsp.h" #include "os/os_dev.h" @@ -142,6 +143,9 @@ hal_bsp_init(void) (void)rc; + /* Make sure system clocks have started */ + hal_system_clock_start(); + #if MYNEWT_VAL(UART_0) rc = os_dev_create((struct os_dev *) &os_bsp_uart0, "uart0", OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&os_bsp_uart0_cfg); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9d943b7/hw/bsp/nrf51dk/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51dk/src/hal_bsp.c b/hw/bsp/nrf51dk/src/hal_bsp.c index 7c77aca..4e65c68 100644 --- a/hw/bsp/nrf51dk/src/hal_bsp.c +++ b/hw/bsp/nrf51dk/src/hal_bsp.c @@ -22,6 +22,7 @@ #include <assert.h> #include "syscfg/syscfg.h" #include "hal/hal_bsp.h" +#include "hal/hal_system.h" #include "mcu/nrf51_hal.h" #include "bsp/bsp.h" #include "os/os_dev.h" @@ -139,6 +140,9 @@ hal_bsp_init(void) (void)rc; + /* Make sure system clocks have started */ + hal_system_clock_start(); + #if MYNEWT_VAL(UART_0) rc = os_dev_create((struct os_dev *) &os_bsp_uart0, "uart0", OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&os_bsp_uart0_cfg); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9d943b7/hw/hal/include/hal/hal_system.h ---------------------------------------------------------------------- diff --git a/hw/hal/include/hal/hal_system.h b/hw/hal/include/hal/hal_system.h index a232496..24436b9 100644 --- a/hw/hal/include/hal/hal_system.h +++ b/hw/hal/include/hal/hal_system.h @@ -51,6 +51,9 @@ enum hal_reset_reason { }; enum hal_reset_reason hal_reset_cause(void); +/* Starts clocks needed by system */ +void hal_system_clock_start(void); + #ifdef __cplusplus } #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9d943b7/hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c b/hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c index 0008995..372142e 100644 --- a/hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c +++ b/hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c @@ -20,7 +20,7 @@ #include <os/os.h> #include "syscfg/syscfg.h" #include <hal/hal_os_tick.h> - +#include <hal/hal_system.h> #include <bsp/cmsis_nvic.h> #include <nrf51.h> #include <nrf51_bitfields.h> @@ -37,6 +37,9 @@ #define OS_TICK_CMPREG 0 #define RTC_FREQ 32768 +#define OS_TICK_TIMER NRF_RTC1 +#define OS_TICK_IRQ RTC1_IRQn + #define RTC_COMPARE_INT_MASK(ccreg) (1UL << ((ccreg) + 16)) @@ -74,7 +77,7 @@ sub24(uint32_t x, uint32_t y) static inline uint32_t nrf51_os_tick_counter(void) { - return (NRF_RTC0->COUNTER); + return (OS_TICK_TIMER->COUNTER); } static inline void @@ -86,7 +89,7 @@ nrf51_os_tick_set_ocmp(uint32_t ocmp) OS_ASSERT_CRITICAL(); while (1) { ocmp &= 0xffffff; - NRF_RTC0->CC[OS_TICK_CMPREG] = ocmp; + OS_TICK_TIMER->CC[OS_TICK_CMPREG] = ocmp; counter = nrf51_os_tick_counter(); /* * From section 19.1.7 "Compare Feature" nRF51 Reference Manual 3.0: @@ -106,7 +109,7 @@ nrf51_os_tick_set_ocmp(uint32_t ocmp) } static void -rtc0_timer_handler(void) +rtc1_timer_handler(void) { int ticks, delta; os_sr_t sr; @@ -123,7 +126,7 @@ rtc0_timer_handler(void) os_time_advance(ticks); /* Clear timer interrupt */ - NRF_RTC0->EVENTS_COMPARE[OS_TICK_CMPREG] = 0; + OS_TICK_TIMER->EVENTS_COMPARE[OS_TICK_CMPREG] = 0; /* Update the time associated with the most recent tick */ lastocmp = (lastocmp + ticks * timer_ticks_per_ostick) & 0xffffff; @@ -160,7 +163,7 @@ os_tick_idle(os_time_t ticks) * Update OS time before anything else when coming out of * the tickless regime. */ - rtc0_timer_handler(); + rtc1_timer_handler(); } } @@ -168,7 +171,6 @@ void os_tick_init(uint32_t os_ticks_per_sec, int prio) { uint32_t ctx; - uint32_t mask; assert(RTC_FREQ % os_ticks_per_sec == 0); @@ -182,74 +184,32 @@ os_tick_init(uint32_t os_ticks_per_sec, int prio) */ nrf51_max_idle_ticks = (1UL << 22) / timer_ticks_per_ostick; - /* Turn on the LFCLK */ - NRF_CLOCK->XTALFREQ = CLOCK_XTALFREQ_XTALFREQ_16MHz; - NRF_CLOCK->TASKS_LFCLKSTOP = 1; - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; -#if MYNEWT_VAL(XTAL_32768) - NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Xtal; - NRF_CLOCK->TASKS_LFCLKSTART = 1; - - /* Wait here till started! */ - mask = CLOCK_LFCLKSTAT_STATE_Msk | CLOCK_LFCLKSTAT_SRC_Xtal; - while (1) { - if (NRF_CLOCK->EVENTS_LFCLKSTARTED) { - if ((NRF_CLOCK->LFCLKSTAT & mask) == mask) { - break; - } - } - } -#endif - -#if MYNEWT_VAL(XTAL_32768_SYNTH) - /* Must turn on HFLCK for synthesized 32768 crystal */ - mask = CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk; - if ((NRF_CLOCK->HFCLKSTAT & mask) != mask) { - NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; - NRF_CLOCK->TASKS_HFCLKSTART = 1; - while (1) { - if ((NRF_CLOCK->EVENTS_HFCLKSTARTED) != 0) { - break; - } - } - } - - NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Synth; - NRF_CLOCK->TASKS_LFCLKSTART = 1; - mask = CLOCK_LFCLKSTAT_STATE_Msk | CLOCK_LFCLKSRC_SRC_Synth; - while (1) { - if (NRF_CLOCK->EVENTS_LFCLKSTARTED) { - if ((NRF_CLOCK->LFCLKSTAT & mask) == mask) { - break; - } - } - } - -#endif + /* Make sure system clocks have started */ + hal_system_clock_start(); /* disable interrupts */ __HAL_DISABLE_INTERRUPTS(ctx); /* Set isr in vector table and enable interrupt */ - NVIC_SetPriority(RTC0_IRQn, prio); - NVIC_SetVector(RTC0_IRQn, (uint32_t)rtc0_timer_handler); - NVIC_EnableIRQ(RTC0_IRQn); + NVIC_SetPriority(OS_TICK_IRQ, prio); + NVIC_SetVector(OS_TICK_IRQ, (uint32_t)rtc1_timer_handler); + NVIC_EnableIRQ(OS_TICK_IRQ); /* * Program the OS_TICK_TIMER to operate at 32KHz and trigger an output * compare interrupt at a rate of 'os_ticks_per_sec'. */ - NRF_RTC0->TASKS_STOP = 1; - NRF_RTC0->TASKS_CLEAR = 1; + OS_TICK_TIMER->TASKS_STOP = 1; + OS_TICK_TIMER->TASKS_CLEAR = 1; - NRF_RTC0->EVTENCLR = 0xffffffff; - NRF_RTC0->INTENCLR = 0xffffffff; - NRF_RTC0->INTENSET = RTC_COMPARE_INT_MASK(OS_TICK_CMPREG); + OS_TICK_TIMER->EVTENCLR = 0xffffffff; + OS_TICK_TIMER->INTENCLR = 0xffffffff; + OS_TICK_TIMER->INTENSET = RTC_COMPARE_INT_MASK(OS_TICK_CMPREG); - NRF_RTC0->EVENTS_COMPARE[OS_TICK_CMPREG] = 0; - NRF_RTC0->CC[OS_TICK_CMPREG] = timer_ticks_per_ostick; + OS_TICK_TIMER->EVENTS_COMPARE[OS_TICK_CMPREG] = 0; + OS_TICK_TIMER->CC[OS_TICK_CMPREG] = timer_ticks_per_ostick; - NRF_RTC0->TASKS_START = 1; + OS_TICK_TIMER->TASKS_START = 1; __HAL_ENABLE_INTERRUPTS(ctx); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a9d943b7/hw/mcu/nordic/nrf51xxx/src/hal_system.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_system.c b/hw/mcu/nordic/nrf51xxx/src/hal_system.c index 62379a7..b5150bb 100644 --- a/hw/mcu/nordic/nrf51xxx/src/hal_system.c +++ b/hw/mcu/nordic/nrf51xxx/src/hal_system.c @@ -18,7 +18,10 @@ */ #include <mcu/cortex_m0.h> +#include "syscfg/syscfg.h" #include "hal/hal_system.h" +#include <nrf51.h> +#include <nrf51_bitfields.h> void hal_system_reset(void) @@ -35,3 +38,63 @@ hal_debugger_connected(void) return 0; } +/** + * hal system clock start + * + * Makes sure the LFCLK and/or HFCLK is started. + */ +void +hal_system_clock_start(void) +{ + uint32_t mask; + +#if MYNEWT_VAL(XTAL_32768) + /* Check if this clock source is already running */ + mask = CLOCK_LFCLKSTAT_STATE_Msk | CLOCK_LFCLKSTAT_SRC_Xtal; + if ((NRF_CLOCK->LFCLKSTAT & mask) != mask) { + NRF_CLOCK->TASKS_LFCLKSTOP = 1; + NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; + NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Xtal; + NRF_CLOCK->TASKS_LFCLKSTART = 1; + + /* Wait here till started! */ + while (1) { + if (NRF_CLOCK->EVENTS_LFCLKSTARTED) { + if ((NRF_CLOCK->LFCLKSTAT & mask) == mask) { + break; + } + } + } + } +#endif + +#if MYNEWT_VAL(XTAL_32768_SYNTH) + /* Must turn on HFLCK for synthesized 32768 crystal */ + mask = CLOCK_LFCLKSTAT_STATE_Msk | CLOCK_LFCLKSRC_SRC_Synth; + if ((NRF_CLOCK->LFCLKSTAT & mask) != mask) { + mask = CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk; + if ((NRF_CLOCK->HFCLKSTAT & mask) != mask) { + NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; + NRF_CLOCK->TASKS_HFCLKSTART = 1; + while (1) { + if ((NRF_CLOCK->EVENTS_HFCLKSTARTED) != 0) { + break; + } + } + } + + NRF_CLOCK->TASKS_LFCLKSTOP = 1; + NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; + NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Synth; + NRF_CLOCK->TASKS_LFCLKSTART = 1; + while (1) { + if (NRF_CLOCK->EVENTS_LFCLKSTARTED) { + mask = CLOCK_LFCLKSTAT_STATE_Msk | CLOCK_LFCLKSRC_SRC_Synth; + if ((NRF_CLOCK->LFCLKSTAT & mask) == mask) { + break; + } + } + } + } +#endif +}
