1 /*******************************************************************************
2 * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * PolarFire SoC Microprocessor Subsystem (MSS) Timer bare metal software driver
25 * public API.
26 */
27 /*=========================================================================*//**
28 @mainpage PolarFire SoC MSS Timer Bare Metal Driver.
29
30 @section intro_sec Introduction
31 The PolarFire SoC Microprocessor Subsystem (MSS) includes a timer hardware
32 block which can be used as two independent 32-bits timers or as a single
33 64-bits timer in periodic or one-shot mode.
34
35 This driver provides a set of functions for controlling the MSS timer as part
36 of a bare metal system where no operating system is available. These drivers
37 can be adapted for use as part of an operating system but the implementation
38 of the adaptation layer between this driver and the operating system's driver
39 model is outside the scope of this driver.
40
41 @section theory_op Theory of Operation
42 The PolarFire SoC MSS Timer can be used in one of two mutually exclusive modes
43 either as a single 64-bits timer or as two independent 32-bits timers. The MSS
44 Timer can be used in either periodic mode or one-shot mode. A timer configured
45 for periodic mode operations will generate an interrupt and reload its
46 down-counter when it reaches 0. The timer will then continue decrementing from
47 its reload value without waiting for the interrupt to be cleared. A timer
48 configured for one-shot mode will only generate an interrupt once when its
49 down-counter reaches 0. It must be explicitly reloaded to start decrementing
50 again.
51
52 The MSS Timer driver functions are grouped into the following categories:
53 - Initialization and Configuration
54 - Timer control
55 - Interrupt control
56
57 The MSS Timer driver provides three initialization functions:
58 - MSS_TIM1_init()
59 - MSS_TIM2_init()
60 - MSS_TIM64_init()
61
62 The MSS Timer driver is initialized through calls to these functions and at
63 least one of them must be called before any other MSS Timer driver functions
64 can be called.
65 You should only use the MSS_TIM1_init() and MSS_TIM2_init() functions if you
66 intend to use the timer in 32-bits mode. Use the MSS_TIM64_init() function is
67 you intend to use the MSS Timer as a single 64-bits timer. The initialization
68 functions take a single parameter specifying the operating mode of the timer
69 being initialized.
70
71 Once initialized a timer can be controlled using the following functions:
72 - MSS_TIM1_load_immediate()
73 - MSS_TIM1_load_background()
74 - MSS_TIM1_get_current_value()
75 - MSS_TIM1_start()
76 - MSS_TIM1_stop()
77 - MSS_TIM2_load_immediate()
78 - MSS_TIM2_load_background()
79 - MSS_TIM2_get_current_value()
80 - MSS_TIM2_start()
81 - MSS_TIM2_stop()
82 - MSS_TIM64_load_immediate()
83 - MSS_TIM64_load_background()
84 - MSS_TIM64_get_current_value()
85 - MSS_TIM64_start()
86 - MSS_TIM64_stop()
87
88 Timer interrupts are controlled using the following functions:
89 - MSS_TIM1_enable_irq()
90 - MSS_TIM1_disable_irq()
91 - MSS_TIM1_clear_irq()
92 - MSS_TIM2_enable_irq()
93 - MSS_TIM2_disable_irq()
94 - MSS_TIM2_clear_irq()
95 - MSS_TIM64_enable_irq()
96 - MSS_TIM64_disable_irq()
97 - MSS_TIM64_clear_irq()
98
99 The function prototypes for the timer interrupt handlers are:
100 - void Timer1_IRQHandler( void )
101 - void Timer2_IRQHandler( void )
102
103 Entries for these interrupt handlers are provided in the PolarFire SoC MPFS
104 HAL vector table. To add a Timer 1 interrupt handler, you must implement a
105 Timer1_IRQHandler( ) function as part of your application code. To add a
106 Timer 2 interrupt handler, you must implement a Timer2_IRQHandler( ) function
107 as part of your application code. When using the MSS Timer as a 64-bit timer,
108 you must implement a Timer1_IRQHandler( ) function as part of your
109 application code. The Timer 2 interrupt is not used when the MSS Timer is
110 configured as a 64-bit timer.
111
112 *//*=========================================================================*/
113 #ifndef MSS_TIMER_H_
114 #define MSS_TIMER_H_
115
116 #include "mpfs_hal/mss_hal.h"
117 #include "mss_timer_regs.h"
118
119 #ifdef __cplusplus
120 extern "C" {
121 #endif
122
123 /*****************************************************************************/
124 /* Peripheral declaration */
125 /*****************************************************************************/
126
127 #define TIMER_LO ((TIMER_TypeDef *) TIMER_LO_BASE)
128 #define TIMER_HI ((TIMER_TypeDef*) TIMER_HI_BASE)
129
130 /*-------------------------------------------------------------------------*//**
131 * Timer mode selection. This enumeration is used to select between the two
132 * possible timer modes of operation: periodic and one-shot mode. It is used as
133 * an argument to the MSS_TIM1_init(), MSS_TIM2_init() and MSS_TIM64_init()
134 * functions.
135 * MSS_TIMER_PERIODIC_MODE:
136 * In periodic mode the timer generates interrupts at constant intervals. On
137 * reaching zero, the timer's counter is reloaded with a value held in a
138 * register and begins counting down again.
139 * MSS_TIMER_ONE_SHOT_MODE:
140 * The timer generates a single interrupt in this mode. On reaching zero, the
141 * timer's counter halts until reprogrammed by the user.
142 */
143 typedef enum __mss_timer_mode
144 {
145 MSS_TIMER_PERIODIC_MODE = 0,//!< MSS_TIMER_PERIODIC_MODE
146 MSS_TIMER_ONE_SHOT_MODE = 1 //!< MSS_TIMER_ONE_SHOT_MODE
147 } mss_timer_mode_t;
148
149 /*-------------------------------------------------------------------------*//**
150 * Timer operation mask defines.
151 */
152 /* Timer 1 interrupt enable bits */
153 #define TIM1_INTEN_MASK 0x00000004u
154
155 /* Timer 1 Mode bits */
156 #define TIM1_MODE_SHIFT 1u
157 #define TIM1_MODE_MASK 0x00000002u
158
159 /* Timer 1 enable bits */
160 #define TIM1_ENABLE_MASK 0x00000001u
161
162 /* Timer 2 interrupt enable bits */
163 #define TIM2_INTEN_MASK 0x00000004u
164
165 /* Timer 2 Mode bits */
166 #define TIM2_MODE_SHIFT 1u
167 #define TIM2_MODE_MASK 0x00000002u
168
169 /* Timer 2 enable bits */
170 #define TIM2_ENABLE_MASK 0x00000001u
171
172 /* Timer 64 interrupt enable bits */
173 #define TIM64_INTEN_MASK 0x00000004u
174
175 /* Timer 64 mode bits */
176 #define TIM64_MODE_SHIFT 1u
177 #define TIM64_MODE_MASK 0x00000002u
178
179 /* Timer 64 enable bits */
180 #define TIM64_ENABLE_MASK 0x00000001u
181
182 static uint32_t readvalue[52] = {0};
183
184 /*-------------------------------------------------------------------------*//**
185 The MSS_TIM1_init() function initializes the MSS Timer block for use as a
186 32-bit timer and selects the operating mode for Timer 1. The MSS Timer block
187 is out of reset before executing this function. The MSS_TIM1_init() function
188 stops Timer 1, disables its interrupt, and sets the Timer 1 operating mode.
189
190 @param timer
191 The timer parameter specifies the Timer block to configure.
192
193 @param mode
194 The mode parameter specifies whether the timer will operate in periodic or
195 one-shot mode. Allowed values for this parameter are:
196 - MSS_TIMER_PERIODIC_MODE
197 - MSS_TIMER_ONE_SHOT_MODE
198
199 Note:The MSS Timer block cannot be used both as a 64-bit and 32-bit timer.
200 Calling MSS_TIM1_init() will overwrite any previous configuration
201 of the MSS Timer as a 64-bit timer.
202 */
203 static inline void
MSS_TIM1_init(TIMER_TypeDef * timer,mss_timer_mode_t mode)204 MSS_TIM1_init(TIMER_TypeDef* timer, mss_timer_mode_t mode)
205 {
206 PLIC_DisableIRQ(TIMER1_PLIC); /* Disable timer 1 irq */
207
208 timer->TIM64_MODE = 0u; /* switch to 32 bits mode */
209 readvalue[1] = timer->TIM64_MODE;
210
211 /* Disable timer and interrupt and set mode (continuous/one-shot) */
212 timer->TIM1_CTRL = TIM1_MODE_MASK & ((uint32_t)mode << TIM1_MODE_SHIFT);
213 readvalue[2] = timer->TIM1_CTRL;
214
215 timer->TIM1_RIS = 1u; /* clear timer 1 interrupt */
216 readvalue[3] = timer->TIM1_RIS;
217 }
218
219 /*-------------------------------------------------------------------------*//**
220 The MSS_TIM1_start() function enables Timer 1 and starts its down-counter
221 decrementing from the load_value specified in previous calls to the
222 MSS_TIM1_load_immediate() or MSS_TIM1_load_background() functions.
223
224 @param timer
225 The timer parameter specifies the Timer block to configure.
226
227 Note: The MSS_TIM1_start() function is also used to resume the down-counter
228 if previously stopped using the MSS_TIM1_stop() function.
229 */
230 static inline void
MSS_TIM1_start(TIMER_TypeDef * timer)231 MSS_TIM1_start(TIMER_TypeDef* timer)
232 {
233 timer->TIM1_CTRL |= TIM1_ENABLE_MASK;
234 }
235
236 /*-------------------------------------------------------------------------*//**
237 The MSS_TIM1_stop() function disables Timer 1 and stops its down-counter
238 decrementing.
239
240 @param timer
241 The timer parameter specifies the Timer block to configure.
242
243 */
244 static inline void
MSS_TIM1_stop(TIMER_TypeDef * timer)245 MSS_TIM1_stop(TIMER_TypeDef* timer)
246 {
247 timer->TIM1_CTRL &= ~((uint32_t)TIM1_ENABLE_MASK); /* disable timer */
248 }
249
250 /*-------------------------------------------------------------------------*//**
251 The MSS_TIM1_get_current_value() returns the current value of the Timer 1
252 down-counter.
253
254 @param timer
255 The timer parameter specifies the Timer block to configure.
256
257 @return
258 This function returns the 32-bits current value of the Timer 1 down-counter.
259 */
260 static inline uint32_t
MSS_TIM1_get_current_value(TIMER_TypeDef * timer)261 MSS_TIM1_get_current_value(TIMER_TypeDef* timer)
262 {
263 return timer->TIM1_VAL;
264 }
265
266 /*-------------------------------------------------------------------------*//**
267 The MSS_TIM1_load_immediate() function loads the value passed by the
268 load_value parameter into the Timer 1 down-counter. The counter will
269 decrement immediately from this value once Timer 1 is enabled. The MSS
270 Timer will generate an interrupt when the counter reaches zero, if Timer 1
271 interrupts are enabled. This function is intended to be used when Timer 1
272 is configured for one-shot mode to time a single delay.
273
274 Note: The value passed by the load_value parameter is loaded immediately
275 into the down-counter regardless of whether Timer 1 is operating in
276 periodic or one-shot mode.
277
278 @param timer
279 The timer parameter specifies the Timer block to configure.
280
281 @param load_value
282 The load_value parameter specifies the value from which the Timer 1
283 down-counter will start decrementing from.
284 */
285 static inline void
MSS_TIM1_load_immediate(TIMER_TypeDef * timer,uint32_t load_value)286 MSS_TIM1_load_immediate(TIMER_TypeDef* timer, uint32_t load_value)
287 {
288 timer->TIM1_LOADVAL = load_value;
289 }
290
291 /*-------------------------------------------------------------------------*//**
292 The MSS_TIM1_load_background() function is used to specify the value that will
293 be reloaded into the Timer 1 down-counter the next time the counter reaches
294 zero. This function is typically used when Timer 1 is configured for periodic
295 mode operation to select or change the delay period between the interrupts
296 generated by Timer 1.
297
298 @param timer
299 The timer parameter specifies the Timer block to configure.
300
301 @param load_value
302 The load_value parameter specifies the value that will be loaded into the
303 Timer 1 down-counter the next time the down-counter reaches zero. The Timer
304 1 down-counter will start decrementing from this value after the current
305 count expires.
306 */
307 static inline void
MSS_TIM1_load_background(TIMER_TypeDef * timer,uint32_t load_value)308 MSS_TIM1_load_background(TIMER_TypeDef* timer, uint32_t load_value)
309 {
310 timer->TIM1_BGLOADVAL = load_value;
311 }
312
313 /*-------------------------------------------------------------------------*//**
314 The MSS_TIM1_enable_irq() function is used to enable interrupt generation for
315 Timer 1. This function also enables the interrupt in the RISC-V PLIC. The
316 Timer1_IRQHandler() function will be called when a Timer 1 interrupt occurs.
317
318 Note: A Timer1_IRQHandler() default implementation is defined, with weak
319 linkage, in the MPFS HAL. You must provide your own implementation of
320 the Timer1_IRQHandler() function, which will override the default
321 implementation, to suit your application.
322
323 @param timer
324 The timer parameter specifies the Timer block to configure.
325
326 */
327 static inline void
MSS_TIM1_enable_irq(TIMER_TypeDef * timer)328 MSS_TIM1_enable_irq(TIMER_TypeDef* timer)
329 {
330 timer->TIM1_CTRL |= TIM1_INTEN_MASK;
331 readvalue[8] = timer->TIM1_CTRL;
332 PLIC_EnableIRQ(TIMER1_PLIC);
333 }
334
335 /*-------------------------------------------------------------------------*//**
336 The MSS_TIM1_disable_irq() function is used to disable interrupt generation for
337 Timer 1. This function also disables the interrupt in the RISC-V PLIC.
338
339 @param timer
340 The timer parameter specifies the Timer block to configure.
341
342 */
343 static inline void
MSS_TIM1_disable_irq(TIMER_TypeDef * timer)344 MSS_TIM1_disable_irq(TIMER_TypeDef* timer)
345 {
346 timer->TIM1_CTRL &= ~((uint32_t)TIM1_INTEN_MASK);
347 PLIC_DisableIRQ(TIMER1_PLIC); /* Disable timer 1 irq */
348 }
349
350 /*-------------------------------------------------------------------------*//**
351 The MSS_TIM1_clear_irq() function is used to clear a pending interrupt from
352 Timer 1. This function also clears the interrupt in the RISC-V PLIC.
353
354 Note:You must call the MSS_TIM1_clear_irq() function as part of your
355 implementation of the Timer1_IRQHandler() Timer 1 interrupt service
356 routine (ISR) in order to prevent the same interrupt event
357 retriggering a call to the ISR.
358
359 @param timer
360 The timer parameter specifies the Timer block to configure.
361
362 */
363 static inline void
MSS_TIM1_clear_irq(TIMER_TypeDef * timer)364 MSS_TIM1_clear_irq(TIMER_TypeDef* timer)
365 {
366 timer->TIM1_RIS = 1u;
367 }
368
369 /*-------------------------------------------------------------------------*//**
370 The MSS_TIM2_init() function initializes the MSS Timer block for use as a
371 32-bit timer and selects the operating mode for Timer 2. The MSS Timer block
372 is already out of reset before executing MSS_TIM2_init() function. This
373 function stops Timer 2, disables its interrupt and sets the Timer 2 operating
374 mode.
375
376 Note:The MSS Timer block cannot be used both as a 64-bit and 32-bit timer.
377 Calling MSS_TIM2_init() will overwrite any previous configuration of the
378 MSS Timer as a 64-bit timer.
379
380 @param timer
381 The timer parameter specifies the Timer block to configure.
382
383 @param mode
384 The mode parameter specifies whether the timer will operate in periodic or
385 one-shot mode. Allowed values for this parameter are:
386 - MSS_TIMER_PERIODIC_MODE
387 - MSS_TIMER_ONE_SHOT_MODE
388 */
389 static inline void
MSS_TIM2_init(TIMER_TypeDef * timer,mss_timer_mode_t mode)390 MSS_TIM2_init(TIMER_TypeDef* timer, mss_timer_mode_t mode)
391 {
392 PLIC_DisableIRQ(TIMER2_PLIC); /* Disable timer 2 irq */
393 timer->TIM64_MODE = 0u; /* switch to 32 bits mode */
394
395 /* Disable timer and interrupt. Set mode (continuous/one-shot) */
396 timer->TIM2_CTRL = TIM2_MODE_MASK & ((uint32_t)mode << TIM2_MODE_SHIFT);
397
398 timer->TIM2_RIS = 1u; /* clear timer 2 interrupt */
399 }
400
401 /*-------------------------------------------------------------------------*//**
402 The MSS_TIM2_start() function enables Timer 2 and starts its down-counter
403 decrementing from the load_value specified in previous calls to the
404 MSS_TIM2_load_immediate() or MSS_TIM2_load_background() functions.
405
406 @param timer
407 The timer parameter specifies the Timer block to configure.
408
409 Note:The MSS_TIM2_start() function is also used to resume the down-counter
410 if previously stopped using the MSS_TIM2_stop() function.
411 */
412 static inline void
MSS_TIM2_start(TIMER_TypeDef * timer)413 MSS_TIM2_start(TIMER_TypeDef* timer)
414 {
415 timer->TIM2_CTRL |= TIM2_ENABLE_MASK; /* enable timer */
416 }
417
418 /*-------------------------------------------------------------------------*//**
419 The MSS_TIM2_stop() function disables Timer 2 and stops its down-counter
420 decrementing.
421
422 @param timer
423 The timer parameter specifies the Timer block to configure.
424 */
425 static inline void
MSS_TIM2_stop(TIMER_TypeDef * timer)426 MSS_TIM2_stop(TIMER_TypeDef* timer)
427 {
428 timer->TIM2_CTRL &= ~((uint32_t)TIM2_ENABLE_MASK); /* disable timer */
429 }
430
431 /*-------------------------------------------------------------------------*//**
432 The MSS_TIM2_get_current_value() returns the current value of the Timer 2
433 down-counter.
434
435 @param timer
436 The timer parameter specifies the Timer block to configure.
437 */
438 static inline uint32_t
MSS_TIM2_get_current_value(TIMER_TypeDef * timer)439 MSS_TIM2_get_current_value(TIMER_TypeDef* timer)
440 {
441 return timer->TIM2_VAL;
442 }
443
444 /*-------------------------------------------------------------------------*//**
445 The MSS_TIM2_load_immediate() function loads the value passed by the
446 load_value parameter into the Timer 2 down-counter. The counter will
447 decrement immediately from this value once Timer 2 is enabled. The MSS Timer
448 will generate an interrupt when the counter reaches zero if Timer 2
449 interrupts are enabled. This function is intended to be used when Timer 2
450 is configured for one-shot mode to time a single delay.
451
452 Note:The value passed by the load_value parameter is loaded immediately into
453 the down-counter regardless of whether Timer 2 is operating in periodic
454 or one-shot mode.
455
456 @param timer
457 The timer parameter specifies the Timer block to configure.
458
459 @param load_value
460 The load_value parameter specifies the value from which the Timer 2
461 down-counter will start decrementing.
462 */
463 static inline void
MSS_TIM2_load_immediate(TIMER_TypeDef * timer,uint32_t load_value)464 MSS_TIM2_load_immediate(TIMER_TypeDef* timer, uint32_t load_value)
465 {
466 timer->TIM2_LOADVAL = load_value;
467 }
468
469 /*-------------------------------------------------------------------------*//**
470 The MSS_TIM2_load_background() function is used to specify the value that will
471 be reloaded into the Timer 2 down-counter the next time the counter reaches
472 zero. This function is typically used when Timer 2 is configured for periodic
473 mode operation to select or change the delay period between the interrupts
474 generated by Timer 2.
475
476 @param timer
477 The timer parameter specifies the Timer block to configure.
478
479 @param load_value
480 The load_value parameter specifies the value that will be loaded into the
481 Timer 2 down-counter the next time the down-counter reaches zero. The Timer
482 2 down-counter will start decrementing from this value after the current
483 count expires.
484 */
485 static inline void
MSS_TIM2_load_background(TIMER_TypeDef * timer,uint32_t load_value)486 MSS_TIM2_load_background(TIMER_TypeDef* timer, uint32_t load_value)
487 {
488 timer->TIM2_BGLOADVAL = load_value;
489 }
490
491 /*-------------------------------------------------------------------------*//**
492 The MSS_TIM2_enable_irq() function is used to enable interrupt generation for
493 Timer 2. This function also enables the interrupt in the RISC-V PLIC. The
494 Timer2_IRQHandler() function will be called when a Timer 2 interrupt occurs.
495
496 Note:A Timer2_IRQHandler() default implementation is defined, with weak
497 linkage, in the MPFS HAL. You must provide your own implementation of
498 the Timer2_IRQHandler() function, which will override the default
499 implementation, to suit your application.
500
501 @param timer
502 The timer parameter specifies the Timer block to configure.
503 */
504 static inline void
MSS_TIM2_enable_irq(TIMER_TypeDef * timer)505 MSS_TIM2_enable_irq(TIMER_TypeDef* timer)
506 {
507 timer->TIM2_CTRL |= TIM2_INTEN_MASK;
508 PLIC_EnableIRQ(TIMER2_PLIC);
509 }
510
511 /*-------------------------------------------------------------------------*//**
512 The MSS_TIM2_disable_irq() function is used to disable interrupt generation for
513 Timer 2. This function also disables the interrupt in the RISC-V PLIC.
514
515 @param timer
516 The timer parameter specifies the Timer block to configure.
517 */
518 static inline void
MSS_TIM2_disable_irq(TIMER_TypeDef * timer)519 MSS_TIM2_disable_irq(TIMER_TypeDef* timer)
520 {
521 timer->TIM2_CTRL &= ~((uint32_t)TIM2_INTEN_MASK);
522 PLIC_DisableIRQ(TIMER2_PLIC); /* Disable timer 2 irq */
523 }
524
525 /*-------------------------------------------------------------------------*//**
526 The MSS_TIM2_clear_irq() function is used to clear a pending interrupt from
527 Timer 2. This function also clears the interrupt in the RISC-V PLIC.
528
529 Note:You must call the MSS_TIM2_clear_irq() function as part of your
530 implementation of the Timer2_IRQHandler() Timer 2 interrupt service
531 routine (ISR) in order to prevent the same interrupt event retriggering
532 a call to the ISR.
533
534 @param timer
535 The timer parameter specifies the Timer block to configure.
536
537 */
538 static inline void
MSS_TIM2_clear_irq(TIMER_TypeDef * timer)539 MSS_TIM2_clear_irq(TIMER_TypeDef* timer)
540 {
541 timer->TIM2_RIS = 1u;
542 }
543
544 /*-------------------------------------------------------------------------*//**
545 The MSS_TIM64_init() function initializes the MSS Timer block for use as a
546 single 64-bit timer and selects the operating mode of the timer. The MSS Timer
547 block is already out of reset before executing MSS_TIM64_init() function.
548 This function stops the timer, disables its interrupts, and sets the timer's
549 operating mode.
550
551 Note:The MSS Timer block cannot be used both as a 64-bit and 32-bit timer.
552 Calling MSS_TIM64_init() will overwrite any previous configuration of the
553 MSS Timer as a 32-bit timer.
554
555 @param timer
556 The timer parameter specifies the Timer block to configure.
557
558 @param mode
559 The mode parameter specifies whether the timer will operate in periodic or
560 one-shot mode. Allowed values for this parameter are:
561 - MSS_TIMER_PERIODIC_MODE
562 - MSS_TIMER_ONE_SHOT_MODE
563 */
564 static inline void
MSS_TIM64_init(TIMER_TypeDef * timer,mss_timer_mode_t mode)565 MSS_TIM64_init(TIMER_TypeDef* timer, mss_timer_mode_t mode)
566 {
567 PLIC_DisableIRQ(TIMER1_PLIC); /* Disable timer 1 irq */
568 PLIC_DisableIRQ(TIMER2_PLIC); /* Disable timer 2 irq */
569
570 timer->TIM64_MODE = 1u; /* switch to 64 bits mode */
571
572 /* Disable timer and interrupt and set mode (continuous/one-shot) */
573 timer->TIM64_CTRL = TIM64_MODE_MASK & ((uint32_t)mode << TIM64_MODE_SHIFT);
574
575 timer->TIM1_RIS = 1u; /* clear timer 1 interrupt */
576 timer->TIM2_RIS = 1u; /* clear timer 2 interrupt */
577 }
578
579 /*-------------------------------------------------------------------------*//**
580 The MSS_TIM64_start() function enables the 64-bit timer and starts its
581 down-counter decrementing from the load_value specified in previous calls to
582 the MSS_TIM64_load_immediate() or MSS_TIM64_load_background() functions.
583
584 Note: The MSS_TIM64_start() function is also used to resume the down-counter
585 if previously stopped using the MSS_TIM64_stop() function.
586
587 @param timer
588 The timer parameter specifies the Timer block to configure.
589 */
590 static inline void
MSS_TIM64_start(TIMER_TypeDef * timer)591 MSS_TIM64_start(TIMER_TypeDef* timer)
592 {
593 timer->TIM64_CTRL |= TIM64_ENABLE_MASK; /* enable timer */
594 }
595
596 /*-------------------------------------------------------------------------*//**
597 The MSS_TIM64_stop() function disables the 64-bit timer and stops its
598 down-counter decrementing.
599
600 @param timer
601 The timer parameter specifies the Timer block to configure.
602 */
603 static inline void
MSS_TIM64_stop(TIMER_TypeDef * timer)604 MSS_TIM64_stop(TIMER_TypeDef* timer)
605 {
606 timer->TIM64_CTRL &= ~((uint32_t)TIM64_ENABLE_MASK); /* disable timer */
607 }
608
609 /*-------------------------------------------------------------------------*//**
610 The MSS_TIM64_get_current_value() is used to read the current value of the
611 64-bit timer down-counter.
612
613 @param timer
614 The timer parameter specifies the Timer block to configure.
615
616 @param load_value_u
617 The load_value_u parameter is a pointer to a 32-bit variable where the upper
618 32 bits of the current value of the 64-bit timer down-counter will be copied.
619
620 @param load_value_l
621 The load_value_l parameter is a pointer to a 32-bit variable where the lower
622 32 bits of the current value of the 64-bit timer down-counter will be copied.
623
624 Example:
625 @code
626 uint32_t current_value_u = 0;
627 uint32_t current_value_l = 0;
628 MSS_TIM64_get_current_value( ¤t_value_u, ¤t_value_l );
629 @endcode
630 */
631 static inline void
MSS_TIM64_get_current_value(TIMER_TypeDef * timer,uint32_t * load_value_u,uint32_t * load_value_l)632 MSS_TIM64_get_current_value
633 (
634 TIMER_TypeDef* timer,
635 uint32_t * load_value_u,
636 uint32_t * load_value_l
637 )
638 {
639 *load_value_l = timer->TIM64_VAL_L;
640 *load_value_u = timer->TIM64_VAL_U;
641 }
642
643 /*-------------------------------------------------------------------------*//**
644 The MSS_TIM64_load_immediate() function loads the values passed by the
645 load_value_u and load_value_l parameters into the 64-bit timer down-counter.
646 The counter will decrement immediately from the concatenated 64-bit value once
647 the 64-bit timer is enabled. The MSS Timer will generate an interrupt when the
648 counter reaches zero if 64-bit timer interrupts are enabled. This function is
649 intended to be used when the 64-bit timer is configured for one-shot mode to
650 time a single delay.
651
652 Note: The value passed by the load_value parameter is loaded immediately into
653 the down-counter regardless of whether the 64-bit timer is operating in
654 periodic or one-shot mode.
655
656 @param timer
657 The timer parameter specifies the Timer block to configure.
658
659 @param load_value_u
660 The load_value_u parameter specifies the upper 32 bits of the 64-bit timer
661 load value from which the 64-bit timer down-counter will start decrementing.
662
663 @param load_value_l
664 The load_value_l parameter specifies the lower 32 bits of the 64-bit timer
665 load value from which the 64-bit timer down-counter will start decrementing.
666 */
667 static inline void
MSS_TIM64_load_immediate(TIMER_TypeDef * timer,uint32_t load_value_u,uint32_t load_value_l)668 MSS_TIM64_load_immediate
669 (
670 TIMER_TypeDef* timer,
671 uint32_t load_value_u,
672 uint32_t load_value_l
673 )
674 {
675 timer->TIM64_LOADVAL_U = load_value_u;
676 timer->TIM64_LOADVAL_L = load_value_l;
677 }
678
679 /*-------------------------------------------------------------------------*//**
680 The MSS_TIM64_load_background() function is used to specify the 64-bit value
681 that will be reloaded into the 64-bit timer down-counter the next time the
682 counter reaches zero. This function is typically used when the 64-bit timer is
683 configured for periodic mode operation to select or change the delay period
684 between the interrupts generated by the 64-bit timer.
685
686 @param timer
687 The timer parameter specifies the Timer block to configure.
688
689 @param load_value_u
690 The load_value_u parameter specifies the upper 32 bits of the 64-bit timer
691 load value. The concatenated 64-bit value formed from load_value_u and
692 load_value_l will be loaded into the 64-bit timer down-counter the next
693 time the down-counter reaches zero. The 64-bit timer down-counter will start
694 decrementing from the concatenated 64-bit value after the current count
695 expires.
696
697 @param load_value_l
698 The load_value_l parameter specifies the lower 32 bits of the 64-bit timer
699 load value. The concatenated 64-bit value formed from load_value_u and
700 load_value_l will be loaded into the 64-bit timer down-counter the next time
701 the down-counter reaches zero. The 64-bit timer down-counter will start
702 decrementing from the concatenated 64-bit value after the current count
703 expires.
704 */
705 static inline void
MSS_TIM64_load_background(TIMER_TypeDef * timer,uint32_t load_value_u,uint32_t load_value_l)706 MSS_TIM64_load_background
707 (
708 TIMER_TypeDef* timer,
709 uint32_t load_value_u,
710 uint32_t load_value_l
711 )
712 {
713 timer->TIM64_BGLOADVAL_U = load_value_u;
714 timer->TIM64_BGLOADVAL_L = load_value_l;
715 }
716
717 /*-------------------------------------------------------------------------*//**
718 The MSS_TIM64_enable_irq() function is used to enable interrupt generation for
719 the 64-bit timer. This function also enables the interrupt in the RISC-V PLIC.
720 The Timer1_IRQHandler() function will be called when a 64-bit timer interrupt
721 occurs.
722
723 Note: A Timer1_IRQHandler() default implementation is defined, with weak
724 linkage, in the MPFS HAL. You must provide your own implementation of
725 the Timer1_IRQHandler() function, which will override the default
726 implementation, to suit your application.
727
728 Note: The MSS_TIM64_enable_irq() function enables and uses Timer 1 interrupts
729 for the 64-bit timer. Timer 2 interrupts remain disabled.
730
731 @param timer
732 The timer parameter specifies the Timer block to configure.
733
734 */
735 static inline void
MSS_TIM64_enable_irq(TIMER_TypeDef * timer)736 MSS_TIM64_enable_irq(TIMER_TypeDef* timer)
737 {
738 timer->TIM64_CTRL |= TIM64_INTEN_MASK;
739 PLIC_EnableIRQ(TIMER1_PLIC);
740 }
741
742 /*-------------------------------------------------------------------------*//**
743 The MSS_TIM64_disable_irq() function is used to disable interrupt generation
744 for the 64-bit timer. This function also disables the interrupt in the RISC-V
745 PLIC.
746
747 @param timer
748 The timer parameter specifies the Timer block to configure.
749 */
750 static inline void
MSS_TIM64_disable_irq(TIMER_TypeDef * timer)751 MSS_TIM64_disable_irq(TIMER_TypeDef* timer)
752 {
753 timer->TIM64_CTRL &= ~((uint32_t)TIM64_INTEN_MASK);
754 PLIC_DisableIRQ(TIMER1_PLIC);
755 }
756
757 /*-------------------------------------------------------------------------*//**
758 The MSS_TIM64_clear_irq() function is used to clear a pending interrupt from
759 the 64-bit timer. This function also clears the interrupt in the RISC-V PLIC.
760
761 Note:You must call the MSS_TIM64_clear_irq() function as part of your
762 implementation of the Timer1_IRQHandler() 64-bit timer interrupt service
763 routine (ISR) in order to prevent the same interrupt event retriggering
764 a call to the ISR.
765
766 @param timer
767 The timer parameter specifies the Timer block to configure.
768 */
769 static inline void
MSS_TIM64_clear_irq(TIMER_TypeDef * timer)770 MSS_TIM64_clear_irq(TIMER_TypeDef* timer)
771 {
772 timer->TIM64_RIS = 1u;
773 }
774
775 #ifdef __cplusplus
776 }
777 #endif
778
779 #endif /*MSS_TIMER_H_*/
780