1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #6851 from haukepetersen/opt_nrf_clkinit

cpu/nrf5x: unified clock initialization code
This commit is contained in:
Hauke Petersen 2017-04-05 21:31:33 +02:00 committed by GitHub
commit 469acf7db8
16 changed files with 209 additions and 55 deletions

View File

@ -27,16 +27,19 @@
#endif #endif
/** /**
* @name Clock configuration * @name Clock configuration
* *
* @note: the radio will not work with the internal RC oscillator! * @note The radio will not work with the internal RC oscillator!
* *
* @{ * @{
*/ */
#define CLOCK_CORECLOCK (16000000U) /* fixed for all NRF51822 */ #define CLOCK_CORECLOCK (16000000U) /* fixed for all nRF51822 */
#define CLOCK_CRYSTAL (16U) /* set to 0: internal RC oscillator #define CLOCK_HFCLK (16U) /* set to 0: internal RC oscillator
16: 16MHz crystal 16: 16MHz crystal
32: 32MHz crystal */ 32: 32MHz crystal */
#define CLOCK_LFCLK (1) /* set to 0: internal RC oscillator
* 1: 32.768 kHz crystal
* 2: derived from HFCLK */
/** @} */ /** @} */
/** /**

View File

@ -32,10 +32,13 @@ extern "C" {
* *
* @{ * @{
*/ */
#define CLOCK_CORECLOCK (16000000U) /* fixed for all NRF51822 */ #define CLOCK_CORECLOCK (16000000U) /* fixed for all nRF51822 */
#define CLOCK_CRYSTAL (16U) /* set to 0: internal RC oscillator #define CLOCK_HFCLK (16U) /* set to 0: internal RC oscillator
16: 16MHz crystal 16: 16MHz crystal
32: 32MHz crystal */ 32: 32MHz crystal */
#define CLOCK_LFCLK (0) /* set to 0: internal RC oscillator
* 1: 32.768 kHz crystal
* 2: derived from HFCLK */
/** @} */ /** @} */
/** /**

View File

@ -32,10 +32,13 @@ extern "C" {
* *
* @{ * @{
*/ */
#define CLOCK_CORECLOCK (16000000U) /* fixed for all NRF51822 */ #define CLOCK_CORECLOCK (16000000U) /* fixed for all nRF51822 */
#define CLOCK_CRYSTAL (16U) /* set to 0: internal RC oscillator #define CLOCK_HFCLK (16U) /* set to 0: internal RC oscillator
16: 16MHz crystal 16: 16MHz crystal
32: 32MHz crystal */ 32: 32MHz crystal */
#define CLOCK_LFCLK (0) /* set to 0: internal RC oscillator
* 1: 32.768 kHz crystal
* 2: derived from HFCLK */
/** @} */ /** @} */
/** /**

View File

@ -26,16 +26,19 @@ extern "C" {
#endif #endif
/** /**
* @name Clock configuration * @name Clock configuration
* *
* @note: the radio will not work with the internal RC oscillator! * @note The radio will not work with the internal RC oscillator!
* *
* @{ * @{
*/ */
#define CLOCK_CORECLOCK (16000000U) /* fixed for all NRF51822 */ #define CLOCK_CORECLOCK (16000000U) /* fixed for all nRF51822 */
#define CLOCK_CRYSTAL (16U) /* set to 0: internal RC oscillator #define CLOCK_HFCLK (16U) /* set to 0: internal RC oscillator
16: 16MHz crystal 16: 16MHz crystal
32: 32MHz crystal */ 32: 32MHz crystal */
#define CLOCK_LFCLK (1) /* set to 0: internal RC oscillator
* 1: 32.768 kHz crystal
* 2: derived from HFCLK */
/** @} */ /** @} */
/** /**

View File

@ -33,9 +33,12 @@ extern "C" {
* *
* @{ * @{
*/ */
#define CLOCK_CORECLOCK (64000000U) /* fixed for all NRF52832 */ #define CLOCK_CORECLOCK (64000000U) /* fixed for all nRF52832 */
#define CLOCK_CRYSTAL (32U) /* set to 0: internal RC oscillator #define CLOCK_HFCLK (32U) /* set to 0: internal RC oscillator
32: 32MHz crystal */ * 32: 32MHz crystal */
#define CLOCK_LFCLK (1) /* set to 0: internal RC oscillator
* 1: 32.768 kHz crystal
* 2: derived from HFCLK */
/** @} */ /** @} */
/** /**

View File

@ -33,9 +33,12 @@ extern "C" {
* *
* @{ * @{
*/ */
#define CLOCK_CORECLOCK (64000000U) /* fixed for all NRF52832 */ #define CLOCK_CORECLOCK (64000000U) /* fixed for all nRF52832 */
#define CLOCK_CRYSTAL (32U) /* set to 0: internal RC oscillator #define CLOCK_HFCLK (32U) /* set to 0: internal RC oscillator
32: 32MHz crystal */ * 32: 32MHz crystal */
#define CLOCK_LFCLK (1) /* set to 0: internal RC oscillator
* 1: 32.768 kHz crystal
* 2: derived from HFCLK */
/** @} */ /** @} */
/** /**

View File

@ -29,16 +29,19 @@ extern "C" {
#endif #endif
/** /**
* @name Clock configuration * @name Clock configuration
* *
* @note: the radio will not work with the internal RC oscillator! * @note The radio will not work with the internal RC oscillator!
* *
* @{ * @{
*/ */
#define CLOCK_CORECLOCK (16000000U) /* fixed for all NRF51822 */ #define CLOCK_CORECLOCK (16000000U) /* fixed for all nRF51822 */
#define CLOCK_CRYSTAL (16U) /* set to 0: internal RC oscillator #define CLOCK_HFCLK (16U) /* set to 0: internal RC oscillator
16: 16MHz crystal 16: 16MHz crystal
32: 32MHz crystal */ 32: 32MHz crystal */
#define CLOCK_LFCLK (1) /* set to 0: internal RC oscillator
* 1: 32.768 kHz crystal
* 2: derived from HFCLK */
/** @} */ /** @} */
/** /**

View File

@ -28,16 +28,19 @@ extern "C" {
#endif #endif
/** /**
* @name Clock configuration * @name Clock configuration
* *
* @note: the radio will not work with the internal RC oscillator! * @note The radio will not work with the internal RC oscillator!
* *
* @{ * @{
*/ */
#define CLOCK_CORECLOCK (16000000U) /* fixed for all NRF51822 */ #define CLOCK_CORECLOCK (16000000U) /* fixed for all nRF51822 */
#define CLOCK_CRYSTAL (16U) /* set to 0: internal RC oscillator #define CLOCK_HFCLK (16U) /* set to 0: internal RC oscillator
16: 16MHz crystal 16: 16MHz crystal
32: 32MHz crystal */ 32: 32MHz crystal */
#define CLOCK_LFCLK (0) /* set to 0: internal RC oscillator
* 1: 32.768 kHz crystal
* 2: derived from HFCLK */
/** @} */ /** @} */
/** /**

View File

@ -28,16 +28,19 @@ extern "C" {
#endif #endif
/** /**
* @name Clock configuration * @name Clock configuration
* *
* @note: the radio will not work with the internal RC oscillator! * @note The radio will not work with the internal RC oscillator!
* *
* @{ * @{
*/ */
#define CLOCK_CORECLOCK (16000000U) /* fixed for all NRF51822 */ #define CLOCK_CORECLOCK (16000000U) /* fixed for all nRF51822 */
#define CLOCK_CRYSTAL (16U) /* set to 0: internal RC oscillator #define CLOCK_HFCLK (16U) /* set to 0: internal RC oscillator
16: 16MHz crystal 16: 16MHz crystal
32: 32MHz crystal */ 32: 32MHz crystal */
#define CLOCK_LFCLK (0) /* set to 0: internal RC oscillator
* 1: 32.768 kHz crystal
* 2: derived from HFCLK */
/** @} */ /** @} */
/** /**

View File

@ -26,16 +26,19 @@ extern "C" {
#endif #endif
/** /**
* @name Clock configuration * @name Clock configuration
* *
* @note: the radio will not work with the internal RC oscillator! * @note The radio will not work with the internal RC oscillator!
* *
* @{ * @{
*/ */
#define CLOCK_CORECLOCK (16000000U) /* fixed for all NRF51822 */ #define CLOCK_CORECLOCK (16000000U) /* fixed for all nRF51822 */
#define CLOCK_CRYSTAL (16U) /* set to 0: internal RC oscillator #define CLOCK_HFCLK (16U) /* set to 0: internal RC oscillator
16: 16MHz crystal 16: 16MHz crystal
32: 32MHz crystal */ 32: 32MHz crystal */
#define CLOCK_LFCLK (0) /* set to 0: internal RC oscillator
* 1: 32.768 kHz crystal
* 2: derived from HFCLK */
/** @} */ /** @} */
/** /**

View File

@ -18,6 +18,7 @@
*/ */
#include "cpu.h" #include "cpu.h"
#include "nrf_clock.h"
#include "periph_conf.h" #include "periph_conf.h"
#include "periph/init.h" #include "periph/init.h"
@ -28,18 +29,8 @@ void cpu_init(void)
{ {
/* initialize the Cortex-M core */ /* initialize the Cortex-M core */
cortexm_init(); cortexm_init();
/* set the correct clock source for HFCLK */ /* setup the HF clock */
#if CLOCK_CRYSTAL == 32 clock_init_hf();
NRF_CLOCK->XTALFREQ = CLOCK_XTALFREQ_XTALFREQ_32MHz;
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {}
#elif CLOCK_CRYSTAL == 16
NRF_CLOCK->XTALFREQ = CLOCK_XTALFREQ_XTALFREQ_16MHz;
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {}
#endif
/* trigger static peripheral initialization */ /* trigger static peripheral initialization */
periph_init(); periph_init();
} }

