1 /*
2 * Copyright (C) 2019 ETH Zurich and University of Bologna
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * SPDX-License-Identifier: Apache-2.0
17 */
18
19 /* Driver to configure PULP timer as periodic interrupt source */
20 /* Author: Robert Balas (balasr@iis.ee.ethz.ch)
21 * Germain Haugou (germain.haugou@iis.ee.ethz.ch)
22 */
23
24 #include <bits.h>
25 #include <pulp_io.h>
26 #include <stdint.h>
27 #include <stdbool.h>
28 #include "core-v-mcu-pulp-mem-map.h"
29 #include "hal_timer.h"
30 #include "hal_timer_irq.h"
31
32 /* TODO: used to measure elapsed time since last "visit" */
33 static uint32_t last_count;
timer_irq_disable()34 int timer_irq_disable(){
35 writew (0,(uintptr_t)(PULP_FC_TIMER_ADDR + TIMER_CFG_LO_OFFSET));
36 writew (0,(uintptr_t)(PULP_FC_TIMER_ADDR + TIMER_CFG_HI_OFFSET));
37
38 }
39
timer_irq_init(uint32_t ticks)40 int timer_irq_init(uint32_t ticks)
41 {
42 /* TODO: enable soc_eu timer interrupt */
43
44 /* set the interrupt interval */
45 timer_irq_set_timeout(ticks, false);
46
47 /* We use only one of the 32-bit timer, leaving the other half available
48 * as an additional timer. We didn't opt for using both together as
49 * 64-bit timer.
50 *
51 * Enable timer, use 32khz ref clock as source. Timer will reset
52 * automatically to zero after causing an interrupt.
53 */
54 /* use high timer for now as int actually gets to cpu */
55 #ifdef configMTIME_BASE_ADDRESS
56 writew(0xc000000f,(uintptr_t)(PULP_FC_TIMER_ADDR + TIMER_CFG_LO_OFFSET));
57 #else
58 writew(TIMER_CFG_LO_ENABLE_MASK | TIMER_CFG_LO_RESET_MASK |
59 TIMER_CFG_LO_MODE_MASK |
60 TIMER_CFG_LO_IRQEN_MASK,
61 (uintptr_t)(PULP_FC_TIMER_ADDR + TIMER_CFG_LO_OFFSET));
62 #endif
63
64 return 0;
65 }
66
timer_irq_set_timeout(uint32_t ticks,bool idle)67 int timer_irq_set_timeout(uint32_t ticks, bool idle)
68 {
69 (void)idle;
70 /* fast reset, value doesn't matter */
71
72 writew(1, (uintptr_t)(PULP_FC_TIMER_ADDR + TIMER_RESET_LO_OFFSET));
73 writew(ticks, (uintptr_t)(PULP_FC_TIMER_ADDR + TIMER_CMP_LO_OFFSET));
74 writew(1, (uintptr_t)(PULP_FC_TIMER_ADDR + TIMER_RESET_HI_OFFSET));
75
76 return 0;
77 }
78
79 /* TODO: implement */
timer_irq_clock_elapsed()80 uint32_t timer_irq_clock_elapsed()
81 {
82 return 0;
83 }
84
timer_irq_cycle_get_32()85 uint32_t timer_irq_cycle_get_32()
86 {
87 return readw((uintptr_t)(PULP_FC_TIMER_ADDR + TIMER_CNT_LO_OFFSET));
88 }
89