EL4121 Embedded System / mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

UserRevisionLine numberNew contents of line
be_bryan 0:b74591d5ab33 1 /**************************************************************************//**
be_bryan 0:b74591d5ab33 2 * @file irq_ctrl_gic.c
be_bryan 0:b74591d5ab33 3 * @brief Interrupt controller handling implementation for GIC
be_bryan 0:b74591d5ab33 4 * @version V1.0.0
be_bryan 0:b74591d5ab33 5 * @date 30. June 2017
be_bryan 0:b74591d5ab33 6 ******************************************************************************/
be_bryan 0:b74591d5ab33 7 /*
be_bryan 0:b74591d5ab33 8 * Copyright (c) 2017 ARM Limited. All rights reserved.
be_bryan 0:b74591d5ab33 9 *
be_bryan 0:b74591d5ab33 10 * SPDX-License-Identifier: Apache-2.0
be_bryan 0:b74591d5ab33 11 *
be_bryan 0:b74591d5ab33 12 * Licensed under the Apache License, Version 2.0 (the License); you may
be_bryan 0:b74591d5ab33 13 * not use this file except in compliance with the License.
be_bryan 0:b74591d5ab33 14 * You may obtain a copy of the License at
be_bryan 0:b74591d5ab33 15 *
be_bryan 0:b74591d5ab33 16 * www.apache.org/licenses/LICENSE-2.0
be_bryan 0:b74591d5ab33 17 *
be_bryan 0:b74591d5ab33 18 * Unless required by applicable law or agreed to in writing, software
be_bryan 0:b74591d5ab33 19 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
be_bryan 0:b74591d5ab33 20 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
be_bryan 0:b74591d5ab33 21 * See the License for the specific language governing permissions and
be_bryan 0:b74591d5ab33 22 * limitations under the License.
be_bryan 0:b74591d5ab33 23 */
be_bryan 0:b74591d5ab33 24
be_bryan 0:b74591d5ab33 25 #include <stddef.h>
be_bryan 0:b74591d5ab33 26
be_bryan 0:b74591d5ab33 27 #include <cmsis.h>
be_bryan 0:b74591d5ab33 28
be_bryan 0:b74591d5ab33 29 #include "irq_ctrl.h"
be_bryan 0:b74591d5ab33 30
be_bryan 0:b74591d5ab33 31 #if defined(__GIC_PRESENT) && (__GIC_PRESENT == 1U)
be_bryan 0:b74591d5ab33 32
be_bryan 0:b74591d5ab33 33 /// Number of implemented interrupt lines
be_bryan 0:b74591d5ab33 34 #ifndef IRQ_GIC_LINE_COUNT
be_bryan 0:b74591d5ab33 35 #define IRQ_GIC_LINE_COUNT (1020U)
be_bryan 0:b74591d5ab33 36 #endif
be_bryan 0:b74591d5ab33 37
be_bryan 0:b74591d5ab33 38 static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U };
be_bryan 0:b74591d5ab33 39 static uint32_t IRQ_ID0;
be_bryan 0:b74591d5ab33 40
be_bryan 0:b74591d5ab33 41 /// Initialize interrupt controller.
be_bryan 0:b74591d5ab33 42 __WEAK int32_t IRQ_Initialize (void) {
be_bryan 0:b74591d5ab33 43 uint32_t i;
be_bryan 0:b74591d5ab33 44
be_bryan 0:b74591d5ab33 45 for (i = 0U; i < IRQ_GIC_LINE_COUNT; i++) {
be_bryan 0:b74591d5ab33 46 IRQTable[i] = (IRQHandler_t)NULL;
be_bryan 0:b74591d5ab33 47 }
be_bryan 0:b74591d5ab33 48 GIC_Enable();
be_bryan 0:b74591d5ab33 49 return (0);
be_bryan 0:b74591d5ab33 50 }
be_bryan 0:b74591d5ab33 51
be_bryan 0:b74591d5ab33 52
be_bryan 0:b74591d5ab33 53 /// Register interrupt handler.
be_bryan 0:b74591d5ab33 54 __WEAK int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) {
be_bryan 0:b74591d5ab33 55 int32_t status;
be_bryan 0:b74591d5ab33 56
be_bryan 0:b74591d5ab33 57 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 58 IRQTable[irqn] = handler;
be_bryan 0:b74591d5ab33 59 status = 0;
be_bryan 0:b74591d5ab33 60 } else {
be_bryan 0:b74591d5ab33 61 status = -1;
be_bryan 0:b74591d5ab33 62 }
be_bryan 0:b74591d5ab33 63
be_bryan 0:b74591d5ab33 64 return (status);
be_bryan 0:b74591d5ab33 65 }
be_bryan 0:b74591d5ab33 66
be_bryan 0:b74591d5ab33 67
be_bryan 0:b74591d5ab33 68 /// Get the registered interrupt handler.
be_bryan 0:b74591d5ab33 69 __WEAK IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) {
be_bryan 0:b74591d5ab33 70 IRQHandler_t h;
be_bryan 0:b74591d5ab33 71
be_bryan 0:b74591d5ab33 72 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 73 h = IRQTable[irqn];
be_bryan 0:b74591d5ab33 74 } else {
be_bryan 0:b74591d5ab33 75 h = (IRQHandler_t)0;
be_bryan 0:b74591d5ab33 76 }
be_bryan 0:b74591d5ab33 77
be_bryan 0:b74591d5ab33 78 return (h);
be_bryan 0:b74591d5ab33 79 }
be_bryan 0:b74591d5ab33 80
be_bryan 0:b74591d5ab33 81
be_bryan 0:b74591d5ab33 82 /// Enable interrupt.
be_bryan 0:b74591d5ab33 83 __WEAK int32_t IRQ_Enable (IRQn_ID_t irqn) {
be_bryan 0:b74591d5ab33 84 int32_t status;
be_bryan 0:b74591d5ab33 85
be_bryan 0:b74591d5ab33 86 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 87 GIC_EnableIRQ ((IRQn_Type)irqn);
be_bryan 0:b74591d5ab33 88 status = 0;
be_bryan 0:b74591d5ab33 89 } else {
be_bryan 0:b74591d5ab33 90 status = -1;
be_bryan 0:b74591d5ab33 91 }
be_bryan 0:b74591d5ab33 92
be_bryan 0:b74591d5ab33 93 return (status);
be_bryan 0:b74591d5ab33 94 }
be_bryan 0:b74591d5ab33 95
be_bryan 0:b74591d5ab33 96
be_bryan 0:b74591d5ab33 97 /// Disable interrupt.
be_bryan 0:b74591d5ab33 98 __WEAK int32_t IRQ_Disable (IRQn_ID_t irqn) {
be_bryan 0:b74591d5ab33 99 int32_t status;
be_bryan 0:b74591d5ab33 100
be_bryan 0:b74591d5ab33 101 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 102 GIC_DisableIRQ ((IRQn_Type)irqn);
be_bryan 0:b74591d5ab33 103 status = 0;
be_bryan 0:b74591d5ab33 104 } else {
be_bryan 0:b74591d5ab33 105 status = -1;
be_bryan 0:b74591d5ab33 106 }
be_bryan 0:b74591d5ab33 107
be_bryan 0:b74591d5ab33 108 return (status);
be_bryan 0:b74591d5ab33 109 }
be_bryan 0:b74591d5ab33 110
be_bryan 0:b74591d5ab33 111
be_bryan 0:b74591d5ab33 112 /// Get interrupt enable state.
be_bryan 0:b74591d5ab33 113 __WEAK uint32_t IRQ_GetEnableState (IRQn_ID_t irqn) {
be_bryan 0:b74591d5ab33 114 uint32_t enable;
be_bryan 0:b74591d5ab33 115
be_bryan 0:b74591d5ab33 116 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 117 enable = GIC_GetEnableIRQ((IRQn_Type)irqn);
be_bryan 0:b74591d5ab33 118 } else {
be_bryan 0:b74591d5ab33 119 enable = 0U;
be_bryan 0:b74591d5ab33 120 }
be_bryan 0:b74591d5ab33 121
be_bryan 0:b74591d5ab33 122 return (enable);
be_bryan 0:b74591d5ab33 123 }
be_bryan 0:b74591d5ab33 124
be_bryan 0:b74591d5ab33 125
be_bryan 0:b74591d5ab33 126 /// Configure interrupt request mode.
be_bryan 0:b74591d5ab33 127 __WEAK int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode) {
be_bryan 0:b74591d5ab33 128 int32_t status;
be_bryan 0:b74591d5ab33 129 uint32_t val;
be_bryan 0:b74591d5ab33 130 uint8_t cfg;
be_bryan 0:b74591d5ab33 131 uint8_t secure;
be_bryan 0:b74591d5ab33 132 uint8_t cpu;
be_bryan 0:b74591d5ab33 133
be_bryan 0:b74591d5ab33 134 status = 0;
be_bryan 0:b74591d5ab33 135
be_bryan 0:b74591d5ab33 136 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 137 // Check triggering mode
be_bryan 0:b74591d5ab33 138 val = (mode & IRQ_MODE_TRIG_Msk);
be_bryan 0:b74591d5ab33 139
be_bryan 0:b74591d5ab33 140 if (val == IRQ_MODE_TRIG_LEVEL) {
be_bryan 0:b74591d5ab33 141 cfg = 0x00U;
be_bryan 0:b74591d5ab33 142 } else if (val == IRQ_MODE_TRIG_EDGE) {
be_bryan 0:b74591d5ab33 143 cfg = 0x02U;
be_bryan 0:b74591d5ab33 144 } else {
be_bryan 0:b74591d5ab33 145 status = -1;
be_bryan 0:b74591d5ab33 146 }
be_bryan 0:b74591d5ab33 147
be_bryan 0:b74591d5ab33 148 // Check interrupt type
be_bryan 0:b74591d5ab33 149 val = mode & IRQ_MODE_TYPE_Msk;
be_bryan 0:b74591d5ab33 150
be_bryan 0:b74591d5ab33 151 if (val != IRQ_MODE_TYPE_IRQ) {
be_bryan 0:b74591d5ab33 152 status = -1;
be_bryan 0:b74591d5ab33 153 }
be_bryan 0:b74591d5ab33 154
be_bryan 0:b74591d5ab33 155 // Check interrupt domain
be_bryan 0:b74591d5ab33 156 val = mode & IRQ_MODE_DOMAIN_Msk;
be_bryan 0:b74591d5ab33 157
be_bryan 0:b74591d5ab33 158 if (val == IRQ_MODE_DOMAIN_NONSECURE) {
be_bryan 0:b74591d5ab33 159 secure = 0;
be_bryan 0:b74591d5ab33 160 } else {
be_bryan 0:b74591d5ab33 161 // Check security extensions support
be_bryan 0:b74591d5ab33 162 val = GIC_DistributorInfo() & (1UL << 10U);
be_bryan 0:b74591d5ab33 163
be_bryan 0:b74591d5ab33 164 if (val != 0U) {
be_bryan 0:b74591d5ab33 165 // Security extensions are supported
be_bryan 0:b74591d5ab33 166 secure = 1;
be_bryan 0:b74591d5ab33 167 } else {
be_bryan 0:b74591d5ab33 168 status = -1;
be_bryan 0:b74591d5ab33 169 }
be_bryan 0:b74591d5ab33 170 }
be_bryan 0:b74591d5ab33 171
be_bryan 0:b74591d5ab33 172 // Check interrupt CPU targets
be_bryan 0:b74591d5ab33 173 val = mode & IRQ_MODE_CPU_Msk;
be_bryan 0:b74591d5ab33 174
be_bryan 0:b74591d5ab33 175 if (val == IRQ_MODE_CPU_ALL) {
be_bryan 0:b74591d5ab33 176 cpu = 0xFF;
be_bryan 0:b74591d5ab33 177 } else {
be_bryan 0:b74591d5ab33 178 cpu = val >> IRQ_MODE_CPU_Pos;
be_bryan 0:b74591d5ab33 179 }
be_bryan 0:b74591d5ab33 180
be_bryan 0:b74591d5ab33 181 // Apply configuration if no mode error
be_bryan 0:b74591d5ab33 182 if (status == 0) {
be_bryan 0:b74591d5ab33 183 GIC_SetConfiguration((IRQn_Type)irqn, cfg);
be_bryan 0:b74591d5ab33 184 GIC_SetTarget ((IRQn_Type)irqn, cpu);
be_bryan 0:b74591d5ab33 185
be_bryan 0:b74591d5ab33 186 if (secure != 0U) {
be_bryan 0:b74591d5ab33 187 GIC_SetGroup ((IRQn_Type)irqn, secure);
be_bryan 0:b74591d5ab33 188 }
be_bryan 0:b74591d5ab33 189 }
be_bryan 0:b74591d5ab33 190 }
be_bryan 0:b74591d5ab33 191
be_bryan 0:b74591d5ab33 192 return (status);
be_bryan 0:b74591d5ab33 193 }
be_bryan 0:b74591d5ab33 194
be_bryan 0:b74591d5ab33 195
be_bryan 0:b74591d5ab33 196 /// Get interrupt mode configuration.
be_bryan 0:b74591d5ab33 197 __WEAK uint32_t IRQ_GetMode (IRQn_ID_t irqn) {
be_bryan 0:b74591d5ab33 198 uint32_t mode;
be_bryan 0:b74591d5ab33 199 uint32_t val;
be_bryan 0:b74591d5ab33 200
be_bryan 0:b74591d5ab33 201 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 202 mode = IRQ_MODE_TYPE_IRQ;
be_bryan 0:b74591d5ab33 203
be_bryan 0:b74591d5ab33 204 // Get trigger mode
be_bryan 0:b74591d5ab33 205 val = GIC_GetConfiguration((IRQn_Type)irqn);
be_bryan 0:b74591d5ab33 206
be_bryan 0:b74591d5ab33 207 if ((val & 2U) != 0U) {
be_bryan 0:b74591d5ab33 208 // Corresponding interrupt is edge triggered
be_bryan 0:b74591d5ab33 209 mode |= IRQ_MODE_TRIG_EDGE;
be_bryan 0:b74591d5ab33 210 } else {
be_bryan 0:b74591d5ab33 211 // Corresponding interrupt is level triggered
be_bryan 0:b74591d5ab33 212 mode |= IRQ_MODE_TRIG_LEVEL;
be_bryan 0:b74591d5ab33 213 }
be_bryan 0:b74591d5ab33 214
be_bryan 0:b74591d5ab33 215 // Get interrupt CPU targets
be_bryan 0:b74591d5ab33 216 mode |= GIC_GetTarget ((IRQn_Type)irqn) << IRQ_MODE_CPU_Pos;
be_bryan 0:b74591d5ab33 217
be_bryan 0:b74591d5ab33 218 } else {
be_bryan 0:b74591d5ab33 219 mode = IRQ_MODE_ERROR;
be_bryan 0:b74591d5ab33 220 }
be_bryan 0:b74591d5ab33 221
be_bryan 0:b74591d5ab33 222 return (mode);
be_bryan 0:b74591d5ab33 223 }
be_bryan 0:b74591d5ab33 224
be_bryan 0:b74591d5ab33 225
be_bryan 0:b74591d5ab33 226 /// Get ID number of current interrupt request (IRQ).
be_bryan 0:b74591d5ab33 227 __WEAK IRQn_ID_t IRQ_GetActiveIRQ (void) {
be_bryan 0:b74591d5ab33 228 IRQn_ID_t irqn;
be_bryan 0:b74591d5ab33 229 uint32_t prio;
be_bryan 0:b74591d5ab33 230
be_bryan 0:b74591d5ab33 231 /* Dummy read to avoid GIC 390 errata 801120 */
be_bryan 0:b74591d5ab33 232 GIC_GetHighPendingIRQ();
be_bryan 0:b74591d5ab33 233
be_bryan 0:b74591d5ab33 234 irqn = GIC_AcknowledgePending();
be_bryan 0:b74591d5ab33 235
be_bryan 0:b74591d5ab33 236 __DSB();
be_bryan 0:b74591d5ab33 237
be_bryan 0:b74591d5ab33 238 /* Workaround GIC 390 errata 733075 (GIC-390_Errata_Notice_v6.pdf, 09-Jul-2014) */
be_bryan 0:b74591d5ab33 239 /* The following workaround code is for a single-core system. It would be */
be_bryan 0:b74591d5ab33 240 /* different in a multi-core system. */
be_bryan 0:b74591d5ab33 241 /* If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up */
be_bryan 0:b74591d5ab33 242 /* so unlock it, otherwise service the interrupt as normal. */
be_bryan 0:b74591d5ab33 243 /* Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 */
be_bryan 0:b74591d5ab33 244 /* so will not occur here. */
be_bryan 0:b74591d5ab33 245
be_bryan 0:b74591d5ab33 246 if ((irqn == 0) || (irqn >= 0x3FE)) {
be_bryan 0:b74591d5ab33 247 /* Unlock the CPU interface with a dummy write to Interrupt Priority Register */
be_bryan 0:b74591d5ab33 248 prio = GIC_GetPriority((IRQn_Type)0);
be_bryan 0:b74591d5ab33 249 GIC_SetPriority ((IRQn_Type)0, prio);
be_bryan 0:b74591d5ab33 250
be_bryan 0:b74591d5ab33 251 __DSB();
be_bryan 0:b74591d5ab33 252
be_bryan 0:b74591d5ab33 253 if ((irqn == 0U) && ((GIC_GetIRQStatus ((IRQn_Type)irqn) & 1U) != 0U) && (IRQ_ID0 == 0U)) {
be_bryan 0:b74591d5ab33 254 /* If the ID is 0, is active and has not been seen before */
be_bryan 0:b74591d5ab33 255 IRQ_ID0 = 1U;
be_bryan 0:b74591d5ab33 256 }
be_bryan 0:b74591d5ab33 257 /* End of Workaround GIC 390 errata 733075 */
be_bryan 0:b74591d5ab33 258 }
be_bryan 0:b74591d5ab33 259
be_bryan 0:b74591d5ab33 260 return (irqn);
be_bryan 0:b74591d5ab33 261 }
be_bryan 0:b74591d5ab33 262
be_bryan 0:b74591d5ab33 263
be_bryan 0:b74591d5ab33 264 /// Get ID number of current fast interrupt request (FIQ).
be_bryan 0:b74591d5ab33 265 __WEAK IRQn_ID_t IRQ_GetActiveFIQ (void) {
be_bryan 0:b74591d5ab33 266 return ((IRQn_ID_t)-1);
be_bryan 0:b74591d5ab33 267 }
be_bryan 0:b74591d5ab33 268
be_bryan 0:b74591d5ab33 269
be_bryan 0:b74591d5ab33 270 /// Signal end of interrupt processing.
be_bryan 0:b74591d5ab33 271 __WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) {
be_bryan 0:b74591d5ab33 272 int32_t status;
be_bryan 0:b74591d5ab33 273
be_bryan 0:b74591d5ab33 274 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 275 GIC_EndInterrupt ((IRQn_Type)irqn);
be_bryan 0:b74591d5ab33 276
be_bryan 0:b74591d5ab33 277 if (irqn == 0) {
be_bryan 0:b74591d5ab33 278 IRQ_ID0 = 0U;
be_bryan 0:b74591d5ab33 279 }
be_bryan 0:b74591d5ab33 280
be_bryan 0:b74591d5ab33 281 status = 0;
be_bryan 0:b74591d5ab33 282 } else {
be_bryan 0:b74591d5ab33 283 status = -1;
be_bryan 0:b74591d5ab33 284 }
be_bryan 0:b74591d5ab33 285
be_bryan 0:b74591d5ab33 286 return (status);
be_bryan 0:b74591d5ab33 287 }
be_bryan 0:b74591d5ab33 288
be_bryan 0:b74591d5ab33 289
be_bryan 0:b74591d5ab33 290 /// Set interrupt pending flag.
be_bryan 0:b74591d5ab33 291 __WEAK int32_t IRQ_SetPending (IRQn_ID_t irqn) {
be_bryan 0:b74591d5ab33 292 int32_t status;
be_bryan 0:b74591d5ab33 293
be_bryan 0:b74591d5ab33 294 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 295 GIC_SetPendingIRQ ((IRQn_Type)irqn);
be_bryan 0:b74591d5ab33 296 status = 0;
be_bryan 0:b74591d5ab33 297 } else {
be_bryan 0:b74591d5ab33 298 status = -1;
be_bryan 0:b74591d5ab33 299 }
be_bryan 0:b74591d5ab33 300
be_bryan 0:b74591d5ab33 301 return (status);
be_bryan 0:b74591d5ab33 302 }
be_bryan 0:b74591d5ab33 303
be_bryan 0:b74591d5ab33 304 /// Get interrupt pending flag.
be_bryan 0:b74591d5ab33 305 __WEAK uint32_t IRQ_GetPending (IRQn_ID_t irqn) {
be_bryan 0:b74591d5ab33 306 uint32_t pending;
be_bryan 0:b74591d5ab33 307
be_bryan 0:b74591d5ab33 308 if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 309 pending = GIC_GetPendingIRQ ((IRQn_Type)irqn);
be_bryan 0:b74591d5ab33 310 } else {
be_bryan 0:b74591d5ab33 311 pending = 0U;
be_bryan 0:b74591d5ab33 312 }
be_bryan 0:b74591d5ab33 313
be_bryan 0:b74591d5ab33 314 return (pending & 1U);
be_bryan 0:b74591d5ab33 315 }
be_bryan 0:b74591d5ab33 316
be_bryan 0:b74591d5ab33 317
be_bryan 0:b74591d5ab33 318 /// Clear interrupt pending flag.
be_bryan 0:b74591d5ab33 319 __WEAK int32_t IRQ_ClearPending (IRQn_ID_t irqn) {
be_bryan 0:b74591d5ab33 320 int32_t status;
be_bryan 0:b74591d5ab33 321
be_bryan 0:b74591d5ab33 322 if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 323 GIC_ClearPendingIRQ ((IRQn_Type)irqn);
be_bryan 0:b74591d5ab33 324 status = 0;
be_bryan 0:b74591d5ab33 325 } else {
be_bryan 0:b74591d5ab33 326 status = -1;
be_bryan 0:b74591d5ab33 327 }
be_bryan 0:b74591d5ab33 328
be_bryan 0:b74591d5ab33 329 return (status);
be_bryan 0:b74591d5ab33 330 }
be_bryan 0:b74591d5ab33 331
be_bryan 0:b74591d5ab33 332
be_bryan 0:b74591d5ab33 333 /// Set interrupt priority value.
be_bryan 0:b74591d5ab33 334 __WEAK int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority) {
be_bryan 0:b74591d5ab33 335 int32_t status;
be_bryan 0:b74591d5ab33 336
be_bryan 0:b74591d5ab33 337 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 338 GIC_SetPriority ((IRQn_Type)irqn, priority);
be_bryan 0:b74591d5ab33 339 status = 0;
be_bryan 0:b74591d5ab33 340 } else {
be_bryan 0:b74591d5ab33 341 status = -1;
be_bryan 0:b74591d5ab33 342 }
be_bryan 0:b74591d5ab33 343
be_bryan 0:b74591d5ab33 344 return (status);
be_bryan 0:b74591d5ab33 345 }
be_bryan 0:b74591d5ab33 346
be_bryan 0:b74591d5ab33 347
be_bryan 0:b74591d5ab33 348 /// Get interrupt priority.
be_bryan 0:b74591d5ab33 349 __WEAK uint32_t IRQ_GetPriority (IRQn_ID_t irqn) {
be_bryan 0:b74591d5ab33 350 uint32_t priority;
be_bryan 0:b74591d5ab33 351
be_bryan 0:b74591d5ab33 352 if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
be_bryan 0:b74591d5ab33 353 priority = GIC_GetPriority ((IRQn_Type)irqn);
be_bryan 0:b74591d5ab33 354 } else {
be_bryan 0:b74591d5ab33 355 priority = IRQ_PRIORITY_ERROR;
be_bryan 0:b74591d5ab33 356 }
be_bryan 0:b74591d5ab33 357
be_bryan 0:b74591d5ab33 358 return (priority);
be_bryan 0:b74591d5ab33 359 }
be_bryan 0:b74591d5ab33 360
be_bryan 0:b74591d5ab33 361
be_bryan 0:b74591d5ab33 362 /// Set priority masking threshold.
be_bryan 0:b74591d5ab33 363 __WEAK int32_t IRQ_SetPriorityMask (uint32_t priority) {
be_bryan 0:b74591d5ab33 364 GIC_SetInterfacePriorityMask (priority);
be_bryan 0:b74591d5ab33 365 return (0);
be_bryan 0:b74591d5ab33 366 }
be_bryan 0:b74591d5ab33 367
be_bryan 0:b74591d5ab33 368
be_bryan 0:b74591d5ab33 369 /// Get priority masking threshold
be_bryan 0:b74591d5ab33 370 __WEAK uint32_t IRQ_GetPriorityMask (void) {
be_bryan 0:b74591d5ab33 371 return GIC_GetInterfacePriorityMask();
be_bryan 0:b74591d5ab33 372 }
be_bryan 0:b74591d5ab33 373
be_bryan 0:b74591d5ab33 374
be_bryan 0:b74591d5ab33 375 /// Set priority grouping field split point
be_bryan 0:b74591d5ab33 376 __WEAK int32_t IRQ_SetPriorityGroupBits (uint32_t bits) {
be_bryan 0:b74591d5ab33 377 int32_t status;
be_bryan 0:b74591d5ab33 378
be_bryan 0:b74591d5ab33 379 if (bits == IRQ_PRIORITY_Msk) {
be_bryan 0:b74591d5ab33 380 bits = 7U;
be_bryan 0:b74591d5ab33 381 }
be_bryan 0:b74591d5ab33 382
be_bryan 0:b74591d5ab33 383 if (bits < 8U) {
be_bryan 0:b74591d5ab33 384 GIC_SetBinaryPoint (7U - bits);
be_bryan 0:b74591d5ab33 385 status = 0;
be_bryan 0:b74591d5ab33 386 } else {
be_bryan 0:b74591d5ab33 387 status = -1;
be_bryan 0:b74591d5ab33 388 }
be_bryan 0:b74591d5ab33 389
be_bryan 0:b74591d5ab33 390 return (status);
be_bryan 0:b74591d5ab33 391 }
be_bryan 0:b74591d5ab33 392
be_bryan 0:b74591d5ab33 393
be_bryan 0:b74591d5ab33 394 /// Get priority grouping field split point
be_bryan 0:b74591d5ab33 395 __WEAK uint32_t IRQ_GetPriorityGroupBits (void) {
be_bryan 0:b74591d5ab33 396 uint32_t bp;
be_bryan 0:b74591d5ab33 397
be_bryan 0:b74591d5ab33 398 bp = GIC_GetBinaryPoint() & 0x07U;
be_bryan 0:b74591d5ab33 399
be_bryan 0:b74591d5ab33 400 return (7U - bp);
be_bryan 0:b74591d5ab33 401 }
be_bryan 0:b74591d5ab33 402
be_bryan 0:b74591d5ab33 403 #endif