| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- /*
- * Copyright (c) 2025, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include "ec_master.h"
- #ifndef CONFIG_EC_TIMESTAMP_CUSTOM
- #if defined(__riscv) || defined(__ICCRISCV__)
- #define READ_CSR(csr_num) ({ uint32_t v; __asm volatile("csrr %0, %1" : "=r"(v) : "i"(csr_num)); v; })
- #define CSR_MCYCLE (0xB00)
- #define CSR_MCYCLEH (0xB80)
- static inline uint64_t riscv_csr_get_core_mcycle(void)
- {
- uint64_t result;
- uint32_t resultl_first = READ_CSR(CSR_MCYCLE);
- uint32_t resulth = READ_CSR(CSR_MCYCLEH);
- uint32_t resultl_second = READ_CSR(CSR_MCYCLE);
- if (resultl_first < resultl_second) {
- result = ((uint64_t)resulth << 32) | resultl_first; /* if MCYCLE didn't roll over, return the value directly */
- } else {
- resulth = READ_CSR(CSR_MCYCLEH);
- result = ((uint64_t)resulth << 32) | resultl_second; /* if MCYCLE rolled over, need to get the MCYCLEH again */
- }
- return result;
- }
- static uint32_t g_clock_time_div;
- void ec_timestamp_init(void)
- {
- g_clock_time_div = ec_get_cpu_frequency() / 1000000;
- uint64_t start_cycle = ec_timestamp_get_time_ns();
- ec_osal_msleep(10);
- EC_ASSERT_MSG((ec_timestamp_get_time_ns() - start_cycle) >= 9000000, "Timestamp timer not running\n");
- }
- EC_FAST_CODE_SECTION uint64_t ec_timestamp_get_time_ns(void)
- {
- return (riscv_csr_get_core_mcycle() * 1000) / g_clock_time_div;
- }
- #elif defined(__arm__) || defined(__ICCARM__) || defined(__ARMCC_VERSION)
- #define DWT_CR (*(volatile uint32_t *)0xE0001000)
- #define DWT_CYCCNT (*(volatile uint32_t *)0xE0001004)
- #define DEM_CR (*(volatile uint32_t *)0xE000EDFC)
- #define DEM_CR_TRCENA (1 << 24)
- #define DWT_CR_CYCCNTENA (1 << 0)
- static volatile uint32_t g_dwt_high = 0;
- static volatile uint32_t g_dwt_last_low = 0;
- static uint32_t g_clock_time_div;
- static inline uint64_t arm_dwt_get_cycle_count(void)
- {
- uint32_t current_low = DWT_CYCCNT;
- if (current_low < g_dwt_last_low) {
- g_dwt_high++;
- }
- g_dwt_last_low = current_low;
- return ((uint64_t)g_dwt_high << 32) | current_low;
- }
- void ec_timestamp_init(void)
- {
- g_clock_time_div = ec_get_cpu_frequency() / 1000000;
- g_dwt_high = 0;
- g_dwt_last_low = 0;
- DEM_CR |= (uint32_t)DEM_CR_TRCENA;
- DWT_CYCCNT = (uint32_t)0u;
- g_dwt_last_low = 0;
- DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;
- uint64_t start_cycle = ec_timestamp_get_time_ns();
- ec_osal_msleep(10);
- EC_ASSERT_MSG((ec_timestamp_get_time_ns() - start_cycle) >= 9000000, "Timestamp timer not running\n");
- }
- EC_FAST_CODE_SECTION uint64_t ec_timestamp_get_time_ns(void)
- {
- return (arm_dwt_get_cycle_count() * 1000) / g_clock_time_div;
- }
- #else
- #error "Unsupported architecture"
- #endif
- #endif
|