diff --git a/ChangeLog b/ChangeLog index bfbe8b7..af86d2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2017-11-16 NIIBE Yutaka + + * chopstx-cortex-m.c (idle): Support WFE. + * mcu/usb-stm32f103.c (usb_lld_init): Use event. + * usb_lld.h (INTR_REQ_USB_WAKEUP): Remove. + 2017-11-15 NIIBE Yutaka * usb_lld.h (INTR_REQ_USB_WAKEUP): New. diff --git a/chopstx-cortex-m.c b/chopstx-cortex-m.c index ffad3ec..cc28311 100644 --- a/chopstx-cortex-m.c +++ b/chopstx-cortex-m.c @@ -237,7 +237,11 @@ idle (void) for (;;) { asm ("ldr %0, %1" : "=r" (sleep_enabled): "m" (chx_allow_sleep)); - if (sleep_enabled) + if (!sleep_enabled) + continue; + if ((sleep_enabled & 0x80)) + asm volatile ("wfe" : : : "memory"); + else asm volatile ("wfi" : : : "memory"); } } @@ -737,31 +741,31 @@ struct PWR volatile uint32_t CSR; }; static struct PWR *const PWR = ((struct PWR *)0x40007000); -#define PWR_CR_LPDS 0x0001 -#define PWR_CR_PDDS 0x0002 -#define PWR_CR_CWUF 0x0004 +#define PWR_CR_LPDS 0x0001 /* Low-power deepsleep */ +#define PWR_CR_PDDS 0x0002 /* Power down deepsleep */ +#define PWR_CR_CWUF 0x0004 /* Clear wakeup flag */ void -chx_sleep_mode (int enable_sleep) +chx_sleep_mode (int how) { - if (enable_sleep == 0) + if (how == 0) ; else { - if (enable_sleep == 1) + if (how == 1) /* sleep only */ SCB->SCR &= ~SCB_SCR_SLEEPDEEP; else { PWR->CR |= PWR_CR_CWUF; - - if (enable_sleep == 2 || enable_sleep == 3) + + if (how == 2 || how == 3) { PWR->CR &= ~PWR_CR_PDDS; - if (enable_sleep == 3) + if (how == 3) PWR->CR |= PWR_CR_LPDS; } - else /* enable_sleep == 4 */ + else /* how == 4 */ PWR->CR |= PWR_CR_PDDS; SCB->SCR |= SCB_SCR_SLEEPDEEP; diff --git a/chopstx.c b/chopstx.c index 387847b..31a0d0c 100644 --- a/chopstx.c +++ b/chopstx.c @@ -1485,11 +1485,10 @@ chopstx_setpriority (chopstx_prio_t prio_new) * * Behavior of @enable_sleep >= 1 depends on MCU. * - * For STM32F103, it's like following. - * 1: Sleep (CPU clock OFF only) - * 2: Stop Wakeup by EXTI (voltage regulator on) - * 3: Stop Wakeup by EXTI (voltage regulator low-power) - * 4: Standby Wakeup by RESET (voltage regulator off) + * For STM32F103, 1 for Sleep (CPU clock OFF only), 2 for Stop (Wakeup + * by EXTI, voltage regulator on), 3 for Stop (Wakeup by EXTI, voltage + * regulator low-power), 4 for Standby (Wakeup by RESET, voltage + * regulator off), and 128 is or-ed to ask WFE instead of WFI. * * Return previous value of @enable_sleep. */ @@ -1501,7 +1500,7 @@ chopstx_conf_idle (int enable_sleep) chx_spin_lock (&chx_enable_sleep_lock); r = chx_allow_sleep; chx_allow_sleep = enable_sleep; - chx_sleep_mode (enable_sleep); + chx_sleep_mode ((enable_sleep & 0x7f)); chx_spin_unlock (&chx_enable_sleep_lock); return r; diff --git a/mcu/usb-stm32f103.c b/mcu/usb-stm32f103.c index 6a8fddf..77ffe55 100644 --- a/mcu/usb-stm32f103.c +++ b/mcu/usb-stm32f103.c @@ -343,10 +343,9 @@ void usb_lld_init (struct usb_dev *dev, uint8_t feature) st103_set_cntr (CNTR_CTRM | CNTR_OVRM | CNTR_ERRM | CNTR_WKUPM | CNTR_SUSPM | CNTR_RESETM); - /* Setting of EXTI wakeup interrupt to break sleep mode. */ + /* Setting of EXTI wakeup event to break sleep on WFE. */ EXTI->RTSR |= (1 << 18); /* Rising trigger selection */ - EXTI->PR |= (1 << 18); /* Clear pending bit */ - EXTI->IMR |= (1 << 18); /* Interrupt mask disabled */ + EXTI->EMR |= (1 << 18); /* Event mask cleared */ } void usb_lld_prepare_shutdown (void) diff --git a/usb_lld.h b/usb_lld.h index c8e6944..ce08f73 100644 --- a/usb_lld.h +++ b/usb_lld.h @@ -153,7 +153,6 @@ void usb_lld_setup_endp (struct usb_dev *dev, int ep_num, int rx_en, int tx_en); void usb_lld_stall_tx (int ep_num); void usb_lld_stall_rx (int ep_num); #else -#define INTR_REQ_USB_WAKEUP 42 #define INTR_REQ_USB 20 /* EP_TYPE[1:0] EndPoint TYPE */ #define EP_BULK (0x0000) /* EndPoint BULK */