drivers: timer: nRF SoC Series RTC system clock implementation
The nRF5x series SoCs do not implement systick, hence we disable CORTEX_M_SYSTICK. Instead, use nRF SoC Series NRF_RTC1 for system clock interfaces. The kernel system clock interface is implemented using the low power real time counter NRF_RTC1. NRF_RTC0 is used by the BLE controller. In addition, cleanup nRF5x series defconfig to be consistent. Jira: ZEP-742 Jira: ZEP-1308 Jira: ZEP-1315 Change-id: I0f6cc1836fe0820a65f2cbb02cf5ae7e9eb92e1d Signed-off-by: Vinayak Chettimada <vinayak.kariappa.chettimada@nordicsemi.no> Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no> Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
92c5f91413
commit
a100ada866
|
@ -26,6 +26,9 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC
|
|||
int
|
||||
default 32768
|
||||
|
||||
config SYS_POWER_MANAGEMENT
|
||||
default y
|
||||
|
||||
config SRAM_BASE_ADDRESS
|
||||
default 0x20000000
|
||||
|
||||
|
|
|
@ -24,6 +24,5 @@ config SOC_SERIES_NRF51X
|
|||
select XIP
|
||||
select HAS_CMSIS
|
||||
select HAS_NORDIC_MDK
|
||||
select CPU_HAS_SYSTICK
|
||||
help
|
||||
Enable support for NRF51 MCU series
|
||||
|
|
|
@ -22,19 +22,11 @@ config SOC
|
|||
string
|
||||
default nRF52832
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
int
|
||||
default 64000000
|
||||
|
||||
config SRAM_SIZE
|
||||
default 64
|
||||
|
||||
config FLASH_SIZE
|
||||
default 512
|
||||
|
||||
config NUM_IRQS
|
||||
int
|
||||
default 39
|
||||
|
||||
endif # SOC_NRF52832
|
||||
|
||||
|
|
|
@ -22,12 +22,23 @@ source "arch/arm/soc/nordic_nrf5/nrf52/Kconfig.defconfig.nrf52*"
|
|||
config SOC_SERIES
|
||||
default nrf52
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
int
|
||||
default 32768
|
||||
|
||||
config SYS_POWER_MANAGEMENT
|
||||
default y
|
||||
|
||||
config SRAM_BASE_ADDRESS
|
||||
default 0x20000000
|
||||
|
||||
config FLASH_BASE_ADDRESS
|
||||
default 0x00000000
|
||||
|
||||
config NUM_IRQS
|
||||
int
|
||||
default 39
|
||||
|
||||
config NUM_IRQ_PRIO_BITS
|
||||
int
|
||||
default 3
|
||||
|
|
|
@ -24,6 +24,5 @@ config SOC_SERIES_NRF52X
|
|||
select XIP
|
||||
select HAS_CMSIS
|
||||
select HAS_NORDIC_MDK
|
||||
select CPU_HAS_SYSTICK
|
||||
help
|
||||
Enable support for NRF52 MCU series
|
||||
|
|
|
@ -149,6 +149,16 @@ config ALTERA_AVALON_TIMER
|
|||
with Nios II and possibly other Altera soft CPUs. It provides the
|
||||
standard "system clock driver" interfaces.
|
||||
|
||||
config NRF_RTC_TIMER
|
||||
bool "nRF Real Time Counter (NRF_RTC1) Timer"
|
||||
default y
|
||||
depends on SOC_FAMILY_NRF5
|
||||
select NANOKERNEL_TICKLESS_IDLE_SUPPORTED
|
||||
help
|
||||
This module implements a kernel device driver for the nRF Real Time
|
||||
Counter NRF_RTC1 and provides the standard "system clock driver"
|
||||
interfaces.
|
||||
|
||||
config SYSTEM_CLOCK_DISABLE
|
||||
bool "API to disable system clock"
|
||||
default n
|
||||
|
|
|
@ -4,6 +4,7 @@ obj-$(CONFIG_HPET_TIMER) += hpet.o
|
|||
obj-$(CONFIG_LOAPIC_TIMER) += loapic_timer.o
|
||||
obj-$(CONFIG_ARCV2_TIMER) += arcv2_timer0.o
|
||||
obj-$(CONFIG_ALTERA_AVALON_TIMER) += altera_avalon_timer.o
|
||||
obj-$(CONFIG_NRF_RTC_TIMER) += nrf_rtc_timer.o
|
||||
|
||||
_CORTEX_M_SYSTICK_AND_GDB_INFO_yy = y
|
||||
obj-$(CONFIG_CORTEX_M_SYSTICK) += cortex_m_systick.o
|
||||
|
|
125
drivers/timer/nrf_rtc_timer.c
Normal file
125
drivers/timer/nrf_rtc_timer.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Nordic Semiconductor ASA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <soc.h>
|
||||
#include <clock_control.h>
|
||||
#include <system_timer.h>
|
||||
#include <drivers/clock_control/nrf5_clock_control.h>
|
||||
|
||||
#define RTC_TICKS ((uint32_t)(((((uint64_t)1000000UL / \
|
||||
CONFIG_SYS_CLOCK_TICKS_PER_SEC) * \
|
||||
1000000000UL) / 30517578125UL)) & 0x00FFFFFF)
|
||||
|
||||
extern int64_t _sys_clock_tick_count;
|
||||
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
extern int32_t _sys_idle_elapsed_ticks;
|
||||
|
||||
void _timer_idle_enter(int32_t ticks)
|
||||
{
|
||||
/* restrict ticks to max supported by RTC */
|
||||
if ((ticks < 0) || (ticks > (0x00FFFFFF / RTC_TICKS))) {
|
||||
ticks = 0x00FFFFFF / RTC_TICKS;
|
||||
}
|
||||
|
||||
/* setup next RTC compare event by ticks amount */
|
||||
NRF_RTC1->CC[0] = ((_sys_clock_tick_count + ticks) * RTC_TICKS) &
|
||||
0x00FFFFFF;
|
||||
|
||||
/* TODO: check if CC is set to stale value */
|
||||
}
|
||||
|
||||
void _timer_idle_exit(void)
|
||||
{
|
||||
uint32_t elapsed_ticks;
|
||||
|
||||
/* update with elapsed ticks from h/w */
|
||||
elapsed_ticks = ((NRF_RTC1->COUNTER -
|
||||
(_sys_clock_tick_count * RTC_TICKS)) /
|
||||
RTC_TICKS) & 0x00FFFFFF;
|
||||
|
||||
/* setup next RTC compare event by 1 tick */
|
||||
NRF_RTC1->CC[0] = ((_sys_clock_tick_count + elapsed_ticks + 1) *
|
||||
RTC_TICKS) & 0x00FFFFFF;
|
||||
|
||||
/* TODO: check if CC is set to stale value */
|
||||
}
|
||||
#endif /* CONFIG_TICKLESS_IDLE */
|
||||
|
||||
static void rtc1_nrf5_isr(void *arg)
|
||||
{
|
||||
ARG_UNUSED(arg);
|
||||
|
||||
if (NRF_RTC1->EVENTS_COMPARE[0]) {
|
||||
NRF_RTC1->EVENTS_COMPARE[0] = 0;
|
||||
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
/* update with elapsed ticks from h/w */
|
||||
_sys_idle_elapsed_ticks = ((NRF_RTC1->COUNTER -
|
||||
(_sys_clock_tick_count *
|
||||
RTC_TICKS)) / RTC_TICKS) &
|
||||
0x00FFFFFF;
|
||||
#endif
|
||||
|
||||
/* setup next RTC compare event */
|
||||
NRF_RTC1->CC[0] = ((_sys_clock_tick_count +
|
||||
_sys_idle_elapsed_ticks + 1) * RTC_TICKS)
|
||||
& 0x00FFFFFF;
|
||||
|
||||
/* TODO: check if CC is set to stale value */
|
||||
|
||||
_sys_clock_tick_announce();
|
||||
}
|
||||
}
|
||||
|
||||
int _sys_clock_driver_init(struct device *device)
|
||||
{
|
||||
struct device *clock;
|
||||
int retval;
|
||||
|
||||
ARG_UNUSED(device);
|
||||
|
||||
clock = device_get_binding(CONFIG_CLOCK_CONTROL_NRF5_K32SRC_DRV_NAME);
|
||||
if (!clock) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
clock_control_on(clock, (void *)CLOCK_CONTROL_NRF5_K32SRC);
|
||||
|
||||
/* TODO: replace with counter driver to access RTC */
|
||||
NRF_RTC1->PRESCALER = 0;
|
||||
NRF_RTC1->CC[0] = RTC_TICKS;
|
||||
NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
|
||||
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;
|
||||
|
||||
IRQ_CONNECT(NRF5_IRQ_RTC1_IRQn, 1, rtc1_nrf5_isr, 0, 0);
|
||||
irq_enable(NRF5_IRQ_RTC1_IRQn);
|
||||
|
||||
NRF_RTC1->TASKS_START = 1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint32_t sys_cycle_get_32(void)
|
||||
{
|
||||
uint32_t elapsed_cycles;
|
||||
|
||||
elapsed_cycles = (NRF_RTC1->COUNTER -
|
||||
(_sys_clock_tick_count * RTC_TICKS)) & 0x00FFFFFF;
|
||||
|
||||
return (_sys_clock_tick_count * sys_clock_hw_cycles_per_tick) +
|
||||
elapsed_cycles;
|
||||
}
|
Loading…
Reference in a new issue