]> begriffs open source - cmsis/blob - CMSIS/RTOS2/Source/os_tick_gtim.c
CMSIS-Core(M): Fixed MPU documentation after prefix addition.
[cmsis] / CMSIS / RTOS2 / Source / os_tick_gtim.c
1 /**************************************************************************//**
2  * @file     os_tick_gtim.c
3  * @brief    CMSIS OS Tick implementation for Private Timer
4  * @version  V1.0.0
5  * @date     21. July 2017
6  ******************************************************************************/
7 /*
8  * Copyright (c) 2017 ARM Limited. All rights reserved.
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  *
12  * Licensed under the Apache License, Version 2.0 (the License); you may
13  * not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  * www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
20  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  */
24
25 #include "os_tick.h"
26 #include "irq_ctrl.h"
27
28 #include "RTE_Components.h"
29 #include CMSIS_device_header
30
31 #ifndef GTIM_IRQ_PRIORITY
32 #define GTIM_IRQ_PRIORITY           0xFFU
33 #endif
34
35 #ifndef GTIM_IRQ_NUM
36 #define GTIM_IRQ_NUM                SecurePhyTimer_IRQn
37 #endif
38
39 // Timer interrupt pending flag
40 static uint8_t GTIM_PendIRQ;
41
42 // Timer tick frequency
43 static uint32_t GTIM_Clock;
44
45 // Timer load value
46 static uint32_t GTIM_Load;
47
48 // Setup OS Tick.
49 int32_t  OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) {
50   uint32_t prio, bits;
51
52   if (freq == 0U) {
53     return (-1);
54   }
55
56   GTIM_PendIRQ = 0U;
57
58   // Get timer clock
59   GTIM_Clock = *(uint32_t*)(SCTR_BASE+0x20);
60   PL1_SetCounterFrequency(GTIM_Clock);
61
62   // Calculate load value
63   GTIM_Load = (GTIM_Clock / freq) - 1U;
64
65   // Disable Generic Timer and set load value
66   PL1_SetControl(0U);
67   PL1_SetLoadValue(GTIM_Load);
68
69   // Disable corresponding IRQ
70   IRQ_Disable(GTIM_IRQ_NUM);
71   IRQ_ClearPending(GTIM_IRQ_NUM);
72
73   // Determine number of implemented priority bits
74   IRQ_SetPriority(GTIM_IRQ_NUM, 0xFFU);
75
76   prio = IRQ_GetPriority(GTIM_IRQ_NUM);
77
78   // At least bits [7:4] must be implemented
79   if ((prio & 0xF0U) == 0U) {
80     return (-1);
81   }
82
83   for (bits = 0; bits < 4; bits++) {
84     if ((prio & 0x01) != 0) {
85       break;
86     }
87     prio >>= 1;
88   }
89   
90   // Adjust configured priority to the number of implemented priority bits
91   prio = (GTIM_IRQ_PRIORITY << bits) & 0xFFUL;
92
93   // Set Private Timer interrupt priority
94   IRQ_SetPriority(GTIM_IRQ_NUM, prio-1U);
95
96   // Set edge-triggered IRQ
97   IRQ_SetMode(GTIM_IRQ_NUM, IRQ_MODE_TRIG_EDGE);
98
99   // Register tick interrupt handler function
100   IRQ_SetHandler(GTIM_IRQ_NUM, handler);
101
102   // Enable corresponding interrupt
103   IRQ_Enable(GTIM_IRQ_NUM);
104
105   // Enable system counter and timer control
106   *(uint32_t*)SCTR_BASE |= 3U;
107   PL1_SetControl(1U);
108
109   return (0);
110 }
111
112 /// Enable OS Tick.
113 int32_t  OS_Tick_Enable (void) {
114   uint32_t ctrl;
115
116   // Set pending interrupt if flag set
117   if (GTIM_PendIRQ != 0U) {
118     GTIM_PendIRQ = 0U;
119     IRQ_SetPending (GTIM_IRQ_NUM);
120   }
121
122   // Start the Private Timer
123   ctrl = PL1_GetControl();
124   // Set bit: Timer enable
125   ctrl |= 1U;
126   PL1_SetControl(ctrl);
127
128   return (0);
129 }
130
131 /// Disable OS Tick.
132 int32_t  OS_Tick_Disable (void) {
133   uint32_t ctrl;
134   
135   // Stop the Private Timer
136   ctrl = PL1_GetControl();
137   // Clear bit: Timer enable
138   ctrl &= ~1U;
139   PL1_SetControl(ctrl);
140
141   // Remember pending interrupt flag
142   if (IRQ_GetPending(GTIM_IRQ_NUM) != 0) {
143     IRQ_ClearPending(GTIM_IRQ_NUM);
144     GTIM_PendIRQ = 1U;
145   }
146
147   return (0);
148 }
149
150 // Acknowledge OS Tick IRQ.
151 int32_t  OS_Tick_AcknowledgeIRQ (void) {
152   IRQ_ClearPending (GTIM_IRQ_NUM);
153   PL1_SetLoadValue(GTIM_Load);
154   return (0);
155 }
156
157 // Get OS Tick IRQ number.
158 int32_t  OS_Tick_GetIRQn (void) {
159   return (GTIM_IRQ_NUM);
160 }
161
162 // Get OS Tick clock.
163 uint32_t OS_Tick_GetClock (void) {
164   return (GTIM_Clock);
165 }
166
167 // Get OS Tick interval.
168 uint32_t OS_Tick_GetInterval (void) {
169   return (GTIM_Load + 1U);
170 }
171
172 // Get OS Tick count value.
173 uint32_t OS_Tick_GetCount (void) {
174   return (GTIM_Load - PL1_GetCurrentValue());
175 }
176
177 // Get OS Tick overflow status.
178 uint32_t OS_Tick_GetOverflow (void) {
179   CNTP_CTL_Type cntp_ctl;
180   cntp_ctl.w = PL1_GetControl();
181   return (cntp_ctl.b.ISTATUS);
182 }