Better support for PICO_DISABLE_SHARED_IRQ_HANDLERS (#496)
* use PICO_DISABLE_SHARED_IRQ_HANDLERS exclusively as config for no shared handler support (rather than also PICO_MAX_SHARED_IRQ_HANDLERS == 0) additionally make irq_add_shared_irq_handler() call irq_set_exclusive_handler() so that single usage of an IRQ still works * Comment typo Co-authored-by: Luke Wren <wren6991@gmail.com>
This commit is contained in:
		@ -63,7 +63,7 @@ void irq_set_pending(uint num) {
 | 
				
			|||||||
    *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ISPR_OFFSET)) = 1u << num;
 | 
					    *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ISPR_OFFSET)) = 1u << num;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if PICO_MAX_SHARED_IRQ_HANDLERS
 | 
					#if !PICO_DISABLE_SHARED_IRQ_HANDLERS
 | 
				
			||||||
// limited by 8 bit relative links (and reality)
 | 
					// limited by 8 bit relative links (and reality)
 | 
				
			||||||
static_assert(PICO_MAX_SHARED_IRQ_HANDLERS >= 1 && PICO_MAX_SHARED_IRQ_HANDLERS < 0x7f, "");
 | 
					static_assert(PICO_MAX_SHARED_IRQ_HANDLERS >= 1 && PICO_MAX_SHARED_IRQ_HANDLERS < 0x7f, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -92,11 +92,13 @@ extern struct irq_handler_chain_slot {
 | 
				
			|||||||
} irq_handler_chain_slots[PICO_MAX_SHARED_IRQ_HANDLERS];
 | 
					} irq_handler_chain_slots[PICO_MAX_SHARED_IRQ_HANDLERS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int8_t irq_hander_chain_free_slot_head;
 | 
					static int8_t irq_hander_chain_free_slot_head;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline bool is_shared_irq_raw_handler(irq_handler_t raw_handler) {
 | 
					static inline bool is_shared_irq_raw_handler(irq_handler_t raw_handler) {
 | 
				
			||||||
    return (uintptr_t)raw_handler - (uintptr_t)irq_handler_chain_slots < sizeof(irq_handler_chain_slots);
 | 
					    return (uintptr_t)raw_handler - (uintptr_t)irq_handler_chain_slots < sizeof(irq_handler_chain_slots);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define is_shared_irq_raw_handler(h) false
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
irq_handler_t irq_get_vtable_handler(uint num) {
 | 
					irq_handler_t irq_get_vtable_handler(uint num) {
 | 
				
			||||||
    check_irq_param(num);
 | 
					    check_irq_param(num);
 | 
				
			||||||
@ -133,6 +135,7 @@ irq_handler_t irq_get_exclusive_handler(uint num) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !PICO_DISABLE_SHARED_IRQ_HANDLERS
 | 
				
			||||||
static uint16_t make_branch(uint16_t *from, void *to) {
 | 
					static uint16_t make_branch(uint16_t *from, void *to) {
 | 
				
			||||||
    uint32_t ui_from = (uint32_t)from;
 | 
					    uint32_t ui_from = (uint32_t)from;
 | 
				
			||||||
    uint32_t ui_to = (uint32_t)to;
 | 
					    uint32_t ui_to = (uint32_t)to;
 | 
				
			||||||
@ -179,18 +182,18 @@ static inline int8_t slot_diff(struct irq_handler_chain_slot *to, struct irq_han
 | 
				
			|||||||
static inline int8_t get_slot_index(struct irq_handler_chain_slot *slot) {
 | 
					static inline int8_t get_slot_index(struct irq_handler_chain_slot *slot) {
 | 
				
			||||||
    return slot_diff(slot, irq_handler_chain_slots);
 | 
					    return slot_diff(slot, irq_handler_chain_slots);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority) {
 | 
					void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority) {
 | 
				
			||||||
    check_irq_param(num);
 | 
					    check_irq_param(num);
 | 
				
			||||||
#if PICO_DISABLE_SHARED_IRQ_HANDLERS
 | 
					#if PICO_NO_RAM_VECTOR_TABLE
 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#if PICO_NO_RAM_VECTOR_TABLE || !PICO_MAX_SHARED_IRQ_HANDLERS
 | 
					 | 
				
			||||||
    panic_unsupported()
 | 
					    panic_unsupported()
 | 
				
			||||||
 | 
					#elif PICO_DISABLE_SHARED_IRQ_HANDLERS
 | 
				
			||||||
 | 
					    irq_set_exclusive_handler(num, handler);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    spin_lock_t *lock = spin_lock_instance(PICO_SPINLOCK_ID_IRQ);
 | 
					    spin_lock_t *lock = spin_lock_instance(PICO_SPINLOCK_ID_IRQ);
 | 
				
			||||||
    uint32_t save = spin_lock_blocking(lock);
 | 
					    uint32_t save = spin_lock_blocking(lock);
 | 
				
			||||||
    hard_assert(irq_hander_chain_free_slot_head >= 0);
 | 
					    hard_assert(irq_hander_chain_free_slot_head >= 0); // we must have a slot
 | 
				
			||||||
    struct irq_handler_chain_slot *slot = &irq_handler_chain_slots[irq_hander_chain_free_slot_head];
 | 
					    struct irq_handler_chain_slot *slot = &irq_handler_chain_slots[irq_hander_chain_free_slot_head];
 | 
				
			||||||
    int8_t slot_index = irq_hander_chain_free_slot_head;
 | 
					    int8_t slot_index = irq_hander_chain_free_slot_head;
 | 
				
			||||||
    irq_hander_chain_free_slot_head = slot->link;
 | 
					    irq_hander_chain_free_slot_head = slot->link;
 | 
				
			||||||
@ -261,7 +264,7 @@ void irq_remove_handler(uint num, irq_handler_t handler) {
 | 
				
			|||||||
    uint32_t save = spin_lock_blocking(lock);
 | 
					    uint32_t save = spin_lock_blocking(lock);
 | 
				
			||||||
    irq_handler_t vtable_handler = get_vtable()[16 + num];
 | 
					    irq_handler_t vtable_handler = get_vtable()[16 + num];
 | 
				
			||||||
    if (vtable_handler != __unhandled_user_irq && vtable_handler != handler) {
 | 
					    if (vtable_handler != __unhandled_user_irq && vtable_handler != handler) {
 | 
				
			||||||
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && PICO_MAX_SHARED_IRQ_HANDLERS
 | 
					#if !PICO_DISABLE_SHARED_IRQ_HANDLERS
 | 
				
			||||||
        if (is_shared_irq_raw_handler(vtable_handler)) {
 | 
					        if (is_shared_irq_raw_handler(vtable_handler)) {
 | 
				
			||||||
            // This is a bit tricky, as an executing IRQ handler doesn't take a lock.
 | 
					            // This is a bit tricky, as an executing IRQ handler doesn't take a lock.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -361,7 +364,7 @@ void irq_set_priority(uint num, uint8_t hardware_priority) {
 | 
				
			|||||||
    *p = (*p & ~(0xffu << (8 * (num & 3u)))) | (((uint32_t) hardware_priority) << (8 * (num & 3u)));
 | 
					    *p = (*p & ~(0xffu << (8 * (num & 3u)))) | (((uint32_t) hardware_priority) << (8 * (num & 3u)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && PICO_MAX_SHARED_IRQ_HANDLERS
 | 
					#if !PICO_DISABLE_SHARED_IRQ_HANDLERS
 | 
				
			||||||
// used by irq_handler_chain.S to remove the last link in a handler chain after it executes
 | 
					// used by irq_handler_chain.S to remove the last link in a handler chain after it executes
 | 
				
			||||||
// note this must be called only with the last slot in a chain (and during the exception)
 | 
					// note this must be called only with the last slot in a chain (and during the exception)
 | 
				
			||||||
void irq_add_tail_to_free_list(struct irq_handler_chain_slot *slot) {
 | 
					void irq_add_tail_to_free_list(struct irq_handler_chain_slot *slot) {
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user