Skip to content

Commit a1c2d50

Browse files
committed
Improve WFI and sleep implementation
1 parent 41cd026 commit a1c2d50

File tree

4 files changed

+36
-19
lines changed

4 files changed

+36
-19
lines changed

core/arm/arm.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static int arm_thrd(void *context) {
2525
uint16_t val;
2626
do {
2727
arm_cpu_execute(arm);
28-
} while (++i);
28+
} while (++i && !arm->sync.slp);
2929
peek = spsc_queue_peek(&arm->usart[0]);
3030
if (unlikely(peek != SPSC_QUEUE_INVALID_ENTRY &&
3131
arm_mem_usart_recv(arm, 3, peek))) {
@@ -150,12 +150,16 @@ bool arm_usart_send(arm_t *arm, uint8_t val) {
150150
bool success = spsc_queue_enqueue(&arm->usart[0], val);
151151
if (likely(success)) {
152152
(void)spsc_queue_flush(&arm->usart[0]);
153+
debug_char(false, val);
153154
}
154155
return success;
155156
}
156157

157158
bool arm_usart_recv(arm_t *arm, uint8_t *val) {
158159
spsc_queue_entry_t entry = spsc_queue_dequeue(&arm->usart[1]);
159160
*val = entry;
161+
if (entry != SPSC_QUEUE_INVALID_ENTRY) {
162+
debug_char(true, *val);
163+
}
160164
return entry != SPSC_QUEUE_INVALID_ENTRY;
161165
}

core/arm/armcpu.c

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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;

core/arm/armcpu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ typedef union arm_cpu {
3535
struct {
3636
uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, ip, sp, lr, pc, altsp;
3737
uint64_t active;
38-
bool v, c, z, n, pm, spsel, exc;
38+
bool v, c, z, n, pm, spsel, exc, wfi;
3939
arm_systick_t systick;
4040
arm_nvic_t nvic;
4141
arm_scb_t scb;

core/arm/armmem.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,10 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t
11281128
switch (offset) {
11291129
case (USB_CTRLA_OFFSET | USB_SYNCBUSY_OFFSET | USB_QOSCTRL_OFFSET) >> 2:
11301130
return;
1131+
case USB_DEVICE_EPSTATUSSET_OFFSET >> 2:
1132+
return;
1133+
case USB_DEVICE_EPINTENSET_OFFSET >> 2:
1134+
return;
11311135
}
11321136
} else if (addr < (uint32_t)SBMATRIX) { // MTB
11331137
switch (offset) {

0 commit comments

Comments
 (0)