1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3  * Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd.
4  */
5 
6 #include "hal_base.h"
7 
8 #ifdef HAL_SYSTICK_MODULE_ENABLED
9 
10 /** @addtogroup RK_HAL_Driver
11  *  @{
12  */
13 
14 /** @addtogroup SYSTICK
15  *  @{
16  */
17 
18 /** @defgroup SYSTICK_How_To_Use How To Use
19  *  @{
20 
21  The SYSTICK driver can be used as follows:
22 
23  Reset SysTick in default setting:
24 
25   - Resgister HAL_SYSTICK_IRQHandler();
26   - Reset HAL_BASE tick frequency value by calling HAL_SetTickFreq() if needed;
27   - Reset SysTick by calling HAL_SYSTICK_Init().
28 
29  Reset SysTick by user:
30 
31  - Resgister HAL_SYSTICK_IRQHandler();
32  - Choose SysTick clock source by calling HAL_SYSTICK_CLKSourceConfig();
33  - Config SysTick reload value by calling HAL_SYSTICK_Config();
34  - Configure the SysTick frequency by calling by calling HAL_SetTickFreq().
35 
36  Reinit SysTick when system core clock and clock source is changed;
37 
38  - Reset core rate by calling CRU module interface;
39  - Update HAL global variable systemCoreClock by calling HAL_UpdateWithNewCoreRate();
40  - Change SysTick clock source by calling HAL_SYSTICK_CLKSourceConfig();
41  - Update SysTick reloader num in default frequency by calling
42     HAL_SYSTICK_Config(rate / (1000 / HAL_GetTickFreq())).
43 
44  @} */
45 
46 /** @defgroup SYSTICK_Private_Definition Private Definition
47  *  @{
48  */
49 /********************* Private MACRO Definition ******************************/
50 #define SYSTICK_INT_PRIORITY 0x0FU
51 
52 /********************* Private Structure Definition **************************/
53 
54 /********************* Private Variable Definition ***************************/
55 
56 /********************* Private Function Definition ***************************/
57 
58 /** @} */
59 /********************* Public Function Definition ****************************/
60 
61 /** @defgroup SYSTICK_Exported_Functions_Group4 Init and DeInit Functions
62  *  @{
63  */
64 
65 /**
66  * @brief  Init SysTick and enable SysTick.
67  * @return HAL_Status: HAL_OK.
68  * Reset SysTick to default setting.
69  */
HAL_SYSTICK_Init(void)70 HAL_Status HAL_SYSTICK_Init(void)
71 {
72     uint32_t ret, rate = SystemCoreClock;
73 
74     ret = HAL_SYSTICK_CLKSourceConfig(HAL_SYSTICK_CLKSRC_EXT);       /* Choose external clock source */
75     if (ret == HAL_OK) {
76         rate = PLL_INPUT_OSC_RATE;
77     }
78 
79     HAL_SYSTICK_Config(rate / (1000 / HAL_GetTickFreq()));        /* Configure the SysTick to have interrupt in TickFreq time basis */
80 
81     /*Configure the SysTick IRQ priority */
82 #ifdef HAL_NVIC_MODULE_ENABLED
83     HAL_NVIC_SetPriority(SysTick_IRQn, SYSTICK_INT_PRIORITY, 0);
84 #endif
85     HAL_SYSTICK_Enable();
86 
87     return HAL_OK;
88 }
89 
90 /** @} */
91 
92 /** @defgroup SYSTICK_Exported_Functions_Group5 Other Functions
93  *  @{
94  */
95 
96 /**
97  * @brief  Config SysTick reload value.
98  * @param  ticksNumb: SysTick reload value.
99  * @return HAL_Status.
100  */
HAL_SYSTICK_Config(uint32_t ticksNumb)101 HAL_Status HAL_SYSTICK_Config(uint32_t ticksNumb)
102 {
103     if ((ticksNumb - 1UL) > SysTick_LOAD_RELOAD_Msk) {
104         return HAL_INVAL;                                             /* Reload value impossible */
105     }
106 
107     SysTick->LOAD = (uint32_t)(ticksNumb - 1UL);                      /* set reload register */
108     NVIC_SetPriority(SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);  /* set Priority for SysTick Interrupt */
109     SysTick->VAL = 0UL;                                               /* Load the SysTick Counter Value */
110 
111     return HAL_OK;
112 }
113 
114 /**
115  * @brief  Config clock source type for SysTick.
116  * @param  clkSource: HAL_SYSTICK_CLKSRC_CORE clock source is from core clk,
117  *                    HAL_SYSTICK_CLKSRC_EXT clock source is from external reference
118  * @return HAL_OK if successful, HAL_INVAL if soc not support.
119  */
HAL_SYSTICK_CLKSourceConfig(eHAL_systickClkSource clkSource)120 HAL_Status HAL_SYSTICK_CLKSourceConfig(eHAL_systickClkSource clkSource)
121 {
122     if (clkSource == HAL_SYSTICK_CLKSRC_CORE) {
123         SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
124     } else {
125         if (SysTick->CALIB & SysTick_CALIB_NOREF_Msk) {
126             return HAL_INVAL;
127         } else {
128             SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
129         }
130     }
131 
132     return HAL_OK;
133 }
134 
135 /**
136  * @brief  System Tick, Is the externalreferance clock enabled as a source clock.
137  * @return HAL_TRUE if external referance clock is enabled
138  */
HAL_SYSTICK_IsExtRefClockEnabled(void)139 HAL_Check HAL_SYSTICK_IsExtRefClockEnabled(void)
140 {
141     if (SysTick->CTRL & SysTick_CTRL_CLKSOURCE_Msk) {
142         return HAL_FALSE;
143     } else {
144         HAL_ASSERT(!(SysTick->CALIB & SysTick_CALIB_NOREF_Msk));
145 
146         return HAL_TRUE;
147     }
148 }
149 
150 /**
151  * @brief  Core internal SysTick IRQ handler
152  * Count plus 1.
153  */
HAL_SYSTICK_IRQHandler(void)154 __WEAK void HAL_SYSTICK_IRQHandler(void)
155 {
156     HAL_IncTick();
157 }
158 
159 /**
160  * @brief  Enable SysTick.
161  * @return HAL_Status.
162  */
HAL_SYSTICK_Enable(void)163 HAL_Status HAL_SYSTICK_Enable(void)
164 {
165     SysTick->CTRL |= (SysTick_CTRL_TICKINT_Msk |
166                       SysTick_CTRL_ENABLE_Msk);                       /* Enable SysTick IRQ and SysTick Timer */
167 
168     return HAL_OK;
169 }
170 
171 /** @} */
172 
173 /** @} */
174 
175 /** @} */
176 
177 #endif /* HAL_SYSTICK_MODULE_ENABLED */
178