From 0692ee251d023313bd2b0bb61d150726ad3d42ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 15 Nov 2013 17:14:45 +0100 Subject: [PATCH] cc2538: usb: Use the new LPM peripheral registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/lpm.c | 19 +++++++------------ cpu/cc2538/lpm.h | 4 ++-- cpu/cc2538/usb/usb-arch.c | 14 ++++++++++++++ platform/cc2538dk/README.md | 1 - 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/cpu/cc2538/lpm.c b/cpu/cc2538/lpm.c index 5642ef023..70dca181e 100644 --- a/cpu/cc2538/lpm.c +++ b/cpu/cc2538/lpm.c @@ -41,7 +41,6 @@ #include "dev/sys-ctrl.h" #include "dev/scb.h" #include "dev/rfcore-xreg.h" -#include "dev/usb-regs.h" #include "rtimer-arch.h" #include "lpm.h" #include "reg.h" @@ -103,7 +102,7 @@ static uint8_t max_pm; #ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX #define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX #else -#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 0 +#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 1 #endif lpm_periph_permit_pm1_func_t @@ -217,15 +216,12 @@ lpm_enter() rtimer_clock_t duration; /* - * If either the RF, the USB or the registered peripherals are on, dropping to - * PM1/2 would equal pulling the rug (32MHz XOSC) from under their feet. Thus, - * we only drop to PM0. PM0 is also used if max_pm==0. - * - * Note: USB Suspend/Resume/Remote Wake-Up are not supported. Once the PLL is - * on, it stays on. + * If either the RF or the registered peripherals are on, dropping to PM1/2 + * would equal pulling the rug (32MHz XOSC) from under their feet. Thus, we + * only drop to PM0. PM0 is also used if max_pm==0. */ if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) != 0 - || REG(USB_CTRL) != 0 || !periph_permit_pm1() || max_pm == 0) { + || !periph_permit_pm1() || max_pm == 0) { enter_pm0(); /* We reach here when the interrupt context that woke us up has returned */ @@ -233,8 +229,7 @@ lpm_enter() } /* - * Registered peripherals were off. USB PLL was off. Radio was off: Some Duty - * Cycling in place. + * Registered peripherals were off. Radio was off: Some Duty Cycling in place. * rtimers run on the Sleep Timer. Thus, if we have a scheduled rtimer * task, a Sleep Timer interrupt will fire and will wake us up. * Choose the most suitable PM based on anticipated deep sleep duration @@ -251,7 +246,7 @@ lpm_enter() } /* If we reach here, we -may- (but may as well not) be dropping to PM1+. We - * know the registered peripherals, USB and RF are off so we can switch to the + * know the registered peripherals and RF are off so we can switch to the * 16MHz RCOSC. */ select_16_mhz_rcosc(); diff --git a/cpu/cc2538/lpm.h b/cpu/cc2538/lpm.h index b33322ad9..cd8b2b510 100644 --- a/cpu/cc2538/lpm.h +++ b/cpu/cc2538/lpm.h @@ -101,7 +101,6 @@ void lpm_init(void); * * This PM selection heuristic has the following primary criteria: * - Is the RF off? - * - Is the USB PLL off? * - Are all registered peripherals permitting PM1+? * - Is the Sleep Timer scheduled to fire an interrupt? * @@ -182,7 +181,8 @@ typedef bool (*lpm_periph_permit_pm1_func_t)(void); * module to get 'permission' to drop to PM1+ * \param permit_pm1_func Pointer to the function * - * Some peripherals are sensitive to PM changes. + * Some peripherals are sensitive to PM changes. For instance, we don't want to + * drop to PM1+ if the USB PLL is active. * * When changing power modes, the LPM driver will call all FPs registered with * this function. The peripheral's function will return true or false to permit diff --git a/cpu/cc2538/usb/usb-arch.c b/cpu/cc2538/usb/usb-arch.c index 5ed1eee8e..315f6f0cb 100644 --- a/cpu/cc2538/usb/usb-arch.c +++ b/cpu/cc2538/usb/usb-arch.c @@ -46,10 +46,12 @@ #include "dev/ioc.h" #include "dev/udma.h" #include "sys/clock.h" +#include "lpm.h" #include "reg.h" #include "dev/watchdog.h" +#include #include /*---------------------------------------------------------------------------*/ /* EP max FIFO sizes without double buffering */ @@ -303,12 +305,24 @@ reset(void) usb_arch_setup_control_endpoint(0); } /*---------------------------------------------------------------------------*/ +static bool +permit_pm1(void) +{ + /* + * Note: USB Suspend/Resume/Remote Wake-Up are not supported. Once the PLL is + * on, it stays on. + */ + return REG(USB_CTRL) == 0; +} +/*---------------------------------------------------------------------------*/ /* Init USB */ void usb_arch_setup(void) { uint8_t i; + lpm_register_peripheral(permit_pm1); + /* Switch on USB PLL & USB module */ REG(USB_CTRL) = USB_CTRL_USB_EN | USB_CTRL_PLL_EN; diff --git a/platform/cc2538dk/README.md b/platform/cc2538dk/README.md index 2d8e19d5f..ada90abd1 100644 --- a/platform/cc2538dk/README.md +++ b/platform/cc2538dk/README.md @@ -388,7 +388,6 @@ The Low-Power module uses a simple heuristic to determine the best power mode, d In a nutshell, the algorithm first answers the following questions: * Is the RF off? -* Is the USB PLL off? * Are all registered peripherals permitting PM1+? * Is the Sleep Timer scheduled to fire an interrupt?