nRF54L15: high current consumption after using FPU, need information about FPU_IRQn interrupt vector.

Hi,

i am working on a project using the nRF54L15.

Hardware: custom board with nRF54L15

Software:

  • Wirepas SDK (1.6.2) 
  • nrfx drivers (version 3.9.0) with some customization to integrate it into the SDK
  • CMSIS DSP floating point libraries (Version 5.1)

I see in my current measurements that idle current increases by roughly 300µA after using the floating point unit. I already checked the developer zone for any similar tickets, and there are lots of them, though all are for other SoC, like nRF52 series. 

Most of these tickets suggest the high current consumption comes from unhandled FPU interrupts. I was already able to confirm that this is indeed the reason for the increased current. Now i'm trying to implement a solution for this.

The suggested solution from other tickets is to do something like the code below:

__STATIC_INLINE void pwr_mgmt_fpu_sleep_prepare(void)
     {
        uint32_t original_fpscr;

        CRITICAL_REGION_ENTER();
        original_fpscr = __get_FPSCR();
        /*
         * Clear FPU exceptions.
         * Without this step, the FPU interrupt is marked as pending,
         * preventing system from sleeping. Exceptions cleared:
         * - IOC - Invalid Operation cumulative exception bit.
         * - DZC - Division by Zero cumulative exception bit.
         * - OFC - Overflow cumulative exception bit.
         * - UFC - Underflow cumulative exception bit.
         * - IXC - Inexact cumulative exception bit.
         * - IDC - Input Denormal cumulative exception bit.
         */
        __set_FPSCR(original_fpscr & ~0x9Fu);
        __DMB();
        NVIC_ClearPendingIRQ(FPU_IRQn);
        CRITICAL_REGION_EXIT();

        /*
         * The last chance to indicate an error in FPU to the user 
         * as the FPSCR is now cleared
         *
         * This assert is related to previous FPU operations 
         * and not power management.
         *
         * Critical FPU exceptions signaled:
         * - IOC - Invalid Operation cumulative exception bit.
         * - DZC - Division by Zero cumulative exception bit.
         * - OFC - Overflow cumulative exception bit.
         */
        ASSERT((original_fpscr & 0x7) == 0);
     }

That is, 1. clear the FPU exception bits in FPSCR, 2. clear the pending IRQ with NVIC_ClearPendingIRQ(FPU_IRQn);

Which brings me to my problem. I can't find any definition for FPU_IRQn for the nRF54L15, neither in the Nordic Documentation nor in any of the processor header files.

For other SoCs FPU_IRQn is defined as an enum value in IRQn_Type. For the nRF54L15, in nrf54l15_application.h there is a similar type definition for IRQn_Type, but it does not contain the FPU_IRQn.

Maybe it is just named differently? 

So my question is: how do i clear the pending IRQ for the FPU on the nRF54L15?

Best regards

Frank Viganske

Parents
  • Hello Frank,

    I got feedback from team. 

    We need to know how have you used FPU in the application. Is this something like the following steps?

    1. CPU wakeup
    2. enable FPU
    3. perform calculations involving FPU
    4. disable FPU
    5. go to sleep

    Thanks.

    BR
    Kazi

  • Hi Kazi,

    1. I have a periodic task that wakes up the CPU once per second. This task checks if a measurement with the onboard sensors has to be done. If not, it will do only some housekeeping stuff and go to sleep again almost immediately.
    2. If the conditions for a measurement are fulfilled, data from some onboard sensors are collected and various calculations have to be done with that data. For these calculations the FPU is used. I was not sure if i had to explictly activate the FPU in my code first, but on a previous project with the nRF52840 it was necessary to enable access to the FPU before first use. So i "borrowed" this piece of code from my previous project: 
      	#if (__FPU_USED == 1ul)
      		SCB->CPACR |= (3UL << 20ul) | (3UL << 22ul);
      		__DSB();
      		__ISB();
      	#endif
      
      It seems to be unnecessary though, because when i comment this out the FPU access still works. I guess this initialization is already done somewhere in the startup code of the Wirepas network firmware. 
    3. For my calculations i use mainly the CMSIS-DSP library with FPU support. The floating point related compiler options are set as follows: -mfloat-abi=hard -mfpu=fpv5-sp-d16 -DARM_MATH_ARMV8MML -D__FPU_PRESENT=1  
    4. After calculations are finished, I do not disable the FPU. I don't know if that is even possible, i did not find anything about that. But it seems to make no difference for the current consumption. Once I have cleared any pending FPU exception bits in the FPSCR the current will go back to its normal level.
    5. After I return from my task, the System will go to sleep, until the next wakeup event.

    It is only one type of FPU exception that i get: regularly, the "Inexact floating point exception" FPUIXC. Seems kind of logical, since floating point precision is limited and you can't avoid that you lose some bits when results are rounded. And for our application an "inexact" result is not an issue. It would be nice if i could just disable that exception. But the CPUC->INTEN register can't do the trick, i already tried that.

    Best regards

    Frank

     

Reply
  • Hi Kazi,

    1. I have a periodic task that wakes up the CPU once per second. This task checks if a measurement with the onboard sensors has to be done. If not, it will do only some housekeeping stuff and go to sleep again almost immediately.
    2. If the conditions for a measurement are fulfilled, data from some onboard sensors are collected and various calculations have to be done with that data. For these calculations the FPU is used. I was not sure if i had to explictly activate the FPU in my code first, but on a previous project with the nRF52840 it was necessary to enable access to the FPU before first use. So i "borrowed" this piece of code from my previous project: 
      	#if (__FPU_USED == 1ul)
      		SCB->CPACR |= (3UL << 20ul) | (3UL << 22ul);
      		__DSB();
      		__ISB();
      	#endif
      
      It seems to be unnecessary though, because when i comment this out the FPU access still works. I guess this initialization is already done somewhere in the startup code of the Wirepas network firmware. 
    3. For my calculations i use mainly the CMSIS-DSP library with FPU support. The floating point related compiler options are set as follows: -mfloat-abi=hard -mfpu=fpv5-sp-d16 -DARM_MATH_ARMV8MML -D__FPU_PRESENT=1  
    4. After calculations are finished, I do not disable the FPU. I don't know if that is even possible, i did not find anything about that. But it seems to make no difference for the current consumption. Once I have cleared any pending FPU exception bits in the FPSCR the current will go back to its normal level.
    5. After I return from my task, the System will go to sleep, until the next wakeup event.

    It is only one type of FPU exception that i get: regularly, the "Inexact floating point exception" FPUIXC. Seems kind of logical, since floating point precision is limited and you can't avoid that you lose some bits when results are rounded. And for our application an "inexact" result is not an issue. It would be nice if i could just disable that exception. But the CPUC->INTEN register can't do the trick, i already tried that.

    Best regards

    Frank

     

Children
No Data
Related