aboutsummaryrefslogtreecommitdiff
path: root/platform/ext/target/arm/mps2/an519/native_drivers/timer_cmsdk/timer_cmsdk.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ext/target/arm/mps2/an519/native_drivers/timer_cmsdk/timer_cmsdk.c')
-rw-r--r--platform/ext/target/arm/mps2/an519/native_drivers/timer_cmsdk/timer_cmsdk.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/platform/ext/target/arm/mps2/an519/native_drivers/timer_cmsdk/timer_cmsdk.c b/platform/ext/target/arm/mps2/an519/native_drivers/timer_cmsdk/timer_cmsdk.c
new file mode 100644
index 0000000000..1037f2da04
--- /dev/null
+++ b/platform/ext/target/arm/mps2/an519/native_drivers/timer_cmsdk/timer_cmsdk.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2016-2017 ARM Limited
+ *
+ * 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.
+ */
+
+/**
+ * \file timer_cmsdk.c
+ * \brief Generic driver for CMSDK APB Timers.
+ * The timer is a 32-bit down-counter with the following features:
+ * - optional programmable external clock source
+ * - programmable interrupt source, triggered if counter reaches 0
+ * - automatic reload if counter reaches 0
+ */
+
+#include "timer_cmsdk.h"
+
+/** Setter bit manipulation macro */
+#define SET_BIT(WORD, BIT_INDEX) ((WORD) |= (1U << (BIT_INDEX)))
+/** Clearing bit manipulation macro */
+#define CLR_BIT(WORD, BIT_INDEX) ((WORD) &= ~(1U << (BIT_INDEX)))
+/** Getter bit manipulation macro */
+#define GET_BIT(WORD, BIT_INDEX) (bool)(((WORD) & (1U << (BIT_INDEX))))
+
+/**
+ * \brief Timer register map structure
+ *
+ */
+struct cmsdk_timer_reg_map_t {
+ volatile uint32_t ctrl; /* Offset: 0x000 (R/W) control register */
+ volatile uint32_t value; /* Offset: 0x004 (R/W) current value register */
+ volatile uint32_t reload; /* Offset: 0x008 (R/W) reload value register */
+ union {
+ volatile uint32_t intstatus; /* Offset: 0x00C (R/ ) interrupt
+ * status register */
+ volatile uint32_t intclear; /* Offset: 0x00C ( /W) interrupt
+ * clear register */
+ }intreg;
+};
+
+/**
+ * \brief CTRL register bit definitions
+ *
+ */
+enum ctrl_reg_bits_t{
+ CTRL_REG_ENUM_ENABLE_INDEX = 0,
+ CTRL_REG_ENUM_EXTERNAL_INPUT_ENABLE_INDEX = 1,
+ CTRL_REG_ENUM_EXTERNAL_INPUT_CLOCK_INDEX = 2,
+ CTRL_REG_ENUM_IRQ_ENABLE_INDEX = 3
+};
+
+/**
+ * \brief INTSTATUS/INTCLEAR register bit definitions
+ *
+ */
+enum interrupt_reg_bits_t{
+ INTERRUPT_REG_ENUM_STATUS_AND_CLEAR_INDEX = 0
+};
+
+void cmsdk_timer_init(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+
+ if (dev->data->is_initialized == 0) {
+ register_map->ctrl = 0;
+ register_map->reload = CMSDK_TIMER_DEFAULT_RELOAD;
+ dev->data->is_initialized = 1;
+ }
+}
+
+bool cmsdk_timer_is_initialized(const struct cmsdk_timer_dev_t* dev)
+{
+ return dev->data->is_initialized;
+}
+
+void cmsdk_timer_enable_external_input(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ SET_BIT(register_map->ctrl, CTRL_REG_ENUM_EXTERNAL_INPUT_ENABLE_INDEX);
+}
+
+void cmsdk_timer_disable_external_input(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ CLR_BIT(register_map->ctrl, CTRL_REG_ENUM_EXTERNAL_INPUT_ENABLE_INDEX);
+}
+
+bool cmsdk_timer_is_external_input_enabled(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ return GET_BIT(register_map->ctrl,
+ CTRL_REG_ENUM_EXTERNAL_INPUT_ENABLE_INDEX);
+}
+
+void cmsdk_timer_set_clock_to_internal(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ CLR_BIT(register_map->ctrl, CTRL_REG_ENUM_EXTERNAL_INPUT_CLOCK_INDEX);
+}
+
+void cmsdk_timer_set_clock_to_external(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ SET_BIT(register_map->ctrl, CTRL_REG_ENUM_EXTERNAL_INPUT_CLOCK_INDEX);
+}
+
+bool cmsdk_timer_is_clock_external(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ return GET_BIT(register_map->ctrl,
+ CTRL_REG_ENUM_EXTERNAL_INPUT_CLOCK_INDEX);
+}
+
+void cmsdk_timer_enable(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ SET_BIT(register_map->ctrl, CTRL_REG_ENUM_ENABLE_INDEX);
+}
+
+void cmsdk_timer_disable(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ CLR_BIT(register_map->ctrl, CTRL_REG_ENUM_ENABLE_INDEX);
+}
+
+bool cmsdk_timer_is_enabled(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ return GET_BIT(register_map->ctrl, CTRL_REG_ENUM_ENABLE_INDEX);
+}
+
+void cmsdk_timer_enable_interrupt(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ SET_BIT(register_map->ctrl, CTRL_REG_ENUM_IRQ_ENABLE_INDEX);
+}
+
+void cmsdk_timer_disable_interrupt(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ CLR_BIT(register_map->ctrl, CTRL_REG_ENUM_IRQ_ENABLE_INDEX);
+}
+
+bool cmsdk_timer_is_interrupt_enabled(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ return GET_BIT(register_map->ctrl, CTRL_REG_ENUM_IRQ_ENABLE_INDEX);
+}
+
+bool cmsdk_timer_is_interrupt_active(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ return GET_BIT(register_map->intreg.intstatus,
+ INTERRUPT_REG_ENUM_STATUS_AND_CLEAR_INDEX);
+}
+
+void cmsdk_timer_clear_interrupt(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ SET_BIT(register_map->intreg.intclear,
+ INTERRUPT_REG_ENUM_STATUS_AND_CLEAR_INDEX);
+}
+
+uint32_t cmsdk_timer_get_current_value(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ return register_map->value;
+}
+
+void cmsdk_timer_set_reload_value(const struct cmsdk_timer_dev_t* dev,
+ uint32_t reload)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ register_map->reload = reload;
+}
+
+void cmsdk_timer_reset(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ register_map->value = register_map->reload;
+}
+
+uint32_t cmsdk_timer_get_reload_value(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ return register_map->reload;
+}
+
+uint32_t cmsdk_timer_get_elapsed_value(const struct cmsdk_timer_dev_t* dev)
+{
+ struct cmsdk_timer_reg_map_t* register_map =
+ (struct cmsdk_timer_reg_map_t*)dev->cfg->base;
+ return register_map->reload - register_map->value;
+}