diff options
Diffstat (limited to 'platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h')
-rw-r--r-- | platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h | 411 |
1 files changed, 411 insertions, 0 deletions
diff --git a/platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h b/platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h new file mode 100644 index 0000000000..d14d2f79e2 --- /dev/null +++ b/platform/ext/target/arm/mps3/an547/native_drivers/systimer_armv8-m_drv.h @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2019 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 systimer_armv8-m_drv.h + * + * \brief Driver for Armv8-M System Timer + * + * This System Timer is based on the 64-bit Armv8-M System Counter, + * generating the physical count for System Timer. + * + * Main features: + * - Disabling the timer doesn't stop counting, but it disables timer output + * signal, what might be a power saving option. + * - 1 interrupt signal, can be triggered by the 2 modes below + * Modes: + * 1. Normal mode + * For clearing the interrupt generated by normal mode, the Timer + * should be disabled. + * Views + * 1.1. 64-bit up-counting Compare view + * As soon as the physical up-counter reaches the set + * compare value, the interrupt status will be asserted. + * \ref systimer_armv8_m_set_compare_value + * \ref systimer_armv8_m_get_compare_value + + * 1.2. 32-bit down-counting Timer view + * As soon as the down-counter timer reaches zero, + * the interrupt status will be asserted. + * Setting the down-counter timer value, sets the compare + * register by + * compare register = current counter + timer value + * \ref systimer_armv8_m_set_timer_value + * \ref systimer_armv8_m_get_timer_value + * + * 2. Auto-Increment mode + * - The auto-increment feature allows generation of Timer + * interrupt at regular intervals without the need for + * reprogramming the Timer after each interrupt and re-enabling + * the timer logic. + * - Auto-increment is working as a 64-bit up-counter, which is set + * by the 32-bit reload register. + * - If auto-increment mode is enabled, none of the normal modes' + * views can assert interrupt. * + * \ref systimer_armv8_m_get_autoinc_value + * \ref systimer_armv8_m_set_autoinc_reload + * \ref systimer_armv8_m_enable_autoinc + * \ref systimer_armv8_m_disable_autoinc + * \ref systimer_armv8_m_is_autoinc_enabled + * \ref systimer_armv8_m_clear_autoinc_interrupt + * \ref systimer_armv8_m_is_autoinc_implemented + * + */ + +#ifndef __SYSTIMER_ARMV8_M_DRV_H__ +#define __SYSTIMER_ARMV8_M_DRV_H__ + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define SYSTIMER_ARMV8_M_REGISTER_BIT_WIDTH 32u + /*!< Armv8-M System Timer registers bit width */ + +/** + * \brief Armv8-M System Timer device configuration structure + */ +struct systimer_armv8_m_dev_cfg_t { + const uint32_t base; + /*!< Armv8-M System Timer device base address */ + uint32_t default_freq_hz; + /*!< Default reported frequency in Hz */ +}; + +/** + * \brief Armv8-M System Timer device data structure + */ +struct systimer_armv8_m_dev_data_t { + bool is_initialized; +}; + +/** + * \brief Armv8-M System Timer device structure + */ +struct systimer_armv8_m_dev_t { + const struct systimer_armv8_m_dev_cfg_t* const cfg; + /*!< Armv8-M System Timer configuration structure */ + struct systimer_armv8_m_dev_data_t* const data; + /*!< Armv8-M System Timer data structure */ +}; + +/** + * \brief Initializes timer to a known default state, which is: + * - timer is enabled + * - interrupt is disabled + * - auto-increment is disabled + * - reported timer frequency is set to default + * Init should be called prior to any other process and + * it's the caller's responsibility to follow proper call order. + * More than one call results fall through. + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_init(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Uninitializes timer to a known default state, which is: + * - timer is disabled + * - interrupt is disabled + * - auto-increment is disabled + * Init should be called prior to any other process and + * it's the caller's responsibility to follow proper call order. + * More than one call results fall through. + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_uninit(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Reads 64-bit physical counter value + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return 64-bit counter value + * + * \note This function doesn't check if dev is NULL. + */ +uint64_t systimer_armv8_m_get_counter_value( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Sets 64-bit compare value + * As soon as the physical up-counter reaches this value, the interrupt + * condition will be asserted \ref systimer_armv8_m_is_interrupt_asserted + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * \param[in] value 64-bit compare value + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_set_compare_value( + struct systimer_armv8_m_dev_t* dev, + uint64_t value); + +/** + * \brief Reads 64-bit compare value + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return 64-bit compare value + * + * \note This function doesn't check if dev is NULL. + */ +uint64_t systimer_armv8_m_get_compare_value( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Sets frequency register in Hz + * Hardware does not interpret the value of the register, so it's only + * for software can discover the frequency of the system counter. + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * \param[in] value frequency in Hz + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_set_counter_freq( + struct systimer_armv8_m_dev_t* dev, + uint32_t value); + +/** + * \brief Reads frequency register in Hz + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return frequency in Hz + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t systimer_armv8_m_get_counter_freq( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Sets 32-bit down-counter timer value + * 'Down-counter timer set' automatically sets the compare register by + * compare register = current counter + this timer value + * + * As soon as the timer value reaches zero, the interrupt condition will + * be asserted \ref systimer_armv8_m_is_interrupt_asserted. + * Reaching zero doesn't stop the timer. + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * \param[in] value 32-bit timer value + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_set_timer_value(struct systimer_armv8_m_dev_t* dev, + uint32_t value); + +/** + * \brief Reads down-counter timer value + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return 32-bit timer value + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t systimer_armv8_m_get_timer_value( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Enables timer + * Enables timer output signal and interrupt status assertion + * \ref systimer_armv8_m_is_interrupt_asserted + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_enable_timer(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Disables timer + * Disables timer output signal. Interrupt status will be unknown + * \ref systimer_armv8_m_is_interrupt_asserted + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_disable_timer(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Polls timer enable status + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool systimer_armv8_m_is_timer_enabled( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Enables timer interrupt + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_enable_interrupt( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Disables timer interrupt + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_disable_interrupt( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Polls timer interrupt enable status + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool systimer_armv8_m_is_interrupt_enabled( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Polls timer interrupt status + * It's asserted if + * 1. Auto-Inc is disabled and counter reaches compare value + * OR + * 2. Auto-Inc is enabled and counter reaches auto-inc value + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return true if asserted, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool systimer_armv8_m_is_interrupt_asserted( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Reads auto-increment value + * This value is automatically calculated by + * auto-inc = current counter + auto-inc reload + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return 64-bit auto-increment value + * + * \note This function doesn't check if dev is NULL. + */ +uint64_t systimer_armv8_m_get_autoinc_value( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Sets 32-bit auto-increment reload value + * Auto-Inc value is automatically calculated by adding this reload value + * to the current counter. + * If the counter reaches auto-inc value, interrupt status is asserted + * and auto-inc value is automatically set by current reload. + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * \param[in] value 32-bit reload value + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_set_autoinc_reload( + struct systimer_armv8_m_dev_t* dev, + uint32_t value); + +/** + * \brief Reads auto-increment reload value + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return 32-bit auto-increment reload value + * + * \note This function doesn't check if dev is NULL. + */ +uint32_t systimer_armv8_m_get_autoinc_reload( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Enables auto-increment mode + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_enable_autoinc(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Disables auto-increment mode + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_disable_autoinc(struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Polls auto-increment enable status + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return true if enabled, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool systimer_armv8_m_is_autoinc_enabled( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Clears auto-increment mode interrupt flag + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \note This function doesn't check if dev is NULL. + */ +void systimer_armv8_m_clear_autoinc_interrupt( + struct systimer_armv8_m_dev_t* dev); + +/** + * \brief Polls auto-increment implementation status + * + * \param[in] dev Timer device struct \ref systimer_armv8_m_dev_t + * + * \return true if implemented, false otherwise + * + * \note This function doesn't check if dev is NULL. + */ +bool systimer_armv8_m_is_autoinc_implemented( + struct systimer_armv8_m_dev_t* dev); + +#ifdef __cplusplus +} +#endif +#endif /* __SYSTIMER_ARMV8_M_DRV_H__ */ |