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);
static inline void check_irq_param(__unused uint num) {
invalid_params_if(IRQ, num >= NUM_IRQS);
}
/*! \brief Set specified interrupt's priority
* \ingroup hardware_irq
*
@ -133,6 +137,21 @@ typedef void (*irq_handler_t)(void);
*/
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
* \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);
}
static inline void check_irq_param(__unused uint num) {
invalid_params_if(IRQ, num >= NUM_IRQS);
}
void irq_set_enabled(uint num, bool enabled) {
check_irq_param(num);
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)));
}
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
// 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)
@ -400,8 +404,11 @@ void irq_add_tail_to_free_list(struct irq_handler_chain_slot *slot) {
void irq_init_priorities() {
#if PICO_DEFAULT_IRQ_PRIORITY != 0
for (uint irq = 0; irq < NUM_IRQS; irq++) {
irq_set_priority(irq, PICO_DEFAULT_IRQ_PRIORITY);
static_assert(!(NUM_IRQS & 3), "");
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
}