This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Is MWU in Softdevice?

Hi,

I am using nRF52832 along with Softdevice 6.0.0, SDK 15.0.0, Chip Revision 2 (QFAA-EX0).

I understand that softdevice uses MWU from this document

As per the Errata 75 there is increased current consumption when MWU is used.

We are not using MWU in our application code, so how to apply the workaround for this errata in our code? Will the softdevice take care of this errata internally or the application has to take care of it. In application we do use __WFE.

Regards,

Justin

Parents
  • I am sorry Justin,

    It is my fault that I did not think about Errata 75 when suggesting you to apply the workaround for Errata 220.

    You are right, we need to apply the workaround of Errata 75 too into the workaround of Errata-220.

    So the required and combined workaround for 220 and 75 becomes like below

    SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
    __disable_irq();
    
    /* MWU Disable */
    NRF_MWU->REGIONENCLR
        = ((MWU_REGIONENCLR_RGN0WA_Clear << MWU_REGIONENCLR_RGN0WA_Pos) 
         | (MWU_REGIONENCLR_PRGN0WA_Clear << MWU_REGIONENCLR_PRGN0WA_Pos));
    
    __WFE()
    __nop();__nop();__nop();__nop();
    
    /* MWU Enable */
    NRF_MWU->REGIONENSET
        = ((MWU_REGIONENSET_RGN0WA_Set << MWU_REGIONENSET_RGN0WA_Pos) 
         | (MWU_REGIONENSET_PRGN0WA_Set << MWU_REGIONENSET_PRGN0WA_Pos));
    
    __enable_irq();

Reply
  • I am sorry Justin,

    It is my fault that I did not think about Errata 75 when suggesting you to apply the workaround for Errata 220.

    You are right, we need to apply the workaround of Errata 75 too into the workaround of Errata-220.

    So the required and combined workaround for 220 and 75 becomes like below

    SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
    __disable_irq();
    
    /* MWU Disable */
    NRF_MWU->REGIONENCLR
        = ((MWU_REGIONENCLR_RGN0WA_Clear << MWU_REGIONENCLR_RGN0WA_Pos) 
         | (MWU_REGIONENCLR_PRGN0WA_Clear << MWU_REGIONENCLR_PRGN0WA_Pos));
    
    __WFE()
    __nop();__nop();__nop();__nop();
    
    /* MWU Enable */
    NRF_MWU->REGIONENSET
        = ((MWU_REGIONENSET_RGN0WA_Set << MWU_REGIONENSET_RGN0WA_Pos) 
         | (MWU_REGIONENSET_PRGN0WA_Set << MWU_REGIONENSET_PRGN0WA_Pos));
    
    __enable_irq();

Children
  • For a more general case where the Softdevice is/isn't installed and user code does/doesn't use the MWU I am using the following:

    // Errata 75: MWU: Increased current consumption
    //  This has to be handled by turning off MWU region 0 which is used in SoftDevice
    //  see https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF52832_EngB%2FERR%2FnRF52832%2FEngineeringB%2Flatest%2Fanomaly_832_75.html
    #define MWU_ACCESS_WATCH_MASK (0x0F0000FF)

    The code replacing the WFE() is as follows:

      // Errata 220: CPU: RAM is not ready when written - Disable IRQ while using WFE
      // Enable SEVONPEND to disable interrupts so the internal events that generate the interrupt cause wakeuup in __WFE context and not in interrupt context
      // Before: ENABLE_WAKEUP_SOURCE -> __WFE -> WAKEUP_SOURCE_ISR -> CONTINUE_FROM_ISR  next line of __WFE
      // After:  ENABLE_WAKEUP_SOURCE -> SEVONPEND -> DISABLE_INTERRUPTS -> __WFE -> WAKEUP inside __WFE -> ENABLE_interrupts -> WAKEUP_SOURCE_ISR
      //
      // Errata 75: MWU: Increased current consumption
      // This has to be handled by turning off MWU but it is used in SoftDevice
      // see https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF52832_EngB%2FERR%2FnRF52832%2FEngineeringB%2Flatest%2Fanomaly_832_75.html
      //
      // Errata 220: Enable SEVONPEND
      SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
      __disable_irq();
      // Errata 75: MWU Disable
      uint32_t MWU_AccessWatchMask = NRF_MWU->REGIONEN & MWU_ACCESS_WATCH_MASK;
      // Handle MNU if any areas are enabled
      if (MWU_AccessWatchMask)
      {
         NRF_MWU->REGIONENCLR = MWU_AccessWatchMask; // Disable write access watch in region[0] and PREGION[0]
         __WFE();
         __NOP(); __NOP(); __NOP(); __NOP();
         // Errata 75: MWU Enable
         NRF_MWU->REGIONENSET = MWU_AccessWatchMask;
      }
      else
      {
         __WFE();
         __NOP(); __NOP(); __NOP(); __NOP();
      }
      __enable_irq();

    This code is required in nrf_pwr_mgmt.c, main.c and nrf_soc.c to cover our use cases with both BLE SoftDevice and without. Feel free to provide constructive feedback .. this is very hard to test!

  • If we are not using softdevice and not using MWU why do we need to add the workaround? 

  • You don't; just the other workaround.  I use both though and am hoping for any feedback from other users. I hadn't anticipated having to look so closely at this.

  • if you are not using the softdevice and you are not enabling MWU anywhere in the application, then you do not need to apply workaround for Errata 75.

Related