View File

@ -23,6 +23,7 @@
#define DONT_OVERRIDE_NVIC #define DONT_OVERRIDE_NVIC
#include "cpu.h" #include "cpu.h"
#include "nrf_clock.h"
#include "periph_conf.h" #include "periph_conf.h"
#include "periph/init.h" #include "periph/init.h"
@ -60,15 +61,8 @@ void cpu_init(void)
NRF_CLOCK->EVENTS_CTTO = 0; NRF_CLOCK->EVENTS_CTTO = 0;
} }
/* set the correct clock source for HFCLK */ /* initialize hf clock */
#if (CLOCK_CRYSTAL == 32) clock_init_hf();
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
#endif
/* softdevice needs to be enabled from ISR context */ /* softdevice needs to be enabled from ISR context */
#ifdef SOFTDEVICE_PRESENT #ifdef SOFTDEVICE_PRESENT

View File

@ -1,3 +1,4 @@
MODULE = cpu_common
DIRS = periph DIRS = periph
# build one of the radio drivers, if enabled # build one of the radio drivers, if enabled

View File

@ -8,5 +8,8 @@ USEMODULE += periph_common
# include nrf5x common periph drivers # include nrf5x common periph drivers
USEMODULE += nrf5x_common_periph USEMODULE += nrf5x_common_periph
# link common cpu code
USEMODULE += cpu_common
# export the common include directory # export the common include directory
export INCLUDES += -I$(RIOTCPU)/nrf5x_common/include export INCLUDES += -I$(RIOTCPU)/nrf5x_common/include

