]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c
Rename RISC-V_RV32_SiFive_HiFive1-FreedomStudio directory to RISC-V_RV32_SiFive_HiFiv...
[freertos] / FreeRTOS / Demo / RISC-V_RV32_SiFive_HiFive1_FreedomStudio / freedom-metal / src / drivers / sifive_wdog0.c
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c
deleted file mode 100644 (file)
index 1a6cf36..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/* Copyright 2019 SiFive, Inc */
-/* SPDX-License-Identifier: Apache-2.0 */
-
-#include <metal/machine/platform.h>
-
-#ifdef METAL_SIFIVE_WDOG0
-
-#include <metal/drivers/sifive_uart0.h>
-#include <metal/machine.h>
-
-#include <limits.h>
-
-/* WDOGCFG */
-#define METAL_WDOGCFG_SCALE_MASK 7
-#define METAL_WDOGCFG_RSTEN (1 << 8)
-#define METAL_WDOGCFG_ZEROCMP (1 << 9)
-#define METAL_WDOGCFG_ENALWAYS (1 << 12)
-#define METAL_WDOGCFG_COREAWAKE (1 << 13)
-#define METAL_WDOGCFG_IP (1 << 28)
-
-/* WDOGCMP */
-#define METAL_WDOGCMP_MASK 0xFFFF
-
-#define WDOG_REG(base, offset)   (((unsigned long)base + offset))
-#define WDOG_REGB(base, offset)  (__METAL_ACCESS_ONCE((__metal_io_u8  *)WDOG_REG(base, offset)))
-#define WDOG_REGW(base, offset)  (__METAL_ACCESS_ONCE((__metal_io_u32 *)WDOG_REG(base, offset)))
-
-/* All writes to watchdog registers must be precedded by a write of
- * a magic number to WDOGKEY */
-#define WDOG_UNLOCK(base) (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGKEY) = METAL_SIFIVE_WDOG0_MAGIC_KEY)
-
-/* Unlock the watchdog and then perform a register access */
-#define WDOG_UNLOCK_REGW(base, offset) \
-    WDOG_UNLOCK(base);\
-    WDOG_REGW(base, offset)
-
-int __metal_driver_sifive_wdog0_feed(const struct metal_watchdog *const wdog)
-{
-    const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog);
-
-    WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGFEED) = METAL_SIFIVE_WDOG0_MAGIC_FOOD;
-
-    return 0;
-}
-
-long int __metal_driver_sifive_wdog0_get_rate(const struct metal_watchdog *const wdog)
-{
-    const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog);
-    const struct metal_clock *const clock = __metal_driver_sifive_wdog0_clock(wdog);
-    
-    const long int clock_rate = metal_clock_get_rate_hz(clock);
-
-    if (clock_rate == 0)
-        return -1;
-
-    const unsigned int scale = (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) & METAL_WDOGCFG_SCALE_MASK);
-
-    return clock_rate / (1 << scale);
-}
-
-long int __metal_driver_sifive_wdog0_set_rate(const struct metal_watchdog *const wdog, const long int rate)
-{
-    const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog);
-    const struct metal_clock *const clock = __metal_driver_sifive_wdog0_clock(wdog);
-    
-    const long int clock_rate = metal_clock_get_rate_hz(clock);
-
-    if (rate >= clock_rate) {
-        /* We can't scale the rate above the driving clock. Clear the scale
-         * field and return the driving clock rate */
-        WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_SCALE_MASK);
-        return clock_rate;
-    }
-
-    /* Look for the closest scale value */
-    long min_diff = LONG_MAX;
-    unsigned int min_scale = 0;
-    for (int i = 0; i < METAL_WDOGCFG_SCALE_MASK; i++) {
-        const long int new_rate = clock_rate / (1 << i);
-
-        long int diff = rate - new_rate;
-        if (diff < 0)
-            diff *= -1;
-
-        if (diff < min_diff) {
-            min_diff = diff;
-            min_scale = i;
-        }
-    }
-
-    WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_SCALE_MASK);
-    WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= (METAL_WDOGCFG_SCALE_MASK & min_scale);
-
-    return clock_rate / (1 << min_scale);
-}
-
-long int __metal_driver_sifive_wdog0_get_timeout(const struct metal_watchdog *const wdog)
-{
-    const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog);
-
-    return (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP) & METAL_WDOGCMP_MASK);
-}
-
-long int __metal_driver_sifive_wdog0_set_timeout(const struct metal_watchdog *const wdog, const long int timeout)
-{
-    const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog);
-
-    /* Cap the timeout at the max value */
-    const long int set_timeout = timeout > METAL_WDOGCMP_MASK ? METAL_WDOGCMP_MASK : timeout;
-
-    /* If we edit the timeout value in-place by masking the compare value to 0 and
-     * then writing it, we cause a spurious interrupt because the compare value
-     * is temporarily 0. Instead, read the value into a local variable, modify it
-     * there, and then write the whole register back */
-    uint32_t wdogcmp = WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP);
-
-    wdogcmp &= ~(METAL_WDOGCMP_MASK);
-    wdogcmp |= set_timeout;
-
-    WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP) = wdogcmp;
-
-    return set_timeout;
-}
-
-int __metal_driver_sifive_wdog0_set_result(const struct metal_watchdog *const wdog,
-                                           const enum metal_watchdog_result result)
-{
-    const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog);
-
-    /* Turn off reset enable and counter reset */
-    WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_RSTEN | METAL_WDOGCFG_ZEROCMP);
-
-    switch (result) {
-    default:
-    case METAL_WATCHDOG_NO_RESULT:
-        break;
-    case METAL_WATCHDOG_INTERRUPT:
-        /* Reset counter to zero after match */
-        WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_ZEROCMP;
-        break;
-    case METAL_WATCHDOG_FULL_RESET:
-        WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_RSTEN;
-        break;
-    }
-
-    return 0;
-}
-
-int __metal_driver_sifive_wdog0_run(const struct metal_watchdog *const wdog,
-                                    const enum metal_watchdog_run_option option)
-{
-    const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog);
-
-    WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_ENALWAYS | METAL_WDOGCFG_COREAWAKE);
-
-    switch (option) {
-    default:
-    case METAL_WATCHDOG_STOP:
-        break;
-    case METAL_WATCHDOG_RUN_ALWAYS:
-        /* Feed the watchdog before starting to reset counter */
-        __metal_driver_sifive_wdog0_feed(wdog);
-
-        WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_ENALWAYS;
-        break;
-    case METAL_WATCHDOG_RUN_AWAKE:
-        /* Feed the watchdog before starting to reset counter */
-        __metal_driver_sifive_wdog0_feed(wdog);
-
-        WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_COREAWAKE;
-        break;
-    }
-
-    return 0;
-}
-
-struct metal_interrupt *__metal_driver_sifive_wdog0_get_interrupt(const struct metal_watchdog *const wdog)
-{
-    return __metal_driver_sifive_wdog0_interrupt_parent(wdog);
-}
-
-int __metal_driver_sifive_wdog0_get_interrupt_id(const struct metal_watchdog *const wdog)
-{
-    return __metal_driver_sifive_wdog0_interrupt_line(wdog);
-}
-
-int __metal_driver_sifive_wdog0_clear_interrupt(const struct metal_watchdog *const wdog)
-{
-    const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog);
-
-    /* Clear the interrupt pending bit */
-    WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_IP);
-
-    return 0;
-}
-
-__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_wdog0) = {
-    .watchdog.feed = __metal_driver_sifive_wdog0_feed,
-    .watchdog.get_rate = __metal_driver_sifive_wdog0_get_rate,
-    .watchdog.set_rate = __metal_driver_sifive_wdog0_set_rate,
-    .watchdog.get_timeout = __metal_driver_sifive_wdog0_get_timeout,
-    .watchdog.set_timeout = __metal_driver_sifive_wdog0_set_timeout,
-    .watchdog.set_result = __metal_driver_sifive_wdog0_set_result,
-    .watchdog.run = __metal_driver_sifive_wdog0_run,
-    .watchdog.get_interrupt = __metal_driver_sifive_wdog0_get_interrupt,
-    .watchdog.get_interrupt_id = __metal_driver_sifive_wdog0_get_interrupt_id,
-    .watchdog.clear_interrupt = __metal_driver_sifive_wdog0_clear_interrupt,
-};
-
-#endif /* METAL_SIFIVE_WDOG0 */
-
-typedef int no_empty_translation_units;
-