add irq_get_priority method - improve efficiency of irq_init_priorities (#609)

This commit is contained in:
Graham Sanderson 2021-10-12 09:04:04 -05:00 committed by GitHub
parent 4c9ba3e8ad
commit 9f1c37318b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 6 deletions

View File

@ -119,6 +119,10 @@ extern "C" {
*/ */
typedef void (*irq_handler_t)(void); typedef void (*irq_handler_t)(void);
static inline void check_irq_param(__unused uint num) {
invalid_params_if(IRQ, num >= NUM_IRQS);
}
/*! \brief Set specified interrupt's priority /*! \brief Set specified interrupt's priority
* \ingroup hardware_irq * \ingroup hardware_irq
* *
@ -133,6 +137,21 @@ typedef void (*irq_handler_t)(void);
*/ */
void irq_set_priority(uint num, uint8_t hardware_priority); void irq_set_priority(uint num, uint8_t hardware_priority);
/*! \brief Get specified interrupt's priority
* \ingroup hardware_irq
*
* Numerically-lower values indicate a higher priority. Hardware priorities
* range from 0 (highest priority) to 255 (lowest priority) though only the
* top 2 bits are significant on ARM Cortex-M0+. To make it easier to specify
* higher or lower priorities than the default, all IRQ priorities are
* initialized to PICO_DEFAULT_IRQ_PRIORITY by the SDK runtime at startup.
* PICO_DEFAULT_IRQ_PRIORITY defaults to 0x80
*
* \param num Interrupt number
* \return the IRQ priority
*/
uint irq_get_priority(uint num);
/*! \brief Enable or disable a specific interrupt on the executing core /*! \brief Enable or disable a specific interrupt on the executing core
* \ingroup hardware_irq * \ingroup hardware_irq
* *

View File

@ -33,10 +33,6 @@ static void set_raw_irq_handler_and_unlock(uint num, irq_handler_t handler, uint
spin_unlock(spin_lock_instance(PICO_SPINLOCK_ID_IRQ), save); spin_unlock(spin_lock_instance(PICO_SPINLOCK_ID_IRQ), save);
} }
static inline void check_irq_param(__unused uint num) {
invalid_params_if(IRQ, num >= NUM_IRQS);
}
void irq_set_enabled(uint num, bool enabled) { void irq_set_enabled(uint num, bool enabled) {
check_irq_param(num); check_irq_param(num);
irq_set_mask_enabled(1u << num, enabled); irq_set_mask_enabled(1u << num, enabled);
@ -364,6 +360,14 @@ 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)));
} }
uint irq_get_priority(uint num) {
check_irq_param(num);
// note that only 32 bit reads are supported
io_rw_32 *p = (io_rw_32 *)((PPB_BASE + M0PLUS_NVIC_IPR0_OFFSET) + (num & ~3u));
return (uint8_t)(*p >> (8 * (num & 3u)));
}
#if !PICO_DISABLE_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)
@ -400,8 +404,11 @@ void irq_add_tail_to_free_list(struct irq_handler_chain_slot *slot) {
void irq_init_priorities() { void irq_init_priorities() {
#if PICO_DEFAULT_IRQ_PRIORITY != 0 #if PICO_DEFAULT_IRQ_PRIORITY != 0
for (uint irq = 0; irq < NUM_IRQS; irq++) { static_assert(!(NUM_IRQS & 3), "");
irq_set_priority(irq, PICO_DEFAULT_IRQ_PRIORITY); uint32_t prio4 = (PICO_DEFAULT_IRQ_PRIORITY & 0xff) * 0x1010101u;
io_rw_32 * p = (io_rw_32 *)(PPB_BASE + M0PLUS_NVIC_IPR0_OFFSET);
for (uint i = 0; i < NUM_IRQS / 4; i++) {
*p++ = prio4;
} }
#endif #endif
} }