@@ -423,6 +423,11 @@ bool arm_cpu_exception(arm_t *arm, arm_exception_number_t exc) {
423423 }
424424 return false;
425425 }
426+ cpu -> wfi = false;
427+ if (cpu -> pm && exc > ARM_Exception_HardFault ) {
428+ return false;
429+ }
430+
426431 arm_cpu_tick (arm );
427432 cpu -> exc = true;
428433 sp -= 0x20 ;
@@ -617,19 +622,17 @@ void arm_cpu_execute(arm_t *arm) {
617622 arm_cpu_exception (arm , ARM_Exception_HardFault );
618623 cpu -> exc = false;
619624 return ;
620- }
621- if (unlikely (!cpu -> pm &&
622- (icsr & (SCB_ICSR_NMIPENDSET_Msk |
623- SCB_ICSR_PENDSVSET_Msk |
624- SCB_ICSR_PENDSTSET_Msk ) ||
625- cpu -> nvic .ipr & cpu -> nvic .ier ))) {
626- if (icsr & SCB_ICSR_NMIPENDSET_Msk ) {
627- if (likely (arm_cpu_exception (arm , ARM_Exception_NMI ))) {
628- cpu -> scb .icsr &= ~SCB_ICSR_NMIPENDSET_Msk ;
629- cpu -> exc = false;
630- return ;
631- }
632- } else if (icsr & SCB_ICSR_PENDSVSET_Msk ) {
625+ } else if (unlikely (icsr & SCB_ICSR_NMIPENDSET_Msk )) {
626+ if (likely (arm_cpu_exception (arm , ARM_Exception_NMI ))) {
627+ cpu -> scb .icsr &= ~SCB_ICSR_NMIPENDSET_Msk ;
628+ cpu -> exc = false;
629+ return ;
630+ }
631+ } else if (unlikely ((!cpu -> pm || cpu -> wfi ) &&
632+ (icsr & (SCB_ICSR_PENDSVSET_Msk |
633+ SCB_ICSR_PENDSTSET_Msk ) ||
634+ cpu -> nvic .ipr & cpu -> nvic .ier ))) {
635+ if (icsr & SCB_ICSR_PENDSVSET_Msk ) {
633636 if (likely (arm_cpu_exception (arm , ARM_Exception_PendSV ))) {
634637 cpu -> scb .icsr &= ~SCB_ICSR_PENDSVSET_Msk ;
635638 cpu -> exc = false;
@@ -654,6 +657,15 @@ void arm_cpu_execute(arm_t *arm) {
654657 return ;
655658 }
656659 }
660+ if (unlikely (cpu -> wfi )) {
661+ if ((arm -> mem .pm .SLEEP .bit .IDLE == PM_SLEEP_IDLE_APB_Val ) &&
662+ (arm -> cpu .scb .scr & SCB_SCR_SLEEPDEEP_Msk )) {
663+ sync_sleep (& arm -> sync );
664+ } else {
665+ arm_cpu_tick (arm );
666+ }
667+ return ;
668+ }
657669 arm_cpu_tick (arm );
658670 opc = arm_mem_load_half (arm , pc );
659671 if (unlikely (cpu -> exc )) {
@@ -965,10 +977,7 @@ void arm_cpu_execute(arm_t *arm) {
965977 case 2 : // Wait for Event hint
966978 break ;
967979 case 3 : // Wait for Interrupt hint
968- if ((arm -> mem .pm .SLEEP .bit .IDLE == PM_SLEEP_IDLE_APB_Val ) &&
969- (arm -> cpu .scb .scr & SCB_SCR_SLEEPDEEP_Msk )) {
970- sync_sleep (& arm -> sync );
971- }
980+ cpu -> wfi = true;
972981 break ;
973982 case 4 : // Send Event hint
974983 break ;
0 commit comments