From: Keith Packard Date: Sat, 6 Feb 2016 11:51:32 +0000 (+1100) Subject: altos/stmf0: Add suspend/resume support X-Git-Tag: 1.6.3~2^2~108 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=a5607aad694c01c01c48229172b289f005a1b6bb altos/stmf0: Add suspend/resume support Allow USB suspend to suspend USB, GPIOs and master clock. Signed-off-by: Keith Packard --- diff --git a/src/stmf0/ao_arch_funcs.h b/src/stmf0/ao_arch_funcs.h index 3db96be2..8d585f80 100644 --- a/src/stmf0/ao_arch_funcs.h +++ b/src/stmf0/ao_arch_funcs.h @@ -18,6 +18,8 @@ #ifndef _AO_ARCH_FUNCS_H_ #define _AO_ARCH_FUNCS_H_ +#include + /* ao_spi_stm.c */ @@ -118,27 +120,44 @@ ao_spi_try_get_mask(struct stm_gpio *reg, uint16_t mask, uint8_t bus, uint32_t s #define ao_spi_get_bit(reg,bit,pin,bus,speed) ao_spi_get_mask(reg,(1< 1 wait state */ @@ -227,29 +266,11 @@ ao_clock_init(void) stm_rcc.cfgr = cfgr; /* Switch to the desired system clock */ - - cfgr = stm_rcc.cfgr; - cfgr &= ~(STM_RCC_CFGR_SW_MASK << STM_RCC_CFGR_SW); - cfgr |= (STM_RCC_CFGR_SW_TARGET_CLOCK << STM_RCC_CFGR_SW); - stm_rcc.cfgr = cfgr; - for (;;) { - uint32_t c, part, mask, val; - - c = stm_rcc.cfgr; - mask = (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS); - val = (STM_RCC_CFGR_SWS_TARGET_CLOCK << STM_RCC_CFGR_SWS); - part = c & mask; - if (part == val) - break; - } + ao_clock_normal_switch(); /* Clear reset flags */ stm_rcc.csr |= (1 << STM_RCC_CSR_RMVF); -#if !AO_HSI && !AO_NEED_HSI - /* Turn off the HSI clock */ - stm_rcc.cr &= ~(1 << STM_RCC_CR_HSION); -#endif #if DEBUG_THE_CLOCK /* Output SYSCLK on PA8 for measurments */ @@ -263,3 +284,18 @@ ao_clock_init(void) stm_rcc.cfgr |= (STM_RCC_CFGR_MCOSEL_HSE << STM_RCC_CFGR_MCOSEL); #endif } + +#if AO_POWER_MANAGEMENT +void +ao_clock_suspend(void) +{ + ao_clock_hsi(); +} + +void +ao_clock_resume(void) +{ + ao_clock_normal_start(); + ao_clock_normal_switch(); +} +#endif diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c index b8146c21..691c2d56 100644 --- a/src/stmf0/ao_usb_stm.c +++ b/src/stmf0/ao_usb_stm.c @@ -18,8 +18,10 @@ #include "ao.h" #include "ao_usb.h" #include "ao_product.h" +#include "ao_power.h" #define USB_DEBUG 0 +#define USB_STATUS 0 #define USB_DEBUG_DATA 0 #define USB_ECHO 0 @@ -129,10 +131,9 @@ static uint8_t ao_usb_out_avail; uint8_t ao_usb_running; static uint8_t ao_usb_configuration; -#define AO_USB_EP0_GOT_RESET 1 -#define AO_USB_EP0_GOT_SETUP 2 -#define AO_USB_EP0_GOT_RX_DATA 4 -#define AO_USB_EP0_GOT_TX_ACK 8 +#define AO_USB_EP0_GOT_SETUP 1 +#define AO_USB_EP0_GOT_RX_DATA 2 +#define AO_USB_EP0_GOT_TX_ACK 4 static uint8_t ao_usb_ep0_receive; static uint8_t ao_usb_address; @@ -438,6 +439,7 @@ static uint16_t int_count; static uint16_t in_count; static uint16_t out_count; static uint16_t reset_count; +static uint16_t suspend_count; /* The USB memory must be accessed in 16-bit units */ @@ -686,11 +688,6 @@ static void ao_usb_ep0_handle(uint8_t receive) { ao_usb_ep0_receive = 0; - if (receive & AO_USB_EP0_GOT_RESET) { - debug ("\treset\n"); - ao_usb_set_ep0(); - return; - } if (receive & AO_USB_EP0_GOT_SETUP) { debug ("\tsetup\n"); ao_usb_ep0_setup(); @@ -721,6 +718,23 @@ ao_usb_ep0_handle(uint8_t receive) } } +void +ao_usb_suspend(void) +{ + stm_usb.cntr |= (1 << STM_USB_CNTR_FSUSP); + ao_power_suspend(); + stm_usb.cntr |= (1 << STM_USB_CNTR_LP_MODE); + ao_clock_suspend(); +} + +void +ao_usb_wakeup(void) +{ + ao_clock_resume(); + stm_usb.cntr &= ~(1 << STM_USB_CNTR_FSUSP); + ao_power_resume(); +} + void stm_usb_isr(void) { @@ -784,10 +798,18 @@ stm_usb_isr(void) if (istr & (1 << STM_USB_ISTR_RESET)) { ++reset_count; - ao_usb_ep0_receive |= AO_USB_EP0_GOT_RESET; - ao_usb_ep0_handle(ao_usb_ep0_receive); + debug ("\treset\n"); + ao_usb_set_ep0(); + } + if (istr & (1 << STM_USB_ISTR_SUSP)) { + ++suspend_count; + debug ("\tsuspend\n"); + ao_usb_suspend(); + } + if (istr & (1 << STM_USB_ISTR_WKUP)) { + debug ("\twakeup\n"); + ao_usb_wakeup(); } - } /* Queue the current IN buffer for transmission */ @@ -1050,8 +1072,8 @@ ao_usb_enable(void) stm_usb.cntr = ((1 << STM_USB_CNTR_CTRM) | (0 << STM_USB_CNTR_PMAOVRM) | (0 << STM_USB_CNTR_ERRM) | - (0 << STM_USB_CNTR_WKUPM) | - (0 << STM_USB_CNTR_SUSPM) | + (1 << STM_USB_CNTR_WKUPM) | + (1 << STM_USB_CNTR_SUSPM) | (1 << STM_USB_CNTR_RESETM) | (0 << STM_USB_CNTR_SOFM) | (0 << STM_USB_CNTR_ESOFM) | @@ -1086,12 +1108,12 @@ ao_usb_echo(void) } #endif -#if USB_DEBUG +#if USB_STATUS static void ao_usb_irq(void) { - printf ("control: %d out: %d in: %d int: %d reset: %d\n", - control_count, out_count, in_count, int_count, reset_count); + printf ("control: %d out: %d in: %d int: %d reset: %d suspend %d\n", + control_count, out_count, in_count, int_count, reset_count, suspend_count); } __code struct ao_cmds ao_usb_cmds[] = { @@ -1119,7 +1141,7 @@ ao_usb_init(void) #if USB_ECHO ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo"); #endif -#if USB_DEBUG +#if USB_STATUS ao_cmd_register(&ao_usb_cmds[0]); #endif #if !USB_ECHO