[nrf][clock] use nrfx lib clock driver
Using Nordic's nrfx driver for the clock control peripheral since it address a handful of errata and abstracts some differences in the nrf52 family of parts.
This commit is contained in:
3
external/platform/nrfx/rules.mk
vendored
3
external/platform/nrfx/rules.mk
vendored
@@ -3,11 +3,12 @@ LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
MODULE := $(LOCAL_DIR)
|
||||
|
||||
MODULE_SRCS := \
|
||||
$(LOCAL_DIR)/drivers/src/nrfx_clock.c \
|
||||
$(LOCAL_DIR)/drivers/src/nrfx_twi.c \
|
||||
$(LOCAL_DIR)/drivers/src/nrfx_twi_twim.c \
|
||||
$(LOCAL_DIR)/drivers/src/nrfx_twim.c \
|
||||
$(LOCAL_DIR)/drivers/src/nrfx_usbd.c \
|
||||
$(LOCAL_DIR)/mdk/system_nrf52.c \
|
||||
$(LOCAL_DIR)/mdk/system_nrf52840.c \
|
||||
$(LOCAL_DIR)/soc/nrfx_atomic.c \
|
||||
|
||||
# The nrfx library doesn't follow the typical lk include directory layout
|
||||
|
||||
91
platform/nrf52xxx/clock.c
Normal file
91
platform/nrf52xxx/clock.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Eric Holland
|
||||
*
|
||||
* Use of this source code is governed by a MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <lk/err.h>
|
||||
#include <kernel/event.h>
|
||||
#include <nrfx.h>
|
||||
#include <nrfx_clock.h>
|
||||
#include <hal/nrf_clock.h>
|
||||
#include <platform/clock.h>
|
||||
|
||||
|
||||
event_t hf_clk_evt = EVENT_INITIAL_VALUE(hf_clk_evt, false, 0);
|
||||
event_t lf_clk_evt = EVENT_INITIAL_VALUE(lf_clk_evt, false, 0);
|
||||
|
||||
void nrf52_POWER_CLOCK_IRQ(void) {
|
||||
arm_cm_irq_entry();
|
||||
nrfx_clock_irq_handler();
|
||||
arm_cm_irq_exit(true);
|
||||
}
|
||||
|
||||
// Handler runs in interrupt context
|
||||
void nrf52_clock_handler(nrfx_clock_evt_type_t event) {
|
||||
switch (event) {
|
||||
case NRFX_CLOCK_EVT_HFCLK_STARTED :
|
||||
event_signal(&hf_clk_evt, false);
|
||||
break;
|
||||
case NRFX_CLOCK_EVT_LFCLK_STARTED :
|
||||
event_signal(&lf_clk_evt, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
status_t nrf52_clock_init(void) {
|
||||
status_t status = nrfx_clock_init(nrf52_clock_handler);
|
||||
if (status == NO_ERROR) {
|
||||
nrfx_clock_enable();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t nrf52_clock_hf_use_xtal_source(void) {
|
||||
// Check if already running on hfclk xtal
|
||||
if (nrfx_clock_hfclk_is_running()) {
|
||||
return NO_ERROR;
|
||||
}
|
||||
event_unsignal(&hf_clk_evt);
|
||||
nrfx_clock_hfclk_start();
|
||||
if (event_wait_timeout(&hf_clk_evt, 100) != NO_ERROR) {
|
||||
dprintf(CRITICAL, "Timeout waiting for hf source\n");
|
||||
return ERR_TIMED_OUT;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
// Switch to using the internal 64MHz oscillator for HF clock
|
||||
void nrf52_clock_hf_use_internal_source(void) {
|
||||
//The clock controller will automatically switch to the internal
|
||||
// oscillator as the source when the external xtal is stopped.
|
||||
// this nrfx function is poorly named as it does not stop the hf clock
|
||||
// but only stops the external xtal oscillator.
|
||||
nrfx_clock_hfclk_stop();
|
||||
}
|
||||
|
||||
status_t nrf52_clock_lfclk_enable(nrf_clock_lfclk_t src) {
|
||||
if (nrfx_clock_lfclk_is_running()) {
|
||||
nrf_clock_lfclk_t current_src = nrf_clock_lf_actv_src_get(NRF_CLOCK);
|
||||
if (current_src == src) {
|
||||
//Already running on the requested source, do nothing.
|
||||
return NO_ERROR;
|
||||
}
|
||||
// If we make it here, it is running, but not right source, so shut it down to change
|
||||
nrfx_clock_lfclk_stop();
|
||||
}
|
||||
nrf_clock_lf_src_set(NRF_CLOCK, src);
|
||||
event_unsignal(&lf_clk_evt);
|
||||
nrfx_clock_lfclk_start();
|
||||
if (event_wait_timeout(&lf_clk_evt, 100) != NO_ERROR) {
|
||||
dprintf(CRITICAL, "Timeout waiting for lf clock start\n");
|
||||
return ERR_TIMED_OUT;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
21
platform/nrf52xxx/include/platform/clock.h
Normal file
21
platform/nrf52xxx/include/platform/clock.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Eric Holland
|
||||
*
|
||||
* Use of this source code is governed by a MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <nrfx.h>
|
||||
#include <nrfx_clock.h>
|
||||
#include <hal/nrf_clock.h>
|
||||
|
||||
|
||||
// Must be called before other functions can be used.
|
||||
status_t nrf52_clock_init(void);
|
||||
|
||||
status_t nrf52_clock_hf_use_xtal_source(void);
|
||||
void nrf52_clock_hf_use_internal_source(void);
|
||||
|
||||
status_t nrf52_clock_lfclk_enable(nrf_clock_lfclk_t src);
|
||||
@@ -11,17 +11,29 @@
|
||||
#include <dev/i2c.h>
|
||||
#include <dev/uart.h>
|
||||
#include <platform.h>
|
||||
#include <platform/init.h>
|
||||
#include <platform/clock.h>
|
||||
#include <nrfx.h>
|
||||
#include <mdk/system_nrf52.h>
|
||||
#include <nrfx_clock.h>
|
||||
|
||||
void platform_early_init(void) {
|
||||
// Crank up the clock before initing timers.
|
||||
|
||||
SystemInit();
|
||||
// Initialize the clock control peripheral
|
||||
nrf52_clock_init();
|
||||
|
||||
arm_cm_systick_init(32768);
|
||||
}
|
||||
|
||||
void platform_init(void) {
|
||||
|
||||
dprintf(SPEW, "Nordic nrf52xxx platform for lk...\n");
|
||||
|
||||
char *variant = (char *)&NRF_FICR->FICR_INFO.VARIANT;
|
||||
dprintf(SPEW, "Part Number - %x-%c%c%c%c\n", NRF_FICR->FICR_INFO.PART,
|
||||
variant[3], variant[2], variant[1], variant[0]);
|
||||
dprintf(SPEW, "\tRam: %dk\n", NRF_FICR->FICR_INFO.RAM);
|
||||
dprintf(SPEW, "\tFlash: %d pages of %d bytes each (%dk bytes total)\n", \
|
||||
NRF_FICR->CODESIZE, NRF_FICR->CODEPAGESIZE, \
|
||||
(NRF_FICR->CODESIZE * NRF_FICR->CODEPAGESIZE)>>10);
|
||||
@@ -32,6 +44,7 @@ void platform_init(void) {
|
||||
(NRF_FICR->DEVICEADDR[0] >> 16) & 0xFF, \
|
||||
(NRF_FICR->DEVICEADDR[0] >> 8) & 0xFF, \
|
||||
(NRF_FICR->DEVICEADDR[0] >> 0) & 0xFF);
|
||||
|
||||
// Note: i2c_init will only instantiate an i2c device if proper defines
|
||||
// are set. See comments at top of i2c_master.c for more info.
|
||||
i2c_init();
|
||||
|
||||
@@ -37,10 +37,13 @@ GLOBAL_DEFINES += \
|
||||
MEMSIZE=$(MEMSIZE)
|
||||
|
||||
# Other important defines
|
||||
#GLOBAL_DEFINES += \
|
||||
GLOBAL_DEFINES += \
|
||||
NRFX_CLOCK_ENABLED=1 \
|
||||
|
||||
# NRFX_ENABLE_LOGGING=1 \
|
||||
|
||||
MODULE_SRCS += \
|
||||
$(LOCAL_DIR)/clock.c \
|
||||
$(LOCAL_DIR)/i2c_master.c \
|
||||
$(LOCAL_DIR)/init.c \
|
||||
$(LOCAL_DIR)/debug.c \
|
||||
|
||||
@@ -10,8 +10,12 @@
|
||||
#include <platform.h>
|
||||
#include <nrfx.h>
|
||||
#include <platform/timer.h>
|
||||
#include <platform/clock.h>
|
||||
#include <nrfx_clock.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// TODO - integrate nrfx rtc driver instead of direct register manipulation here.
|
||||
|
||||
//base counter is total number of clock cycles elapsed
|
||||
static volatile uint64_t base_counter = 0;
|
||||
|
||||
@@ -27,15 +31,12 @@ typedef enum handler_return (*platform_timer_callback)(void *arg, lk_time_t now)
|
||||
|
||||
status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, lk_time_t interval) {
|
||||
ASSERT(clock_rate > 0);
|
||||
|
||||
ASSERT(nrfx_clock_lfclk_is_running());
|
||||
cb = callback;
|
||||
cb_args = arg;
|
||||
|
||||
cycles_per_tick = clock_rate * interval / 1000 ;
|
||||
|
||||
NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos;
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1;
|
||||
|
||||
NRF_RTC1->CC[0] = 0x00ffffff & (base_counter + cycles_per_tick);
|
||||
|
||||
NRF_RTC1->PRESCALER = 0;
|
||||
@@ -95,6 +96,9 @@ void nrf52_RTC1_IRQ(void) {
|
||||
}
|
||||
|
||||
void arm_cm_systick_init(uint32_t hz) {
|
||||
ASSERT(hz == 32768);
|
||||
clock_rate = hz;
|
||||
//Enable the LF xtal oscillator
|
||||
nrf52_clock_lfclk_enable(NRF_CLOCK_LFCLK_Xtal);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
#include <lk/debug.h>
|
||||
#include <lk/compiler.h>
|
||||
#include <arch/arm/cm.h>
|
||||
#include <lib/cbuf.h>
|
||||
#include <platform/nrf52.h>
|
||||
#include <target/debugconfig.h>
|
||||
|
||||
/* un-overridden irq handler */
|
||||
void nrf52_dummy_irq(void) {
|
||||
|
||||
@@ -9,9 +9,20 @@
|
||||
#define __TARGET_GPIOCONFIG_H
|
||||
|
||||
#define GPIO_LED1 13
|
||||
#define LED1_ON gpio_set(GPIO_LED1,0)
|
||||
#define LED1_OFF gpio_set(GPIO_LED1,1)
|
||||
|
||||
#define GPIO_LED2 14
|
||||
#define LED2_ON gpio_set(GPIO_LED2,0)
|
||||
#define LED2_OFF gpio_set(GPIO_LED2,1)
|
||||
|
||||
#define GPIO_LED3 15
|
||||
#define LED3_ON gpio_set(GPIO_LED3,0)
|
||||
#define LED3_OFF gpio_set(GPIO_LED3,1)
|
||||
|
||||
#define GPIO_LED4 16
|
||||
#define LED4_ON gpio_set(GPIO_LED4,0)
|
||||
#define LED4_OFF gpio_set(GPIO_LED4,1)
|
||||
|
||||
#define UART0_TX_PIN 6
|
||||
#define UART0_RX_PIN 8
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <lk/compiler.h>
|
||||
#include <nrfx_usbd.h>
|
||||
#include <dev/gpio.h>
|
||||
#include <platform/nrf52.h>
|
||||
#include <platform/init.h>
|
||||
#include <target/gpioconfig.h>
|
||||
|
||||
void target_early_init(void) {
|
||||
@@ -20,10 +20,10 @@ void target_early_init(void) {
|
||||
gpio_config(GPIO_LED3, GPIO_OUTPUT);
|
||||
gpio_config(GPIO_LED4, GPIO_OUTPUT);
|
||||
|
||||
gpio_set(GPIO_LED1,0);
|
||||
gpio_set(GPIO_LED2,0);
|
||||
gpio_set(GPIO_LED3,0);
|
||||
gpio_set(GPIO_LED4,0);
|
||||
LED1_OFF;
|
||||
LED2_OFF;
|
||||
LED3_OFF;
|
||||
LED4_OFF;
|
||||
|
||||
nrf52_debug_early_init();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user