diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-03-24 20:14:27 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-03-24 20:31:22 +0100 |
commit | 34c6151754f2e9ed03e66058047fa2c627a60f3f (patch) | |
tree | 3cdfdb6774334cc4164c9d57d0e09996156c3380 /c/src/lib/libbsp/arm/shared/armv7m | |
parent | ARM: New define ARMV7M_EXCEPTION_PRIORITY_LOWEST (diff) | |
download | rtems-34c6151754f2e9ed03e66058047fa2c627a60f3f.tar.bz2 |
bsps: Shared ARMv7-M clock driver
Diffstat (limited to 'c/src/lib/libbsp/arm/shared/armv7m')
-rw-r--r-- | c/src/lib/libbsp/arm/shared/armv7m/clock/armv7m-clock-config.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/shared/armv7m/clock/armv7m-clock-config.c b/c/src/lib/libbsp/arm/shared/armv7m/clock/armv7m-clock-config.c new file mode 100644 index 0000000000..82fefcee9f --- /dev/null +++ b/c/src/lib/libbsp/arm/shared/armv7m/clock/armv7m-clock-config.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2011-2012 Sebastian Huber. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include <rtems.h> +#include <rtems/score/armv7m.h> + +#include <bsp.h> + +#ifdef ARM_MULTILIB_ARCH_V7M + +/* This is defined in clockdrv_shell.h */ +rtems_isr Clock_isr(rtems_vector_number vector); + +#define _ARMV7M_Systick_get_factor(freq) \ + ((1000000000ULL << 32) / (freq)) + +#ifdef BSP_ARMV7M_SYSTICK_FREQUENCY + #define _ARMV7M_Systick_factor \ + _ARMV7M_Systick_get_factor(BSP_ARMV7M_SYSTICK_FREQUENCY) +#else + static uint64_t _ARMV7M_Systick_factor; +#endif + +static void _ARMV7M_Systick_at_tick(void) +{ + volatile ARMV7M_Systick *systick = _ARMV7M_Systick; + + /* Clear COUNTFLAG */ + systick->csr; +} + +static void _ARMV7M_Systick_handler(void) +{ + _ARMV7M_Interrupt_service_enter(); + Clock_isr(ARMV7M_VECTOR_SYSTICK); + _ARMV7M_Interrupt_service_leave(); +} + +static void _ARMV7M_Systick_handler_install(void) +{ + _ARMV7M_Set_exception_priority( + ARMV7M_VECTOR_SYSTICK, + ARMV7M_EXCEPTION_PRIORITY_LOWEST + ); + _ARMV7M_Set_exception_handler( + ARMV7M_VECTOR_SYSTICK, + _ARMV7M_Systick_handler + ); +} + +static void _ARMV7M_Systick_initialize(void) +{ + volatile ARMV7M_Systick *systick = _ARMV7M_Systick; + #ifdef BSP_ARMV7M_SYSTICK_FREQUENCY + uint64_t freq = BSP_ARMV7M_SYSTICK_FREQUENCY; + #else + uint64_t freq = ARMV7M_SYSTICK_CALIB_TENMS_GET(systick->calib) * 100ULL; + #endif + uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); + uint64_t interval = (freq * us_per_tick) / 1000000ULL; + + #ifndef BSP_ARMV7M_SYSTICK_FREQUENCY + _ARMV7M_Systick_factor = _ARMV7M_Systick_get_factor(freq); + #endif + + systick->rvr = (uint32_t) interval; + systick->cvr = 0; + systick->csr = ARMV7M_SYSTICK_CSR_ENABLE + | ARMV7M_SYSTICK_CSR_TICKINT + | ARMV7M_SYSTICK_CSR_CLKSOURCE; +} + +static void _ARMV7M_Systick_cleanup(void) +{ + volatile ARMV7M_Systick *systick = _ARMV7M_Systick; + + systick->csr = 0; +} + +static uint32_t _ARMV7M_Systick_nanoseconds_since_last_tick(void) +{ + volatile ARMV7M_Systick *systick = _ARMV7M_Systick; + volatile ARMV7M_SCB *scb = _ARMV7M_SCB; + uint32_t rvr = systick->rvr; + uint32_t c = rvr - systick->cvr; + + if ((scb->icsr & ARMV7M_SCB_ICSR_PENDSTSET) != 0) { + c = rvr - systick->cvr + rvr; + } + + return (uint32_t) ((c * _ARMV7M_Systick_factor) >> 32); +} + +#define Clock_driver_support_at_tick() \ + _ARMV7M_Systick_at_tick() + +#define Clock_driver_support_initialize_hardware() \ + _ARMV7M_Systick_initialize() + +#define Clock_driver_support_install_isr(isr, old_isr) \ + do { \ + _ARMV7M_Systick_handler_install(); \ + old_isr = NULL; \ + } while (0) + +#define Clock_driver_support_shutdown_hardware() \ + _ARMV7M_Systick_cleanup() + +#define Clock_driver_nanoseconds_since_last_tick \ + _ARMV7M_Systick_nanoseconds_since_last_tick + +/* Include shared source clock driver code */ +#include "../../../../shared/clockdrv_shell.h" + +#endif /* ARM_MULTILIB_ARCH_V7M */ |