diff --git a/boards/pca10000/include/periph_conf.h b/boards/pca10000/include/periph_conf.h index 6bd5462a0b..90aba936b2 100644 --- a/boards/pca10000/include/periph_conf.h +++ b/boards/pca10000/include/periph_conf.h @@ -15,12 +15,12 @@ * * @author Christian Kühling * @author Timo Ziegler + * @author Hauke Petersen */ #ifndef __PERIPH_CONF_H #define __PERIPH_CONF_H - /** * @name Timer configuration * @{ @@ -53,6 +53,20 @@ #define TIMER_2_IRQ TIMER2_IRQn /** @} */ +/** + * @name Real time counter configuration + * @{ + */ +#define RTT_NUMOF (1U) +#define RTT_IRQ_PRIO 1 + +#define RTT_DEV NRF_RTC0 +#define RTT_IRQ RTC0_IRQn +#define RTT_ISR isr_rtc0 +#define RTT_MAX_VALUE (0xffffff) +#define RTT_FREQUENCY (10) /* in Hz */ +#define RTT_PRESCALER (3275U) /* run with 10 Hz */ +/** @} */ /** * @name UART configuration diff --git a/cpu/nrf51822/periph/rtt.c b/cpu/nrf51822/periph/rtt.c new file mode 100644 index 0000000000..b0203a59f9 --- /dev/null +++ b/cpu/nrf51822/periph/rtt.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2014 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_nrf51822 + * @{ + * + * @file rtt.c + * @brief Real-time timer driver implementation + * + * @author Hauke Petersen + * + * @} + */ + +#include +#include + +#include "cpu.h" +#include "board.h" +#include "sched.h" +#include "thread.h" +#include "periph_conf.h" +#include "periph/rtt.h" + +/* guard file in case no RTC device was specified */ +#if RTT_NUMOF + +/* + * callback and argument for an active alarm + */ +static rtt_alarm_cb_t alarm_cb; +static void *alarm_arg; + +void rtt_init(void) +{ + rtt_poweron(); + + /* configure interrupt */ + NVIC_SetPriority(RTT_IRQ, RTT_IRQ_PRIO); + NVIC_EnableIRQ(RTT_IRQ); + + /* set prescaler */ + RTT_DEV->PRESCALER = RTT_PRESCALER; + + /* enable the low-frequency clock */ + NRF_CLOCK->TASKS_LFCLKSTART = 1; + + /* start the actual RTT thing */ + RTT_DEV->TASKS_START = 1; +} + +uint32_t rtt_get_counter(void) +{ + return RTT_DEV->COUNTER; +} + +void rtt_set_counter(uint32_t counter) +{ + /* not supported for the NRF51822? -> could not find out how to do this */ +} + +void rtt_set_alarm(uint32_t alarm, rtt_alarm_cb_t cb, void *arg) +{ + alarm_cb = cb; + alarm_arg = arg; + RTT_DEV->CC[0] = (alarm & RTT_MAX_VALUE); + RTT_DEV->INTENSET = RTC_INTENSET_COMPARE0_Msk; +} + +uint32_t rtt_get_alarm(void) +{ + return RTT_DEV->CC[0]; +} + +void rtt_clear_alarm(void) +{ + RTT_DEV->INTENCLR = RTC_INTENSET_COMPARE0_Msk; +} + +void rtt_poweron(void) +{ + RTT_DEV->POWER = 1; +} + +void rtt_poweroff(void) +{ + RTT_DEV->POWER = 0; +} + +__attribute__((naked)) void RTT_ISR(void) +{ + ISR_ENTER(); + if (RTT_DEV->EVENTS_COMPARE[0] ==1) { + RTT_DEV->EVENTS_COMPARE[0] = 0; + RTT_DEV->INTENCLR = RTC_INTENSET_COMPARE0_Msk; + alarm_cb(alarm_arg); + } + if (sched_context_switch_request) { + thread_yield(); + } + ISR_EXIT(); +} + +#endif /* RTT_NUMOF */ diff --git a/tests/periph_rtt/Makefile b/tests/periph_rtt/Makefile new file mode 100644 index 0000000000..a719175a62 --- /dev/null +++ b/tests/periph_rtt/Makefile @@ -0,0 +1,10 @@ +export APPLICATION = periph_rtt +include ../Makefile.tests_common + +BOARD_BLACKLIST := chronos mbed_lpc1768 msb-430 msb-430h native qemu-i386 redbee-econotag telosb \ + wsn430-v1_3b wsn430-v1_4 z1 +# all listed boards: no periph_conf.h defined, + +DISABLE_MODULE += auto_init + +include $(RIOTBASE)/Makefile.include diff --git a/tests/periph_rtt/README.md b/tests/periph_rtt/README.md new file mode 100644 index 0000000000..6e093a32cb --- /dev/null +++ b/tests/periph_rtt/README.md @@ -0,0 +1,7 @@ +Expected result +=============== +When everything works as expected, you should see a hello message popping up every 10 seconds. + +Background +========== +Test for the low-level RTT driver. diff --git a/tests/periph_rtt/main.c b/tests/periph_rtt/main.c new file mode 100644 index 0000000000..8dcddadb5f --- /dev/null +++ b/tests/periph_rtt/main.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2014 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 tests + * @{ + * + * @file + * @brief Test for low-level Real Time Timer drivers + * + * This test will initialize the real-time timer and trigger an alarm printing + * 'Hello' every 10 seconds + * + * @author Hauke Petersen + * + * @} + */ + +#include +#include + +#include "cpu.h" +#include "periph_conf.h" +#include "periph/rtt.h" + +/* only compile this test if a RTT device is defined */ +#if RTT_NUMOF + +#define TICKS_TO_WAIT (10 * RTT_FREQUENCY) + +void cb(void *arg) +{ + (void)arg; + uint32_t now; + + now = rtt_get_counter() + TICKS_TO_WAIT; + now = (now > RTT_MAX_VALUE) ? now - RTT_MAX_VALUE : now; + rtt_set_alarm(now, cb, 0); + puts("Hello"); +} + + +int main(void) +{ + puts("\nRIOT RTT low-level driver test"); + puts("This test will display 'Hello' every 10 seconds\n"); + + puts("Initializing the RTT driver"); + rtt_init(); + + puts("Setting initial alarm"); + rtt_set_alarm(TICKS_TO_WAIT, cb, 0); + + puts("Done setting up the RTT, wait for many Hellos"); + return 0; +} + +#else + +int main(void) +{ + puts("\nRIOT RTT low-level driver test"); + puts("There are no RTT devices defined for this board!"); + + return 0; +} + +#endif /* RTT_NUMOF */