@@ -54,8 +54,8 @@ def init_pmu(m_i2c):
5454 pmu .disableIRQ (AXP2101 .XPOWERS_AXP2101_ALL_IRQ );
5555 # Enable the required interrupt function
5656 pmu .enableIRQ (
57- AXP2101 .XPOWERS_AXP2101_BAT_INSERT_IRQ | AXP2101 .XPOWERS_AXP2101_BAT_REMOVE_IRQ | # BATTERY
58- AXP2101 .XPOWERS_AXP2101_VBUS_INSERT_IRQ | AXP2101 .XPOWERS_AXP2101_VBUS_REMOVE_IRQ | # VBUS
57+ # AXP2101.XPOWERS_AXP2101_BAT_INSERT_IRQ | AXP2101.XPOWERS_AXP2101_BAT_REMOVE_IRQ | # BATTERY is not removable
58+ # AXP2101.XPOWERS_AXP2101_VBUS_INSERT_IRQ | AXP2101.XPOWERS_AXP2101_VBUS_REMOVE_IRQ | # VBUS don't think this will be used
5959 AXP2101 .XPOWERS_AXP2101_PKEY_SHORT_IRQ | AXP2101 .XPOWERS_AXP2101_PKEY_LONG_IRQ | # POWER KEY
6060 AXP2101 .XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | AXP2101 .XPOWERS_AXP2101_BAT_CHG_START_IRQ # CHARGE
6161 )
@@ -92,19 +92,42 @@ def init_pmu(m_i2c):
9292except Exception as e :
9393 print (f"Exception while initializing PMU: { e } " )
9494
95+ async def pmu_irq_watchdog ():
96+ # Workaround for IRQ's that don't always get cleared (race condition?)
97+ pmu = BatteryManager .pmu
98+ while True :
99+ await TaskManager .sleep (3 ) # check every 3 seconds
100+ if pmu_int .value () == 0 : # IRQ pin is still LOW → stuck!
101+ print ("PMU IRQ line is stuck low - running recovery..." )
102+ for _ in range (10 ):
103+ pmu .clearIrqStatus ()
104+ await TaskManager .sleep_ms (10 )
105+ print ("PMU IRQ recovery completed" )
106+
95107def _pmu_irq_task (_arg ):
96108 pmu = BatteryManager .pmu
97- status = pmu .getIrqStatus ()
98- print ("PMU interrupt: status=0x{0:06X}" .format (status ))
99- if pmu .isPekeyShortPressIrq ():
100- print ("PMU interrupt: PEKEY short press" )
101- if pmu .isEnableALDO2 ():
102- pmu .disableALDO2 ()
103- else :
104- pmu .enableALDO2 ()
105- if pmu .isPekeyLongPressIrq ():
106- print ("PMU interrupt: PEKEY long press" )
107- pmu .clearIrqStatus ()
109+ try :
110+ status = pmu .getIrqStatus ()
111+ print (f"PMU interrupt: status=0x{ status :06X} " )
112+ if status == 0 :
113+ print ("PMU: spurious interrupt (status already cleared)" )
114+ return
115+ if pmu .isPekeyShortPressIrq ():
116+ print ("PMU interrupt: PEKEY short press" )
117+ if pmu .isEnableALDO2 ():
118+ pmu .disableALDO2 ()
119+ else :
120+ pmu .enableALDO2 ()
121+ if pmu .isPekeyLongPressIrq ():
122+ print ("PMU interrupt: PEKEY long press" )
123+ except Exception as e :
124+ print (f"Exception in PMU IRQ task: { e } " )
125+ finally :
126+ # clear interrupt, can take multiple tries
127+ attempts = 0
128+ while pmu .getIrqStatus () != 0 and attempts < 5 : # safety limit
129+ attempts += 1
130+ pmu .clearIrqStatus ()
108131
109132def _handle_pmu_irq (_pin ):
110133 try :
@@ -115,6 +138,10 @@ def _handle_pmu_irq(_pin):
115138pmu_int = Pin (21 , Pin .IN , Pin .PULL_UP )
116139pmu_int .irq (trigger = Pin .IRQ_FALLING , handler = _handle_pmu_irq )
117140
141+ from mpos import TaskManager
142+ TaskManager .create_task (pmu_irq_watchdog ())
143+
144+
118145
119146print ("DRV2605L vibrator test" )
120147DRV2605L_ADDR = 0x5A
0 commit comments