1 /** 2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 * 15 * Description: Provides systick driver source \n 16 * 17 * History: \n 18 * 2022-08-01, Create file. \n 19 */ 20 #include <stdbool.h> 21 #include "securec.h" 22 #include "interrupt/osal_interrupt.h" 23 24 #include "systick_porting.h" 25 #include "hal_systick.h" 26 #include "systick.h" 27 28 static bool g_systick_hw_inited = false; 29 30 #if defined(CONFIG_SYSTICK_SUPPORT_LPM) 31 static uint64_t g_systick_sleep_compensation_count = 0; 32 static uint64_t g_systick_sleep_suspend_current_count = 0; 33 #endif 34 uapi_systick_init(void)35void uapi_systick_init(void) 36 { 37 uint32_t irq_sts = osal_irq_lock(); 38 if (unlikely(g_systick_hw_inited)) { 39 osal_irq_restore(irq_sts); 40 return; 41 } 42 43 hal_systick_init(); 44 g_systick_hw_inited = true; 45 osal_irq_restore(irq_sts); 46 } 47 uapi_systick_deinit(void)48void uapi_systick_deinit(void) 49 { 50 uint32_t irq_sts = osal_irq_lock(); 51 if (unlikely(!g_systick_hw_inited)) { 52 osal_irq_restore(irq_sts); 53 return; 54 } 55 56 hal_systick_deinit(); 57 g_systick_hw_inited = false; 58 osal_irq_restore(irq_sts); 59 } 60 uapi_systick_count_clear(void)61errcode_t uapi_systick_count_clear(void) 62 { 63 errcode_t ret; 64 uint32_t irq_sts = osal_irq_lock(); 65 if (unlikely(!g_systick_hw_inited)) { 66 osal_irq_restore(irq_sts); 67 return ERRCODE_SYSTICK_NOT_INIT; 68 } 69 70 ret = hal_systick_count_clear(); 71 osal_irq_restore(irq_sts); 72 73 return ret; 74 } 75 uapi_systick_get_count(void)76uint64_t uapi_systick_get_count(void) 77 { 78 uint64_t count = 0; 79 80 uint32_t irq_sts = osal_irq_lock(); 81 if (unlikely(!g_systick_hw_inited)) { 82 osal_irq_restore(irq_sts); 83 return count; 84 } 85 86 count = hal_systick_get_count(); 87 osal_irq_restore(irq_sts); 88 89 #if defined(CONFIG_SYSTICK_SUPPORT_LPM) 90 return count + g_systick_sleep_compensation_count; 91 #else 92 return count; 93 #endif 94 } 95 uapi_systick_get_s(void)96uint64_t uapi_systick_get_s(void) 97 { 98 return convert_count_2_s(uapi_systick_get_count()); 99 } 100 uapi_systick_get_ms(void)101uint64_t uapi_systick_get_ms(void) 102 { 103 return convert_count_2_ms(uapi_systick_get_count()); 104 } 105 uapi_systick_get_us(void)106uint64_t uapi_systick_get_us(void) 107 { 108 return convert_count_2_us(uapi_systick_get_count()); 109 } 110 uapi_systick_delay_count(uint64_t c_delay)111errcode_t uapi_systick_delay_count(uint64_t c_delay) 112 { 113 if (unlikely(!g_systick_hw_inited)) { 114 return ERRCODE_SYSTICK_NOT_INIT; 115 } 116 117 uint64_t current_ticks; 118 uint64_t origin_ticks; 119 120 origin_ticks = uapi_systick_get_count(); 121 for (;;) { 122 current_ticks = uapi_systick_get_count(); 123 if ((current_ticks - origin_ticks) >= c_delay) { 124 break; 125 } 126 } 127 return ERRCODE_SUCC; 128 } 129 uapi_systick_delay_s(uint32_t s_delay)130errcode_t uapi_systick_delay_s(uint32_t s_delay) 131 { 132 if (unlikely(!g_systick_hw_inited)) { 133 return ERRCODE_SYSTICK_NOT_INIT; 134 } 135 136 uapi_systick_delay_count((uint64_t)convert_s_2_count((uint64_t)s_delay)); 137 138 return ERRCODE_SUCC; 139 } 140 uapi_systick_delay_ms(uint32_t m_delay)141errcode_t uapi_systick_delay_ms(uint32_t m_delay) 142 { 143 if (unlikely(!g_systick_hw_inited)) { 144 return ERRCODE_SYSTICK_NOT_INIT; 145 } 146 147 uapi_systick_delay_count((uint64_t)convert_ms_2_count((uint64_t)m_delay)); 148 149 return ERRCODE_SUCC; 150 } 151 uapi_systick_delay_us(uint32_t u_delay)152errcode_t uapi_systick_delay_us(uint32_t u_delay) 153 { 154 if (unlikely(!g_systick_hw_inited)) { 155 return ERRCODE_SYSTICK_NOT_INIT; 156 } 157 158 uapi_systick_delay_count((uint64_t)convert_us_2_count((uint64_t)u_delay)); 159 return ERRCODE_SUCC; 160 } 161 162 #if defined(CONFIG_SYSTICK_SUPPORT_LPM) uapi_systick_suspend(uintptr_t arg)163errcode_t uapi_systick_suspend(uintptr_t arg) 164 { 165 uint64_t sleep_compensation_count = uapi_systick_get_count(); 166 uint32_t irq_sts = osal_irq_lock(); 167 g_systick_sleep_suspend_current_count = sleep_compensation_count; 168 osal_irq_restore(irq_sts); 169 170 if ((uint64_t *)arg != NULL) { 171 *(uint64_t *)arg = sleep_compensation_count; 172 } 173 return ERRCODE_SUCC; 174 } 175 uapi_systick_resume(uintptr_t arg)176errcode_t uapi_systick_resume(uintptr_t arg) 177 { 178 errcode_t ret; 179 uint32_t irq_sts; 180 uint64_t sleep_compensation_count = *(uint64_t *)arg; 181 uapi_systick_deinit(); 182 uapi_systick_init(); 183 ret = uapi_systick_count_clear(); 184 if (ret != ERRCODE_SUCC) { 185 return ret; 186 } 187 188 irq_sts = osal_irq_lock(); 189 g_systick_sleep_compensation_count = g_systick_sleep_suspend_current_count + sleep_compensation_count; 190 osal_irq_restore(irq_sts); 191 192 return ERRCODE_SUCC; 193 } 194 #endif /* CONFIG_SYSTICK_SUPPORT_LPM */