• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2019 Nuclei Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 #ifndef __CORE_FEATURE_TIMER_H__
19 #define __CORE_FEATURE_TIMER_H__
20 /*!
21  * @file     core_feature_timer.h
22  * @brief    System Timer feature API header file for Nuclei N/NX Core
23  */
24 /*
25  * System Timer Feature Configuration Macro:
26  * 1. __SYSTIMER_PRESENT:  Define whether Private System Timer is present or not.
27  *   * 0: Not present
28  *   * 1: Present
29  * 2. __SYSTIMER_BASEADDR:  Define the base address of the System Timer.
30  */
31 #ifdef __cplusplus
32  extern "C" {
33 #endif
34 
35 #if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1)
36 /**
37  * \defgroup NMSIS_Core_SysTimer_Registers     Register Define and Type Definitions Of System Timer
38  * \ingroup NMSIS_Core_Registers
39  * \brief   Type definitions and defines for system timer registers.
40  *
41  * @{
42  */
43 /**
44  * \brief  Structure type to access the System Timer (SysTimer).
45  * \details
46  * Structure definition to access the system timer(SysTimer).
47  * \remarks
48  * - MSFTRST register is introduced in Nuclei N Core version 1.3(\ref __NUCLEI_N_REV >= 0x0103)
49  * - MSTOP register is renamed to MTIMECTL register in Nuclei N Core version 1.4(\ref __NUCLEI_N_REV >= 0x0104)
50  * - CMPCLREN and CLKSRC bit in MTIMECTL register is introduced in Nuclei N Core version 1.4(\ref __NUCLEI_N_REV >= 0x0104)
51  */
52 typedef struct {
53     __IOM uint64_t MTIMER;                  /*!< Offset: 0x000 (R/W)  System Timer current value 64bits Register */
54     __IOM uint64_t MTIMERCMP;               /*!< Offset: 0x008 (R/W)  System Timer compare Value 64bits Register */
55     __IOM uint32_t RESERVED0[0x3F8];        /*!< Offset: 0x010 - 0xFEC Reserved */
56     __IOM uint32_t MSFTRST;                 /*!< Offset: 0xFF0 (R/W)  System Timer Software Core Reset Register */
57     __IOM uint32_t RESERVED1;               /*!< Offset: 0xFF4 Reserved */
58     __IOM uint32_t MTIMECTL;                /*!< Offset: 0xFF8 (R/W)  System Timer Control Register, previously MSTOP register */
59     __IOM uint32_t MSIP;                    /*!< Offset: 0xFFC (R/W)  System Timer SW interrupt Register */
60 } SysTimer_Type;
61 
62 /* Timer Control / Status Register Definitions */
63 #define SysTimer_MTIMECTL_TIMESTOP_Pos      0U                                          /*!< SysTick Timer MTIMECTL: TIMESTOP bit Position */
64 #define SysTimer_MTIMECTL_TIMESTOP_Msk      (1UL << SysTimer_MTIMECTL_TIMESTOP_Pos)     /*!< SysTick Timer MTIMECTL: TIMESTOP Mask */
65 #define SysTimer_MTIMECTL_CMPCLREN_Pos      1U                                          /*!< SysTick Timer MTIMECTL: CMPCLREN bit Position */
66 #define SysTimer_MTIMECTL_CMPCLREN_Msk      (1UL << SysTimer_MTIMECTL_CMPCLREN_Pos)     /*!< SysTick Timer MTIMECTL: CMPCLREN Mask */
67 #define SysTimer_MTIMECTL_CLKSRC_Pos        2U                                          /*!< SysTick Timer MTIMECTL: CLKSRC bit Position */
68 #define SysTimer_MTIMECTL_CLKSRC_Msk        (1UL << SysTimer_MTIMECTL_CLKSRC_Pos)       /*!< SysTick Timer MTIMECTL: CLKSRC Mask */
69 
70 #define SysTimer_MSIP_MSIP_Pos              0U                                          /*!< SysTick Timer MSIP: MSIP bit Position */
71 #define SysTimer_MSIP_MSIP_Msk              (1UL << SysTimer_MSIP_MSIP_Pos)             /*!< SysTick Timer MSIP: MSIP Mask */
72 
73 #define SysTimer_MTIMER_Msk                 (0xFFFFFFFFFFFFFFFFULL)                     /*!< SysTick Timer MTIMER value Mask */
74 #define SysTimer_MTIMERCMP_Msk              (0xFFFFFFFFFFFFFFFFULL)                     /*!< SysTick Timer MTIMERCMP value Mask */
75 #define SysTimer_MTIMECTL_Msk               (0xFFFFFFFFUL)                              /*!< SysTick Timer MTIMECTL/MSTOP value Mask */
76 #define SysTimer_MSIP_Msk                   (0xFFFFFFFFUL)                              /*!< SysTick Timer MSIP   value Mask */
77 #define SysTimer_MSFTRST_Msk                (0xFFFFFFFFUL)                              /*!< SysTick Timer MSFTRST value Mask */
78 
79 #define SysTimer_MSFRST_KEY                 (0x80000A5FUL)                              /*!< SysTick Timer Software Reset Request Key */
80 
81 #ifndef __SYSTIMER_BASEADDR
82 /* Base address of SYSTIMER(__SYSTIMER_BASEADDR) should be defined in <Device.h> */
83 #error "__SYSTIMER_BASEADDR is not defined, please check!"
84 #endif
85 /* System Timer Memory mapping of Device  */
86 #define SysTimer_BASE                       __SYSTIMER_BASEADDR                         /*!< SysTick Base Address */
87 #define SysTimer                            ((SysTimer_Type *) SysTimer_BASE)           /*!< SysTick configuration struct */
88 /** @} */ /* end of group NMSIS_Core_SysTimer_Registers */
89 
90 /* ##################################    SysTimer function  ############################################ */
91 /**
92  * \defgroup NMSIS_Core_SysTimer SysTimer Functions
93  * \brief    Functions that configure the Core System Timer.
94  * @{
95  */
96 /**
97  * \brief  Set system timer load value
98  * \details
99  * This function set the system timer load value in MTIMER register.
100  * \param [in]  value   value to set system timer MTIMER register.
101  * \remarks
102  * - Load value is 64bits wide.
103  * - \ref SysTimer_GetLoadValue
104  */
SysTimer_SetLoadValue(uint64_t value)105 __STATIC_FORCEINLINE void SysTimer_SetLoadValue(uint64_t value)
106 {
107     SysTimer->MTIMER = value;
108 }
109 
110 /**
111  * \brief  Get system timer load value
112  * \details
113  * This function get the system timer current value in MTIMER register.
114  * \return  current value(64bit) of system timer MTIMER register.
115  * \remarks
116  * - Load value is 64bits wide.
117  * - \ref SysTimer_SetLoadValue
118  */
SysTimer_GetLoadValue(void)119 __STATIC_FORCEINLINE uint64_t SysTimer_GetLoadValue(void)
120 {
121     return SysTimer->MTIMER;
122 }
123 
124 /**
125  * \brief  Set system timer compare value
126  * \details
127  * This function set the system Timer compare value in MTIMERCMP register.
128  * \param [in]  value   compare value to set system timer MTIMERCMP register.
129  * \remarks
130  * - Compare value is 64bits wide.
131  * - If compare value is larger than current value timer interrupt generate.
132  * - Modify the load value or compare value less to clear the interrupt.
133  * - \ref SysTimer_GetCompareValue
134  */
SysTimer_SetCompareValue(uint64_t value)135 __STATIC_FORCEINLINE void SysTimer_SetCompareValue(uint64_t value)
136 {
137     SysTimer->MTIMERCMP = value;
138 }
139 
140 /**
141  * \brief  Get system timer compare value
142  * \details
143  * This function get the system timer compare value in MTIMERCMP register.
144  * \return  compare value of system timer MTIMERCMP register.
145  * \remarks
146  * - Compare value is 64bits wide.
147  * - \ref SysTimer_SetCompareValue
148  */
SysTimer_GetCompareValue(void)149 __STATIC_FORCEINLINE uint64_t SysTimer_GetCompareValue(void)
150 {
151     return SysTimer->MTIMERCMP;
152 }
153 
154 /**
155  * \brief  Enable system timer counter running
156  * \details
157  * Enable system timer counter running by clear
158  * TIMESTOP bit in MTIMECTL register.
159  */
SysTimer_Start(void)160 __STATIC_FORCEINLINE void SysTimer_Start(void)
161 {
162     SysTimer->MTIMECTL &= ~(SysTimer_MTIMECTL_TIMESTOP_Msk);
163 }
164 
165 /**
166  * \brief  Stop system timer counter running
167  * \details
168  * Stop system timer counter running by set
169  * TIMESTOP bit in MTIMECTL register.
170  */
SysTimer_Stop(void)171 __STATIC_FORCEINLINE void SysTimer_Stop(void)
172 {
173     SysTimer->MTIMECTL |= SysTimer_MTIMECTL_TIMESTOP_Msk;
174 }
175 
176 /**
177  * \brief  Set system timer control value
178  * \details
179  * This function set the system timer MTIMECTL register value.
180  * \param [in]  mctl    value to set MTIMECTL register
181  * \remarks
182  * - Bit TIMESTOP is used to start and stop timer.
183  *   Clear TIMESTOP bit to 0 to start timer, otherwise to stop timer.
184  * - Bit CMPCLREN is used to enable auto MTIMER clear to zero when MTIMER >= MTIMERCMP.
185  *   Clear CMPCLREN bit to 0 to stop auto clear MTIMER feature, otherwise to enable it.
186  * - Bit CLKSRC is used to select timer clock source.
187  *   Clear CLKSRC bit to 0 to use *mtime_toggle_a*, otherwise use *core_clk_aon*
188  * - \ref SysTimer_GetControlValue
189  */
SysTimer_SetControlValue(uint32_t mctl)190 __STATIC_FORCEINLINE void SysTimer_SetControlValue(uint32_t mctl)
191 {
192     SysTimer->MTIMECTL = (mctl & SysTimer_MTIMECTL_Msk);
193 }
194 
195 /**
196  * \brief  Get system timer control value
197  * \details
198  * This function get the system timer MTIMECTL register value.
199  * \return  MTIMECTL register value
200  * \remarks
201  * - \ref SysTimer_SetControlValue
202  */
SysTimer_GetControlValue(void)203 __STATIC_FORCEINLINE uint32_t SysTimer_GetControlValue(void)
204 {
205     return (SysTimer->MTIMECTL & SysTimer_MTIMECTL_Msk);
206 }
207 
208 /**
209  * \brief  Trigger or set software interrupt via system timer
210  * \details
211  * This function set the system timer MSIP bit in MSIP register.
212  * \remarks
213  * - Set system timer MSIP bit and generate a SW interrupt.
214  * - \ref SysTimer_ClearSWIRQ
215  * - \ref SysTimer_GetMsipValue
216  */
SysTimer_SetSWIRQ(void)217 __STATIC_FORCEINLINE void SysTimer_SetSWIRQ(void)
218 {
219     SysTimer->MSIP |= SysTimer_MSIP_MSIP_Msk;
220 }
221 
222 /**
223  * \brief  Clear system timer software interrupt pending request
224  * \details
225  * This function clear the system timer MSIP bit in MSIP register.
226  * \remarks
227  * - Clear system timer MSIP bit in MSIP register to clear the software interrupt pending.
228  * - \ref SysTimer_SetSWIRQ
229  * - \ref SysTimer_GetMsipValue
230  */
SysTimer_ClearSWIRQ(void)231 __STATIC_FORCEINLINE void SysTimer_ClearSWIRQ(void)
232 {
233     SysTimer->MSIP &= ~SysTimer_MSIP_MSIP_Msk;
234 }
235 
236 /**
237  * \brief  Get system timer MSIP register value
238  * \details
239  * This function get the system timer MSIP register value.
240  * \return    Value of Timer MSIP register.
241  * \remarks
242  * - Bit0 is SW interrupt flag.
243  *   Bit0 is 1 then SW interrupt set. Bit0 is 0 then SW interrupt clear.
244  * - \ref SysTimer_SetSWIRQ
245  * - \ref SysTimer_ClearSWIRQ
246  */
SysTimer_GetMsipValue(void)247 __STATIC_FORCEINLINE uint32_t SysTimer_GetMsipValue(void)
248 {
249     return (uint32_t)(SysTimer->MSIP & SysTimer_MSIP_Msk);
250 }
251 
252 /**
253  * \brief  Set system timer MSIP register value
254  * \details
255  * This function set the system timer MSIP register value.
256  * \param [in]  msip   value to set MSIP register
257  */
SysTimer_SetMsipValue(uint32_t msip)258 __STATIC_FORCEINLINE void SysTimer_SetMsipValue(uint32_t msip)
259 {
260     SysTimer->MSIP = (msip & SysTimer_MSIP_Msk);
261 }
262 
263 /**
264  * \brief  Do software reset request
265  * \details
266  * This function will do software reset request through MTIMER
267  * - Software need to write \ref SysTimer_MSFRST_KEY to generate software reset request
268  * - The software request flag can be cleared by reset operation to clear
269  * \remarks
270  * - The software reset is sent to SoC, SoC need to generate reset signal and send back to Core
271  * - This function will not return, it will do while(1) to wait the Core reset happened
272  */
SysTimer_SoftwareReset(void)273 __STATIC_FORCEINLINE void SysTimer_SoftwareReset(void)
274 {
275     SysTimer->MSFTRST = SysTimer_MSFRST_KEY;
276     while(1);
277 }
278 
279 #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) && defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
280 /**
281  * \brief   System Tick Configuration
282  * \details Initializes the System Timer and its non-vector interrupt, and starts the System Tick Timer.
283  *
284  *  In our default implementation, the timer counter will be set to zero, and it will start a timer compare non-vector interrupt
285  *  when it matches the ticks user set, during the timer interrupt user should reload the system tick using \ref SysTick_Reload function
286  *  or similar function written by user, so it can produce period timer interrupt.
287  * \param [in]  ticks  Number of ticks between two interrupts.
288  * \return          0  Function succeeded.
289  * \return          1  Function failed.
290  * \remarks
291  * - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced,
292  *   but we assume that the CMPCLREN bit is set to 0, so MTIMER register will not be
293  *   auto cleared to 0 when MTIMER >= MTIMERCMP.
294  * - When the variable \ref __Vendor_SysTickConfig is set to 1, then the
295  *   function \ref SysTick_Config is not included.
296  * - In this case, the file <b><Device>.h</b> must contain a vendor-specific implementation
297  *   of this function.
298  * - If user need this function to start a period timer interrupt, then in timer interrupt handler
299  *   routine code, user should call \ref SysTick_Reload with ticks to reload the timer.
300  * - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0
301  * \sa
302  * - \ref SysTimer_SetCompareValue; SysTimer_SetLoadValue
303  */
SysTick_Config(uint64_t ticks)304 __STATIC_INLINE uint32_t SysTick_Config(uint64_t ticks)
305 {
306     SysTimer_SetLoadValue(0);
307     SysTimer_SetCompareValue(ticks);
308     ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT);
309     ECLIC_SetLevelIRQ(SysTimer_IRQn, 0);
310     ECLIC_EnableIRQ(SysTimer_IRQn);
311     return (0UL);
312 }
313 
314 /**
315  * \brief   System Tick Reload
316  * \details Reload the System Timer Tick when the MTIMECMP reached TIME value
317  *
318  * \param [in]  ticks  Number of ticks between two interrupts.
319  * \return          0  Function succeeded.
320  * \return          1  Function failed.
321  * \remarks
322  * - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced,
323  *   but for this \ref SysTick_Config function, we assume this CMPCLREN bit is set to 0,
324  *   so in interrupt handler function, user still need to set the MTIMERCMP or MTIMER to reload
325  *   the system tick, if vendor want to use this timer's auto clear feature, they can define
326  *   \ref __Vendor_SysTickConfig to 1, and implement \ref SysTick_Config and \ref SysTick_Reload functions.
327  * - When the variable \ref __Vendor_SysTickConfig is set to 1, then the
328  *   function \ref SysTick_Reload is not included.
329  * - In this case, the file <b><Device>.h</b> must contain a vendor-specific implementation
330  *   of this function.
331  * - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0
332  * - Since the MTIMERCMP value might overflow, if overflowed, MTIMER will be set to 0, and MTIMERCMP set to ticks
333  * \sa
334  * - \ref SysTimer_SetCompareValue
335  * - \ref SysTimer_SetLoadValue
336  */
SysTick_Reload(uint64_t ticks)337 __STATIC_FORCEINLINE uint32_t SysTick_Reload(uint64_t ticks)
338 {
339     uint64_t cur_ticks = SysTimer->MTIMER;
340     uint64_t reload_ticks = ticks + cur_ticks;
341 
342     if (__USUALLY(reload_ticks > cur_ticks)) {
343         SysTimer->MTIMERCMP = reload_ticks;
344     } else {
345         /* When added the ticks value, then the MTIMERCMP < TIMER,
346          * which means the MTIMERCMP is overflowed,
347          * so we need to reset the counter to zero */
348         SysTimer->MTIMER = 0;
349         SysTimer->MTIMERCMP = ticks;
350     }
351 
352     return (0UL);
353 }
354 
355 #endif /* defined(__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) */
356 /** @} */ /* End of Doxygen Group NMSIS_Core_SysTimer */
357 
358 #endif /* defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1) */
359 
360 #ifdef __cplusplus
361 }
362 #endif
363 #endif /** __CORE_FEATURE_TIMER_H__  */
364 
365