NVIC_SetPriority

Comments

4 comments

  • Avatar
    Joe

    I believe Crosswork's CTL implementation of ctl_set_priority(..) is wrong.

    As a test example ... Use a Cortex M4 that has (__NVIC_PRIO_BITS equal to 4.

    The call to set irq 24 to priority 6 using the CTL would be ctl_set_priority(24, 6).

    Expanding into the CTL function as shown above ...

    void ctl_set_priority(int irq, int priority)
    {
        NVIC_SetPriority(irq, (1 << (__NVIC_PRIO_BITS - 1)) + priority);
    }

    1 << (__NVIC_PRIO_BITS - 1) equals 0x08  so the parameters being passed to the function   NVIC_SetPriority would be the irq value of 24 and the priority value of 0x08 + 0x06 which equals 14 or 0x0e.

    The following is from the Crosswork's V3 packages ....

    /** \brief  Set Interrupt Priority
    
        The function sets the priority of an interrupt.
    
        \note The priority cannot be set for every core interrupt.
    
        \param [in]      IRQn  Interrupt number.
        \param [in]  priority  Priority to set.
     */
    __STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
    {
      if((int32_t)IRQn < 0) {
        SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
      }
      else {
        NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
      }
    }

    So the inline function being called is ...

        NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
     

     

    (priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL is expanded ...

    0x0e << (8 - 4) === 0x0e << 4 === 0xe0

    In this example, the CTL code is setting the priority to a value of 14 when the request was to set it to a value of 6.

    Again -- the Crosswork's implementation of void ctl_set_priority(int irq, int priority) appears to be in error.

    If my analysis is correct -- the proper implementation should be

    void ctl_set_priority(int irq, int priority)
    {
        NVIC_SetPriority(irq, priority);
    }

    Thanks.

    Joe
    0
    Comment actions Permalink
  • Avatar
    Michael Johnson

    For cortex-m3/4/7 ctl priority interrupts have to be in the lowest half of the priority range. On a device with 4 priority bits priorities 8-15 are ctl interrupts, with PendSV set to the lowest 15. The highest priority interrupts 0-7 can be used for interrupts that don't require ctl. The ctl functions are trying to help with this.

    0
    Comment actions Permalink
  • Avatar
    Joe

    I do not remember any documentation that states the CTL set_priority function was taking the requested priority number and moving it into the priority range for the CTL.

     

    I say that because if I'm using the CTL but want to set an irq priority to 6 (actual 6 - not the CTL version of 6) ... I need to use the NVIC priority function NOT the CTL version .... again --- I don't remember seeing documentation stating that as a requirement.

    If it is stated somewhere -- sorry for bring up the question.

     

    Joe

    0
    Comment actions Permalink
  • Avatar
    Michael Johnson

    There are some words in the "Cortex-M implementation details" section. Use NVIC calls for non-ctl interrupts.

    0
    Comment actions Permalink

Please sign in to leave a comment.