83
cpu/nrf5x_common/clock.c Normal file
View File

@ -0,0 +1,83 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_nrf5x_common
* @{
*
* @file
* @brief Clock initialization code
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @}
*/
#include "cpu.h"
#include "periph_conf.h"
/* make sure both clocks are configured */
#ifndef CLOCK_HFCLK
#error "Clock init: CLOCK_HFCLK is not defined by your board!"
#endif
#ifndef CLOCK_LFCLK
#error "Clock init: CLOCK_LFCLK is not defined by your board!"
#endif
void clock_init_hf(void)
{
/* for the nRF51 we can chose the XTAL frequency */
#ifdef CPU_FAM_NRF51
#if (CLOCK_HFCLK == 32)
NRF_CLOCK->XTALFREQ = CLOCK_XTALFREQ_XTALFREQ_32MHz;
#elif (CLOCK_HFCLK == 16)
NRF_CLOCK->XTALFREQ = CLOCK_XTALFREQ_XTALFREQ_16MHz;
#endif
#endif
#if CLOCK_HFCLK
/* start the HF clock */
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {}
#endif
}
void clock_start_lf(void)
{
/* abort if LF clock is already running */
if (NRF_CLOCK->LFCLKSTAT & CLOCK_LFCLKSTAT_STATE_Msk) {
return;
}
#if (CLOCK_LFCLK == 0)
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC);
#elif (CLOCK_LFCLK == 1)
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal);
#elif (CLOCK_LFCLK == 2)
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Synth);
#else
#error "LFCLK init: CLOCK_LFCLK has invalid value"
#endif
/* enable LF clock */
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {}
/* calibrate the RC LF clock if applicable */
#if (CLOCK_HFCLK && (CLOCK_LFCLK == 0))
NRF_CLOCK->EVENTS_DONE = 0;
NRF_CLOCK->TASKS_CAL = 1;
while (NRF_CLOCK->EVENTS_DONE == 0) {}
#endif
}
void clock_stop_lf(void)
{
NRF_CLOCK->TASKS_LFCLKSTOP = 1;
while (NRF_CLOCK->LFCLKSTAT & CLOCK_LFCLKSTAT_STATE_Msk) {}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_nrf5x_common
* @{
*
* @file
* @brief nRF5x shared functions for configuration the system clocks
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef NRF_CLOCK_H
#define NRF_CLOCK_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize the high frequency clock (HFCLK) as configured in the
* board's periph_conf.h
*/
void clock_init_hf(void);
/**
* @brief Start the low frequency clock (LFCLK) as configured in the board's
* periph_conf.
*
* Calling this function while the LFCLK is already running will have no effect.
*/
void clock_start_lf(void);
/**
* @brief Stop the low frequency clock (LFCLK)
*
* @note Be sure that no module is using the LFCLK before you shut it down!
*/
void clock_stop_lf(void);
#ifdef __cplusplus
}
#endif
#endif /* NRF_CLOCK_H */
/** @} */