]> begriffs open source - cmsis/blob - CMSIS/DoxyGen/Core_A/src/irq_ctrl.txt
CMSIS-Core(A): Enhanced documentation for new IRQ API.
[cmsis] / CMSIS / DoxyGen / Core_A / src / irq_ctrl.txt
1 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
2 //  ==== IRQ Controller API ====
3 /** 
4 \defgroup irq_ctrl_gr Interrupts and Exceptions
5 \brief Generic functions to access the Interrupt Controller.
6
7 \details This section describes the device agnostic interrupt API viable for a wide range of specific interrupt controllers.
8 The IRQ Controller API allows interrupt dependend applications to be easily portable across a wide range of controllers.
9
10 \note The default implementation for \ref GIC_functions "ARM GIC (Generic Interrupt Controller)" can be found in \ref irq_ctrl_gic.c.
11 It uses \c weak functions thus it can easily be overwritten by an alternative user implementation if needed.
12
13 The ARMv7-A architecture defines a common set of first level exceptions, see table below.
14
15 | Exception                     | CMSIS Handler | Offset | Description                                                                 |
16 |-------------------------------|---------------|--------|-----------------------------------------------------------------------------|
17 | Reset                         | Reset_Handler | 0x0000 | First instruction executed after reset.                                     |
18 | Undefined Instruction (Undef) | Undef_Handler | 0x0004 | Signals usage of an illegal instructions.                                   |
19 | Supervisor Call (SVC)         | SVC_Handler   | 0x0008 | Issued by software using SVC instruction.                                   |
20 | Prefetch Abort (PAbt)         | PAbt_Handler  | 0x000C | Signals a memory abort on istruction fetch.                                 |
21 | Data Abort (DAbt)             | DAbt_Handler  | 0x0010 | Signals a memory abort on data read or write.                               |
22 | Hyp Trap                      | (NOP)         | 0x0014 | Hypervisor instruction trap, only available with Virtualization Extensions. |
23 | IRQ interrupt                 | IRQ_Handler   | 0x0018 | Interrupt Request (typically from Interrupt Controller)                     |
24 | FIQ interrupt                 | FIQ_Handler   | 0x001C | Fast Interrupt Request (typically from Interrupt Controller)                |
25
26 By default those handlers are defined as weak empty functions by the \ref startup_c_sec "device specific startup code".
27 Software and peripheral interrupts are all handled by one of the both central interrupt handlers (IRQ and FIQ). These needs to
28 be implemented application specific. If an RTOS is used the interrupt handlers are typically provided by the RTOS, e.g. when using 
29 <a href="../../RTOS2/html/rtx5_impl.html">RTX5</a>.
30
31 The interrupts available depends on the actual device in use. According to CMSIS specification the interrupts are defined
32 as \ref IRQn_Type in \ref device_h_pg. Using the generic IRQ API one can easily enable and disable interrupts, set up priorities, modes 
33 and preemption rules, and register interrupt callbacks.
34
35 \b Example:
36
37 \code
38 void SGI0_Handler() {
39   /* 
40    * Handle Interrupt 
41    */
42   
43   IRQ_ClearPending((IRQn_ID_t)SGI0_IRQn);
44 }
45  
46 void main() {
47   /* Initialize the Interrupt Controller */
48   IRQ_Initialize();
49   
50   /* Register the user defined handler function */
51   IRQ_SetHandler((IRQn_ID_t)SGI0_IRQn, SGI0_Handler);  
52   
53   /* Set the priority considering the priority grouping */
54   const uint32_t subprio = IRQ_GetPriorityGroupBits();
55   IRQ_SetPriority((IRQn_ID_t)SGI0_IRQn, 1u << subprio);
56   
57   /* Set interrupt mode to falling edge */
58   IRQ_SetMode((IRQn_ID_t)SGI0_IRQn, IRQ_MODE_TYPE_IRQ | IRQ_MODE_CPU_0 | IRQ_MODE_TRIG_EDGE | IRQ_MODE_TRIG_EDGE_FALLING);
59   
60   IRQ_Enable((IRQn_ID_t)SGI0_IRQn);
61   
62   /* Trigger interrupt */
63   IRQ_SetPending((IRQn_ID_t)SGI0_IRQn);
64   
65   IRQ_Disable((IRQn_ID_t)SGI0_IRQn);
66 }
67 \endcode
68
69 @{
70 */
71
72 /**
73 \defgroup irq_mode_defs IRQ Mode Bit-Masks
74 \brief Configure interrupt line mode
75 \details
76 @{
77 The following codes are used as values for the parameter \em mode of the function \ref IRQ_SetMode to configure interrupt line mode.
78 They are also returned by the function \ref IRQ_GetMode when retrieving interrupt line mode.
79
80 The values of \b IRQ_MODE_TRIG_x definitions specify
81 The values of \b IRQ_MODE_TYPE_x definitions specify
82 The values of \b IRQ_MODE_DOMAIN_x definitions specify
83 The values of \b IRQ_MODE_CPU_x definitions specify
84
85 // Interrupt mode bit-masks
86 \def IRQ_MODE_TRIG_LEVEL
87 \def IRQ_MODE_TRIG_LEVEL_LOW
88 \def IRQ_MODE_TRIG_LEVEL_HIGH
89 \def IRQ_MODE_TRIG_EDGE
90 \def IRQ_MODE_TRIG_EDGE_RISING
91 \def IRQ_MODE_TRIG_EDGE_FALLING
92 \def IRQ_MODE_TRIG_EDGE_BOTH
93
94 \def IRQ_MODE_TYPE_IRQ
95 \def IRQ_MODE_TYPE_FIQ
96
97 \def IRQ_MODE_DOMAIN_NONSECURE
98 \def IRQ_MODE_DOMAIN_SECURE
99
100 \def IRQ_MODE_CPU_ALL
101 \def IRQ_MODE_CPU_0
102 \def IRQ_MODE_CPU_1
103 \def IRQ_MODE_CPU_2
104 \def IRQ_MODE_CPU_3
105 \def IRQ_MODE_CPU_4
106 \def IRQ_MODE_CPU_5
107 \def IRQ_MODE_CPU_6
108 \def IRQ_MODE_CPU_7
109
110 \def IRQ_MODE_ERROR
111 @}
112 */
113
114 /**
115 \defgroup irq_priority_defs IRQ Priority Bit-Masks
116 \brief Definitions used by interrupt priority functions.
117 \details
118 @{
119 The following values are used by the interrupt priority functions.
120
121 The value of \b IRQ_PRIORITY_Msk specifies maximum interrupt priority value and can be used as parameter for the functions
122 \ref IRQ_GetPriority and \ref IRQ_SetPriorityGroupBits to retrieve implementation specific priority values.
123
124 The value of \b IRQ_PRIORITY_ERROR is used by functions \ref IRQ_GetPriority, IRQ_GetPriorityMask and \ref IRQ_GetPriorityGroupBits
125 to signal function execution error.
126
127 \def IRQ_PRIORITY_Msk
128 \def IRQ_PRIORITY_ERROR
129 @}
130 */
131
132 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
133 /**
134 \fn int32_t IRQ_Initialize (void) 
135 \details This function initializes interrupt controller.
136
137 It disables all interrupt sources, clears all pending interrupts, sets interrupt priorities to highest priority and
138 configures priority mask to lowest priority. IRQ and FIQ signal lines should be enabled and all interrupt handlers should
139 be set to NULL.
140
141 For ARM GIC the default implementation looks like the following example:
142
143 \code
144 /// Number of implemented interrupt lines
145 #ifndef IRQ_GIC_LINE_COUNT
146 #define IRQ_GIC_LINE_COUNT      (1020U)
147 #endif
148  
149 static IRQHandler IRQTable[IRQ_GIC_LINE_COUNT] = { 0U };
150  
151 int32_t IRQ_Initialize (void) {
152   uint32_t i;
153  
154   for (i = 0U; i < IRQ_GIC_LINE_COUNT; i++) {
155     IRQTable[i] = (IRQHandler)NULL;
156   }
157   GIC_Enable();
158   return (0);
159 }
160 \endcode
161 */
162
163 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
164 /**
165 \fn int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) 
166 \details This function registers address of the interrupt handler callback function corresponding to the specified interrupt
167 ID number.
168
169 For ARM GIC the default implementation looks like the following example:
170
171 \code
172 int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) {
173   int32_t status;
174  
175   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
176     IRQTable[irqn] = handler;
177     status =  0;
178   } else {
179     status = -1;
180   }
181  
182   return (status);
183 }
184 \endcode
185 */
186
187 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
188 /**
189 \fn IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) 
190 \details This function retrieves address of the interrupt handler callback function corresponding to the specified interrupt
191 ID number.
192
193 For ARM GIC the default implementation looks like the following example:
194
195 \code
196 IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) {
197   IRQHandler h;
198  
199   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
200     h = IRQTable[irqn];
201   } else {
202     h = (IRQHandler_t)0;
203   }
204  
205   return (h);
206 }
207 \endcode
208 */
209
210 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
211 /**
212 \fn int32_t IRQ_Enable (IRQn_ID_t irqn)
213 \details This function enables forwarding of the corresponding interrupt to the CPU.
214
215 For ARM GIC the default implementation looks like the following example:
216
217 \code
218 int32_t IRQ_Enable (IRQn_ID_t irqn) {
219   int32_t status;
220  
221   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
222     GIC_EnableIRQ ((IRQn_Type)irqn);
223     status = 0;
224   } else {
225     status = -1;
226   }
227  
228   return (status);
229 }
230 \endcode
231 */
232
233 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
234 /**
235 \fn int32_t IRQ_Disable (IRQn_ID_t irqn)
236 \details This function disables forwarding of the corresponding interrupt to the CPU. 
237
238 For ARM GIC the default implementation looks like the following example:
239
240 \code
241 int32_t IRQ_Disable (IRQn_ID_t irqn) {
242   int32_t status;
243  
244   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
245     GIC_DisableIRQ ((IRQn_Type)irqn);
246     status = 0;
247   } else {
248     status = -1;
249   }
250  
251   return (status);
252 }
253 \endcode
254 */
255
256 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
257 /**
258 \fn uint32_t IRQ_GetEnableState (IRQn_ID_t irqn) 
259 \details This function retrieves the interrupt enable status of the interrupt identified by the irqn parameter.
260
261 Interrupt enable status can be either disabled (0) or enabled (1). Disabled status is returned for interrupts
262 which cannot be identified by irqn. 
263
264 For ARM GIC the default implementation looks like the following example:
265
266 \code
267 uint32_t IRQ_GetEnableState (IRQn_ID_t irqn) {
268   uint32_t enable;
269  
270   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
271     enable = GIC_GetEnableIRQ((IRQn_Type)irqn);
272   } else {
273     enable = 0U;
274   }
275  
276   return (enable);
277 }
278 \endcode
279 */
280
281 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
282 /**
283 \fn int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode)
284
285 \details This function configures the interrupt triggering mode, type, secure access and target CPUs of the interrupt
286 (see \ref irq_mode_defs) identified by the irqn parameter.
287
288 For ARM GIC the default implementation looks like the following example:
289
290 \code
291 int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode) {
292   int32_t status;
293   uint32_t val;
294   uint8_t cfg;
295   uint8_t secure;
296   uint8_t cpu;
297  
298   status = 0;
299  
300   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
301     // Check triggering mode
302     val = (mode & IRQ_MODE_TRIG_Msk);
303
304     if (val == IRQ_MODE_TRIG_LEVEL) {
305       cfg = 0x00U;
306     } else if (val == IRQ_MODE_TRIG_EDGE) {
307       cfg = 0x02U;
308     } else {
309       status = -1;
310     }
311  
312     // Check interrupt type
313     val = mode & IRQ_MODE_TYPE_Msk;
314  
315     if (val != IRQ_MODE_TYPE_IRQ) {
316       status = -1;
317     }
318  
319     // Check interrupt domain
320     val = mode & IRQ_MODE_DOMAIN_Msk;
321  
322     if (val == IRQ_MODE_DOMAIN_NONSECURE) {
323       secure = 0;
324     } else {
325       // Check security extensions support
326       val = GIC_DistributorInfo() & (1UL << 10U);
327  
328       if (val != 0U) {
329         // Security extensions are supported
330         secure = 1;
331       } else {
332         status = -1;
333       }
334     }
335  
336     // Check interrupt CPU targets
337     val = mode & IRQ_MODE_CPU_Msk;
338  
339     if (val == IRQ_MODE_CPU_ALL) {
340       cpu = 0xFF;
341     } else {
342       cpu = val >> IRQ_MODE_CPU_Pos;
343     }
344  
345     // Apply configuration if no mode error
346     if (status == 0) {
347       GIC_SetConfiguration((IRQn_Type)irqn, cfg);
348       GIC_SetTarget       ((IRQn_Type)irqn, cpu);
349  
350       if (secure != 0U) {
351         GIC_SetGroup ((IRQn_Type)irqn, secure);
352       }
353     }
354   }
355  
356   return (status);
357 }
358 \endcode
359 */
360
361 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
362 /**
363 \fn uint32_t IRQ_GetMode (IRQn_ID_t irqn)
364 \details This function retrieves interrupt mode configuration of the interrupt identified by the irqn parameter.
365 \ref IRQ_MODE_ERROR is returned for interrupts which cannot be identified by irqn.
366
367 For ARM GIC the default implementation looks like the following example:
368
369 \code
370 uint32_t IRQ_GetMode (IRQn_ID_t irqn) {
371   uint32_t mode;
372   uint32_t val;
373  
374   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
375     mode = IRQ_MODE_TYPE_IRQ;
376  
377     // Get trigger mode
378     val = GIC_GetConfiguration((IRQn_Type)irqn);
379  
380     if ((val & 2U) != 0U) {
381       // Corresponding interrupt is edge triggered
382       mode |= IRQ_MODE_TRIG_EDGE;
383     } else {
384       // Corresponding interrupt is level triggered
385       mode |= IRQ_MODE_TRIG_LEVEL;
386     }
387  
388     // Get interrupt CPU targets
389     mode |= GIC_GetTarget ((IRQn_Type)irqn) << IRQ_MODE_CPU_Pos;
390  
391   } else {
392     mode = IRQ_MODE_ERROR;
393   }
394  
395   return (mode);
396 }
397 \endcode
398 */
399
400 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
401 /**
402 \fn IRQn_ID_t IRQ_GetActiveIRQ (void)
403 \details This function retrieves the interrupt ID number of current IRQ source and acknowledges the interrupt. 
404
405 For ARM GIC the default implementation looks like the following example:
406
407 \code
408 IRQn_ID_t IRQ_GetActiveIRQ (void) {
409   IRQn_ID_t irqn;
410  
411   irqn = (IRQn_ID_t)GIC_AcknowledgePending();
412  
413   return (irqn);
414 }
415 \endcode
416 */
417
418 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
419 /**
420 \fn IRQn_ID_t IRQ_GetActiveFIQ (void)
421 \details This function retrieves the interrupt ID number of current FIQ source and acknowledges the interrupt.
422
423 For ARM GIC the default implementation looks like the following example:
424
425 \code
426 IRQn_ID_t IRQ_GetActiveFIQ (void) {
427   // FIQ is not supported, return invalid ID
428   return ((IRQn_ID_t)-1);
429 }
430 \endcode
431 */
432
433 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
434 /**
435 \fn int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn)
436 \details This function informs the interrupt controller that the interrupt service routine processing of the currently
437 active interrupt request is completed.
438
439 The parameter irqn should specify the value previously returned by the \ref IRQ_GetActiveIRQ or \ref IRQ_GetActiveFIQ functions.
440
441 For ARM GIC the default implementation looks like the following example:
442
443 \code
444 int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) {
445   int32_t status;
446  
447   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
448     GIC_EndInterrupt ((IRQn_Type)irqn);
449  
450     if (irqn == 0) {
451       IRQ_ID0 = 0U;
452     }
453  
454     status = 0;
455   } else {
456     status = -1;
457   }
458  
459   return (status);
460 }
461 \endcode
462 */
463
464 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
465 /**
466 \fn int32_t IRQ_SetPending (IRQn_ID_t irqn) 
467 \details This function sets the pending status of the interrupt identified by the irqn parameter.
468
469 For ARM GIC the default implementation looks like the following example:
470
471 \code
472 int32_t IRQ_SetPending (IRQn_ID_t irqn) {
473   int32_t status;
474  
475   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
476     GIC_SetPendingIRQ ((IRQn_Type)irqn);
477     status = 0;
478   } else {
479     status = -1;
480   }
481  
482   return (status);
483 }
484 \endcode
485 */
486
487 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
488 /**
489 \fn uint32_t IRQ_GetPending (IRQn_ID_t irqn)
490 \details This function retrieves the pending status of the interrupt identified by the irqn parameter.
491
492 Interrupt pending status can be either not pending (0) or pending (1). Not pending status is returned for interrupts which
493 cannot be identified by irqn.
494
495 For ARM GIC the default implementation looks like the following example:
496
497 \code
498 uint32_t IRQ_GetPending (IRQn_ID_t irqn) {
499   uint32_t pending;
500  
501   if ((irqn >= 16) && (irqn < IRQ_GIC_LINE_COUNT)) {
502     pending = GIC_GetPendingIRQ ((IRQn_Type)irqn);
503   } else {
504     pending = 0U;
505   }
506  
507   return (pending & 1U);
508 }
509 \endcode
510 */
511
512 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
513 /**
514 \fn int32_t IRQ_ClearPending (IRQn_ID_t irqn) 
515 \details This function clears the pending status of the interrupt identified by the irqn parameter.
516
517 For ARM GIC the default implementation looks like the following example:
518
519 \code
520 int32_t IRQ_ClearPending (IRQn_ID_t irqn) {
521   int32_t status;
522  
523   if ((irqn >= 16) && (irqn < IRQ_GIC_LINE_COUNT)) {
524     GIC_ClearPendingIRQ ((IRQn_Type)irqn);
525     status = 0;
526   } else {
527     status = -1;
528   }
529  
530   return (status);
531 }
532 \endcode
533 */
534
535 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
536 /**
537 \fn int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority)
538 \details This function sets the priority of the interrupt identified by the irqn parameter.
539
540 Higher priority numbers have lower priority. The highest interrupt priority has priority value 0, while the lowest value
541 depends on the number of implemented priority levels.
542
543 The number of implemented priority bits can be determined by setting value \ref IRQ_PRIORITY_Msk to arbitrary irqn and by
544 retrieving the actual stored value with IRQ_GetPriority function.
545
546 For ARM GIC the default implementation looks like the following example:
547
548 \code
549 int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority) {
550   int32_t status;
551  
552   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
553     GIC_SetPriority ((IRQn_Type)irqn, priority);
554     status = 0;
555   } else {
556     status = -1;
557   }
558  
559   return (status);
560 }
561 \endcode
562 */
563
564 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
565 /**
566 \fn uint32_t IRQ_GetPriority (IRQn_ID_t irqn) 
567 \details This function retrieves the priority of the interrupt identified by the irqn parameter.
568
569 The valid priority value can be from zero (0) to the value of \ref IRQ_PRIORITY_Msk. \ref IRQ_PRIORITY_ERROR bit is set in
570 returned value for interrupts which cannot be identified by irqn.
571
572 For ARM GIC the default implementation looks like the following example:
573
574 \code
575 uint32_t IRQ_GetPriority (IRQn_ID_t irqn) {
576   uint32_t priority;
577  
578   if ((irqn >= 0) && (irqn < IRQ_GIC_LINE_COUNT)) {
579     priority = GIC_GetPriority ((IRQn_Type)irqn);
580   } else {
581     priority = IRQ_PRIORITY_ERROR;
582   }
583  
584   return (priority);
585 }
586 \endcode
587 */
588
589 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
590 /**
591 \fn int32_t IRQ_SetPriorityMask (uint32_t priority) 
592 \details This function sets the priority masking threshold for the current processor.
593
594 It ensures that only interrupts with a higher priority than priority threshold value are signaled to the target processor.
595 Function returns error status -1 if priority masking is not supported.
596
597 For ARM GIC the default implementation looks like the following example:
598
599 \code
600 IRQ_SetPriorityMask (uint32_t priority) {
601   GIC_SetInterfacePriorityMask (priority);
602   return (0);
603 }
604 \endcode
605 */
606
607 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
608 /**
609 \fn uint32_t IRQ_GetPriorityMask (void)
610 \details This function retrieves the priority masking threshold for the current processor.
611
612 \ref IRQ_PRIORITY_ERROR value is returned if priority masking is not supported.
613
614 For ARM GIC the default implementation looks like the following example:
615
616 \code
617 uint32_t IRQ_GetPriorityMask (void) {
618   return GIC_GetInterfacePriorityMask();
619 }
620 \endcode
621 */
622
623 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
624 /**
625 \fn int32_t IRQ_SetPriorityGroupBits (uint32_t bits)
626 \details This function sets the number of MSB priority bits used to determine whether a pending interrupt has sufficient
627 priority to preempt a currently active interrupt.
628
629 The number of implemented group priority bits can be determined by setting value \ref IRQ_PRIORITY_Msk and by retrieving the
630 actual stored value with \ref IRQ_GetPriorityGroupBits function.
631 Function returns error status -1 if priority grouping is not supported.
632
633 For ARM GIC the default implementation looks like the following example:
634
635 \code
636 int32_t IRQ_SetPriorityGroupBits (uint32_t bits) {
637   int32_t status;
638  
639   if (bits < 8U) {
640     GIC_SetBinaryPoint (bits);
641     status = 0;
642   } else {
643     status = -1;
644   }
645  
646   return (status);
647 }
648 \endcode
649 */
650
651 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
652 /**
653 \fn uint32_t IRQ_GetPriorityGroupBits (void) 
654 \details This function retrieves the number of MSB bits used to determine whether a pending interrupt has sufficient
655 priority to preempt a currently active interrupt.
656
657 \ref IRQ_PRIORITY_ERROR value is returned when priority grouping is not supported.
658
659 For ARM GIC the default implementation looks like the following example:
660
661 \code
662 uint32_t IRQ_GetPriorityGroupBits (void) {
663   return (GIC_GetBinaryPoint() & 0x07U);
664 }
665 \endcode
666 */
667
668 /** @} */ /* group irq_ctrl_gr */