cc2538: usb: Use the new LPM peripheral registration

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
This commit is contained in:
Benoît Thébaudeau 2013-11-15 17:14:45 +01:00
parent d35732505b
commit 0692ee251d
4 changed files with 23 additions and 15 deletions

View file

@ -41,7 +41,6 @@
#include "dev/sys-ctrl.h" #include "dev/sys-ctrl.h"
#include "dev/scb.h" #include "dev/scb.h"
#include "dev/rfcore-xreg.h" #include "dev/rfcore-xreg.h"
#include "dev/usb-regs.h"
#include "rtimer-arch.h" #include "rtimer-arch.h"
#include "lpm.h" #include "lpm.h"
#include "reg.h" #include "reg.h"
@ -103,7 +102,7 @@ static uint8_t max_pm;
#ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX #ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX #define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
#else #else
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 0 #define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 1
#endif #endif
lpm_periph_permit_pm1_func_t lpm_periph_permit_pm1_func_t
@ -217,15 +216,12 @@ lpm_enter()
rtimer_clock_t duration; rtimer_clock_t duration;
/* /*
* If either the RF, the USB or the registered peripherals are on, dropping to * If either the RF or the registered peripherals are on, dropping to PM1/2
* PM1/2 would equal pulling the rug (32MHz XOSC) from under their feet. Thus, * would equal pulling the rug (32MHz XOSC) from under their feet. Thus, we
* we only drop to PM0. PM0 is also used if max_pm==0. * 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((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) != 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(); enter_pm0();
/* We reach here when the interrupt context that woke us up has returned */ /* 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 * Registered peripherals were off. Radio was off: Some Duty Cycling in place.
* Cycling in place.
* rtimers run on the Sleep Timer. Thus, if we have a scheduled rtimer * 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. * task, a Sleep Timer interrupt will fire and will wake us up.
* Choose the most suitable PM based on anticipated deep sleep duration * 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 /* 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. */ * 16MHz RCOSC. */
select_16_mhz_rcosc(); select_16_mhz_rcosc();

View file

@ -101,7 +101,6 @@ void lpm_init(void);
* *
* This PM selection heuristic has the following primary criteria: * This PM selection heuristic has the following primary criteria:
* - Is the RF off? * - Is the RF off?
* - Is the USB PLL off?
* - Are all registered peripherals permitting PM1+? * - Are all registered peripherals permitting PM1+?
* - Is the Sleep Timer scheduled to fire an interrupt? * - 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+ * module to get 'permission' to drop to PM1+
* \param permit_pm1_func Pointer to the function * \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 * 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 * this function. The peripheral's function will return true or false to permit

View file

@ -46,10 +46,12 @@
#include "dev/ioc.h" #include "dev/ioc.h"
#include "dev/udma.h" #include "dev/udma.h"
#include "sys/clock.h" #include "sys/clock.h"
#include "lpm.h"
#include "reg.h" #include "reg.h"
#include "dev/watchdog.h" #include "dev/watchdog.h"
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* EP max FIFO sizes without double buffering */ /* EP max FIFO sizes without double buffering */
@ -303,12 +305,24 @@ reset(void)
usb_arch_setup_control_endpoint(0); 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 */ /* Init USB */
void void
usb_arch_setup(void) usb_arch_setup(void)
{ {
uint8_t i; uint8_t i;
lpm_register_peripheral(permit_pm1);
/* Switch on USB PLL & USB module */ /* Switch on USB PLL & USB module */
REG(USB_CTRL) = USB_CTRL_USB_EN | USB_CTRL_PLL_EN; REG(USB_CTRL) = USB_CTRL_USB_EN | USB_CTRL_PLL_EN;

View file

@ -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: In a nutshell, the algorithm first answers the following questions:
* Is the RF off? * Is the RF off?
* Is the USB PLL off?
* Are all registered peripherals permitting PM1+? * Are all registered peripherals permitting PM1+?
* Is the Sleep Timer scheduled to fire an interrupt? * Is the Sleep Timer scheduled to fire an interrupt?