1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "hardware/irq.h"
8 #include "hardware/claim.h"
9 
10 // totally non-functional IRQ
11 
12 #if PICO_VTABLE_PER_CORE
13 static uint8_t user_irq_claimed[NUM_CORES];
user_irq_claimed_ptr(void)14 static inline uint8_t *user_irq_claimed_ptr(void) {
15     return &user_irq_claimed[get_core_num()];
16 }
17 #else
18 static uint8_t user_irq_claimed;
user_irq_claimed_ptr(void)19 static inline uint8_t *user_irq_claimed_ptr(void) {
20     return &user_irq_claimed;
21 }
22 #endif
23 
PICO_WEAK_FUNCTION_DEF(irq_set_enabled)24 PICO_WEAK_FUNCTION_DEF(irq_set_enabled)
25 void PICO_WEAK_FUNCTION_IMPL_NAME(irq_set_enabled)(uint num, bool enabled) {
26     panic_unsupported();
27 }
28 
PICO_WEAK_FUNCTION_DEF(irq_is_enabled)29 PICO_WEAK_FUNCTION_DEF(irq_is_enabled)
30 bool PICO_WEAK_FUNCTION_IMPL_NAME(irq_is_enabled)(uint num) {
31     return false;
32 }
33 
PICO_WEAK_FUNCTION_DEF(irq_set_mask_enabled)34 PICO_WEAK_FUNCTION_DEF(irq_set_mask_enabled)
35 void PICO_WEAK_FUNCTION_IMPL_NAME(irq_set_mask_enabled)(uint32_t mask, bool enabled) {
36     panic_unsupported();
37 }
38 
PICO_WEAK_FUNCTION_DEF(irq_set_mask_n_enabled)39 PICO_WEAK_FUNCTION_DEF(irq_set_mask_n_enabled)
40 void PICO_WEAK_FUNCTION_IMPL_NAME(irq_set_mask_n_enabled)(uint n, uint32_t mask, bool enabled) {
41     panic_unsupported();
42 }
43 
PICO_WEAK_FUNCTION_DEF(irq_set_pending)44 PICO_WEAK_FUNCTION_DEF(irq_set_pending)
45 void PICO_WEAK_FUNCTION_IMPL_NAME(irq_set_pending)(uint num) {
46     panic_unsupported();
47 }
48 
PICO_WEAK_FUNCTION_DEF(irq_has_shared_handler)49 PICO_WEAK_FUNCTION_DEF(irq_has_shared_handler)
50 bool PICO_WEAK_FUNCTION_IMPL_NAME(irq_has_shared_handler)(uint irq_num) {
51     return false;
52 }
53 
PICO_WEAK_FUNCTION_DEF(irq_get_vtable_handler)54 PICO_WEAK_FUNCTION_DEF(irq_get_vtable_handler)
55 irq_handler_t PICO_WEAK_FUNCTION_IMPL_NAME(irq_get_vtable_handler)(uint num) {
56     panic_unsupported();
57 }
58 
PICO_WEAK_FUNCTION_DEF(irq_set_exclusive_handler)59 PICO_WEAK_FUNCTION_DEF(irq_set_exclusive_handler)
60 void PICO_WEAK_FUNCTION_IMPL_NAME(irq_set_exclusive_handler)(uint num, irq_handler_t handler) {
61     panic_unsupported();
62 }
63 
PICO_WEAK_FUNCTION_DEF(irq_get_exclusive_handler)64 PICO_WEAK_FUNCTION_DEF(irq_get_exclusive_handler)
65 irq_handler_t PICO_WEAK_FUNCTION_IMPL_NAME(irq_get_exclusive_handler)(uint num) {
66     panic_unsupported();
67 }
68 
PICO_WEAK_FUNCTION_DEF(irq_add_shared_handler)69 PICO_WEAK_FUNCTION_DEF(irq_add_shared_handler)
70 void PICO_WEAK_FUNCTION_IMPL_NAME(irq_add_shared_handler)(uint num, irq_handler_t handler, uint8_t order_priority) {
71     panic_unsupported();
72 }
73 
PICO_WEAK_FUNCTION_DEF(irq_remove_handler)74 PICO_WEAK_FUNCTION_DEF(irq_remove_handler)
75 void PICO_WEAK_FUNCTION_IMPL_NAME(irq_remove_handler)(uint num, irq_handler_t handler) {
76     panic_unsupported();
77 }
78 
PICO_WEAK_FUNCTION_DEF(irq_set_priority)79 PICO_WEAK_FUNCTION_DEF(irq_set_priority)
80 void PICO_WEAK_FUNCTION_IMPL_NAME(irq_set_priority)(uint num, uint8_t hardware_priority) {
81     panic_unsupported();
82 }
83 
PICO_WEAK_FUNCTION_DEF(irq_get_priority)84 PICO_WEAK_FUNCTION_DEF(irq_get_priority)
85 uint PICO_WEAK_FUNCTION_IMPL_NAME(irq_get_priority)(uint num) {
86     panic_unsupported();
87 }
88 
PICO_WEAK_FUNCTION_DEF(irq_clear)89 PICO_WEAK_FUNCTION_DEF(irq_clear)
90 void PICO_WEAK_FUNCTION_IMPL_NAME(irq_clear)(uint int_num) {
91     panic_unsupported();
92 }
93 
PICO_WEAK_FUNCTION_DEF(irq_init_priorities)94 PICO_WEAK_FUNCTION_DEF(irq_init_priorities)
95 void PICO_WEAK_FUNCTION_IMPL_NAME(irq_init_priorities)() {
96 }
97 
get_user_irq_claim_index(uint irq_num)98 static uint get_user_irq_claim_index(uint irq_num) {
99     invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= NUM_IRQS);
100     // we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31
101     static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today.
102     return NUM_IRQS - irq_num  - 1u;
103 }
104 
PICO_WEAK_FUNCTION_DEF(user_irq_claim)105 PICO_WEAK_FUNCTION_DEF(user_irq_claim)
106 void PICO_WEAK_FUNCTION_IMPL_NAME(user_irq_claim)(uint irq_num) {
107     hw_claim_or_assert(user_irq_claimed_ptr(), get_user_irq_claim_index(irq_num), "User IRQ is already claimed");
108 }
109 
PICO_WEAK_FUNCTION_DEF(user_irq_unclaim)110 PICO_WEAK_FUNCTION_DEF(user_irq_unclaim)
111 void PICO_WEAK_FUNCTION_IMPL_NAME(user_irq_unclaim)(uint irq_num) {
112     hw_claim_clear(user_irq_claimed_ptr(), get_user_irq_claim_index(irq_num));
113 }
114 
PICO_WEAK_FUNCTION_DEF(user_irq_claim_unused)115 PICO_WEAK_FUNCTION_DEF(user_irq_claim_unused)
116 int PICO_WEAK_FUNCTION_IMPL_NAME(user_irq_claim_unused)(bool required) {
117     int bit = hw_claim_unused_from_range(user_irq_claimed_ptr(), required, 0, NUM_USER_IRQS - 1, "No user IRQs are available");
118     if (bit >= 0) bit =  (int)NUM_IRQS - bit - 1;
119     return bit;
120 }
121 
PICO_WEAK_FUNCTION_DEF(user_irq_is_claimed)122 PICO_WEAK_FUNCTION_DEF(user_irq_is_claimed)
123 bool PICO_WEAK_FUNCTION_IMPL_NAME(user_irq_is_claimed)(uint irq_num) {
124     return hw_is_claimed(user_irq_claimed_ptr(), get_user_irq_claim_index(irq_num));
125 }
126