cc3200: Allow separate selection of the power mode in Pin callbacks.
This commit is contained in:
parent
10f7ef0832
commit
04749e677f
@ -50,7 +50,7 @@ const mp_arg_t mpcallback_init_args[] = {
|
||||
{ MP_QSTR_handler, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_priority, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_wake, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYB_PWR_MODE_ACTIVE_IDLE } },
|
||||
{ MP_QSTR_wake, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYB_PWR_MODE_ACTIVE} },
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -166,8 +166,8 @@ STATIC void wlan_reenable (SlWlanMode_t mode);
|
||||
STATIC void wlan_get_sl_mac (void);
|
||||
STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, const char* bssid, uint8_t sec,
|
||||
const char* key, uint32_t key_len);
|
||||
STATIC void wlan_callback_enable (mp_obj_t self_in);
|
||||
STATIC void wlan_callback_disable (mp_obj_t self_in);
|
||||
STATIC void wlan_lpds_callback_enable (mp_obj_t self_in);
|
||||
STATIC void wlan_lpds_callback_disable (mp_obj_t self_in);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
@ -668,12 +668,12 @@ STATIC mp_obj_t wlan_init_helper(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC void wlan_callback_enable (mp_obj_t self_in) {
|
||||
pybsleep_set_wlan_wake_callback (wlan_obj.callback);
|
||||
STATIC void wlan_lpds_callback_enable (mp_obj_t self_in) {
|
||||
pybsleep_set_wlan_lpds_callback (wlan_obj.callback);
|
||||
}
|
||||
|
||||
STATIC void wlan_callback_disable (mp_obj_t self_in) {
|
||||
pybsleep_set_wlan_wake_callback (NULL);
|
||||
STATIC void wlan_lpds_callback_disable (mp_obj_t self_in) {
|
||||
pybsleep_set_wlan_lpds_callback (NULL);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -957,7 +957,7 @@ STATIC mp_obj_t wlan_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
|
||||
self->callback = mpcallback_new (self, args[1].u_obj, &wlan_cb_methods);
|
||||
|
||||
// enable network wakeup
|
||||
pybsleep_set_wlan_wake_callback (self->callback);
|
||||
pybsleep_set_wlan_lpds_callback (self->callback);
|
||||
}
|
||||
return self->callback;
|
||||
}
|
||||
@ -1020,8 +1020,8 @@ STATIC MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table);
|
||||
|
||||
STATIC const mp_cb_methods_t wlan_cb_methods = {
|
||||
.init = wlan_callback,
|
||||
.enable = wlan_callback_enable,
|
||||
.disable = wlan_callback_disable,
|
||||
.enable = wlan_lpds_callback_enable,
|
||||
.disable = wlan_lpds_callback_disable,
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -119,13 +119,36 @@ STATIC void GPIOA2IntHandler (void);
|
||||
STATIC void GPIOA3IntHandler (void);
|
||||
STATIC void EXTI_Handler(uint port);
|
||||
STATIC void pin_obj_configure (const pin_obj_t *self);
|
||||
STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *wake_pin, uint *idx);
|
||||
STATIC void pin_extint_enable (mp_obj_t self_in);
|
||||
STATIC void pin_extint_disable (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBPIN_NUM_WAKE_PINS (6)
|
||||
#define PYBPIN_WAKES_NOT (-1)
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
bool active;
|
||||
int8_t lpds;
|
||||
int8_t hib;
|
||||
} pybpin_wake_pin_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC const mp_cb_methods_t pin_cb_methods;
|
||||
STATIC pybpin_wake_pin_t pybpin_wake_pin[PYBPIN_NUM_WAKE_PINS] =
|
||||
{ {.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
|
||||
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
|
||||
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
|
||||
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
|
||||
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
|
||||
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT} } ;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
@ -248,14 +271,83 @@ STATIC void pin_obj_configure (const pin_obj_t *self) {
|
||||
MAP_PinConfigSet(self->pin_num, self->strength, self->type);
|
||||
}
|
||||
|
||||
STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *hib_pin, uint *idx) {
|
||||
// pin_num is actually : (package_pin - 1)
|
||||
switch (self->pin_num) {
|
||||
case 56: // GPIO2
|
||||
*hib_pin = PRCM_HIB_GPIO2;
|
||||
*idx = 0;
|
||||
break;
|
||||
case 58: // GPIO4
|
||||
*hib_pin = PRCM_HIB_GPIO4;
|
||||
*idx = 1;
|
||||
break;
|
||||
case 3: // GPIO13
|
||||
*hib_pin = PRCM_HIB_GPIO13;
|
||||
*idx = 2;
|
||||
break;
|
||||
case 7: // GPIO17
|
||||
*hib_pin = PRCM_HIB_GPIO17;
|
||||
*idx = 3;
|
||||
break;
|
||||
case 1: // GPIO11
|
||||
*hib_pin = PRCM_HIB_GPIO11;
|
||||
*idx = 4;
|
||||
break;
|
||||
case 16: // GPIO24
|
||||
*hib_pin = PRCM_HIB_GPIO24;
|
||||
*idx = 5;
|
||||
break;
|
||||
default:
|
||||
*idx = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pin_extint_enable (mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
MAP_GPIOIntClear(self->port, self->bit);
|
||||
MAP_GPIOIntEnable(self->port, self->bit);
|
||||
const pin_obj_t *self = self_in;
|
||||
uint hib_pin, idx;
|
||||
|
||||
pin_get_hibernate_pin_and_idx (self, &hib_pin, &idx);
|
||||
if (idx < PYBPIN_NUM_WAKE_PINS) {
|
||||
if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) {
|
||||
// enable GPIO as a wake source during LPDS
|
||||
MAP_PRCMLPDSWakeUpGPIOSelect(idx, pybpin_wake_pin[idx].lpds);
|
||||
MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_GPIO);
|
||||
}
|
||||
|
||||
if (pybpin_wake_pin[idx].hib != PYBPIN_WAKES_NOT) {
|
||||
// enable GPIO as a wake source during hibernate
|
||||
MAP_PRCMHibernateWakeUpGPIOSelect(hib_pin, pybpin_wake_pin[idx].hib);
|
||||
MAP_PRCMHibernateWakeupSourceEnable(hib_pin);
|
||||
}
|
||||
else {
|
||||
MAP_PRCMHibernateWakeupSourceDisable(hib_pin);
|
||||
}
|
||||
}
|
||||
// if idx is invalid, the the pin supports active_idle interrupts for sure
|
||||
if (idx >= PYBPIN_NUM_WAKE_PINS || pybpin_wake_pin[idx].active) {
|
||||
MAP_GPIOIntClear(self->port, self->bit);
|
||||
MAP_GPIOIntEnable(self->port, self->bit);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pin_extint_disable (mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
const pin_obj_t *self = self_in;
|
||||
uint hib_pin, idx;
|
||||
|
||||
pin_get_hibernate_pin_and_idx (self, &hib_pin, &idx);
|
||||
if (idx < PYBPIN_NUM_WAKE_PINS) {
|
||||
if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) {
|
||||
// disable GPIO as a wake source during LPDS
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_GPIO);
|
||||
}
|
||||
if (pybpin_wake_pin[idx].hib != PYBPIN_WAKES_NOT) {
|
||||
// disable GPIO as a wake source during hibernate
|
||||
MAP_PRCMHibernateWakeupSourceDisable(hib_pin);
|
||||
}
|
||||
}
|
||||
// not need to check for the active flag, it's safe to disable it anyway
|
||||
MAP_GPIOIntDisable(self->port, self->bit);
|
||||
}
|
||||
|
||||
@ -534,35 +626,20 @@ STATIC mp_obj_t pin_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
if (args[4].u_int & PYB_PWR_MODE_LPDS) {
|
||||
uint wake_pin;
|
||||
uint wake_mode;
|
||||
// pin_num is actually : (package_pin - 1)
|
||||
switch (self->pin_num) {
|
||||
case 56: // GPIO2
|
||||
wake_pin = PRCM_LPDS_GPIO2;
|
||||
break;
|
||||
case 58: // GPIO4
|
||||
wake_pin = PRCM_LPDS_GPIO4;
|
||||
break;
|
||||
case 3: // GPIO13
|
||||
wake_pin = PRCM_LPDS_GPIO13;
|
||||
break;
|
||||
case 7: // GPIO17
|
||||
wake_pin = PRCM_LPDS_GPIO17;
|
||||
break;
|
||||
case 1: // GPIO11
|
||||
wake_pin = PRCM_LPDS_GPIO11;
|
||||
break;
|
||||
case 16: // GPIO24
|
||||
wake_pin = PRCM_LPDS_GPIO24;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
break;
|
||||
}
|
||||
uint pwrmode = args[4].u_int;
|
||||
if (pwrmode > (PYB_PWR_MODE_ACTIVE | PYB_PWR_MODE_LPDS | PYB_PWR_MODE_HIBERNATE)) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// intmodes are different in LDPS
|
||||
// get the wake info from this pin
|
||||
uint hib_pin, idx;
|
||||
pin_get_hibernate_pin_and_idx ((const pin_obj_t *)self, &hib_pin, &idx);
|
||||
if (pwrmode & PYB_PWR_MODE_LPDS) {
|
||||
if (idx >= PYBPIN_NUM_WAKE_PINS) {
|
||||
goto invalid_args;
|
||||
}
|
||||
// wake modes are different in LDPS
|
||||
uint wake_mode;
|
||||
switch (intmode) {
|
||||
case GPIO_FALLING_EDGE:
|
||||
wake_mode = PRCM_LPDS_FALL_EDGE;
|
||||
@ -577,44 +654,32 @@ STATIC mp_obj_t pin_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map
|
||||
wake_mode = PRCM_LPDS_HIGH_LEVEL;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
goto invalid_args;
|
||||
break;
|
||||
}
|
||||
|
||||
// enable GPIO as a wake source during LPDS
|
||||
MAP_PRCMLPDSWakeUpGPIOSelect(wake_pin, wake_mode);
|
||||
MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_GPIO);
|
||||
// first clear the lpds value from all wake-able pins
|
||||
for (uint i = 0; i < PYBPIN_NUM_WAKE_PINS; i++) {
|
||||
pybpin_wake_pin[i].lpds = PYBPIN_WAKES_NOT;
|
||||
}
|
||||
|
||||
// enable this pin as a wake-up source during LPDS
|
||||
pybpin_wake_pin[idx].lpds = wake_mode;
|
||||
}
|
||||
else {
|
||||
// this pin was the previous LPDS wake source, so disable it completely
|
||||
if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) {
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_GPIO);
|
||||
}
|
||||
pybpin_wake_pin[idx].lpds = PYBPIN_WAKES_NOT;
|
||||
}
|
||||
|
||||
if (args[4].u_int & PYB_PWR_MODE_HIBERNATE) {
|
||||
uint wake_pin;
|
||||
uint wake_mode;
|
||||
// pin_num is actually : (package_pin - 1)
|
||||
switch (self->pin_num) {
|
||||
case 56: // GPIO2
|
||||
wake_pin = PRCM_HIB_GPIO2;
|
||||
break;
|
||||
case 58: // GPIO4
|
||||
wake_pin = PRCM_HIB_GPIO4;
|
||||
break;
|
||||
case 3: // GPIO13
|
||||
wake_pin = PRCM_HIB_GPIO13;
|
||||
break;
|
||||
case 7: // GPIO17
|
||||
wake_pin = PRCM_HIB_GPIO17;
|
||||
break;
|
||||
case 1: // GPIO11
|
||||
wake_pin = PRCM_HIB_GPIO11;
|
||||
break;
|
||||
case 16: // GPIO24
|
||||
wake_pin = PRCM_HIB_GPIO24;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
break;
|
||||
if (pwrmode & PYB_PWR_MODE_HIBERNATE) {
|
||||
if (idx >= PYBPIN_NUM_WAKE_PINS) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// intmodes are bit different in hibernate
|
||||
// wake modes are different in hibernate
|
||||
uint wake_mode;
|
||||
switch (intmode) {
|
||||
case GPIO_FALLING_EDGE:
|
||||
wake_mode = PRCM_HIB_FALL_EDGE;
|
||||
@ -629,26 +694,44 @@ STATIC mp_obj_t pin_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map
|
||||
wake_mode = PRCM_HIB_HIGH_LEVEL;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
goto invalid_args;
|
||||
break;
|
||||
}
|
||||
|
||||
// enable GPIO as a wake source during hibernate
|
||||
MAP_PRCMHibernateWakeUpGPIOSelect(wake_pin, wake_mode);
|
||||
MAP_PRCMHibernateWakeupSourceEnable(wake_pin);
|
||||
// enable this pin as wake-up source during hibernate
|
||||
pybpin_wake_pin[idx].hib = wake_mode;
|
||||
}
|
||||
else {
|
||||
pybpin_wake_pin[idx].hib = PYBPIN_WAKES_NOT;
|
||||
}
|
||||
|
||||
// we need to update the callback atomically, so we disable the
|
||||
// interrupt before we update anything.
|
||||
pin_extint_disable(self);
|
||||
// register the interrupt
|
||||
pin_extint_register((pin_obj_t *)self, intmode, priority);
|
||||
// create the callback
|
||||
if (pwrmode & PYB_PWR_MODE_ACTIVE) {
|
||||
// register the interrupt
|
||||
pin_extint_register((pin_obj_t *)self, intmode, priority);
|
||||
if (idx < PYBPIN_NUM_WAKE_PINS) {
|
||||
pybpin_wake_pin[idx].active = true;
|
||||
}
|
||||
}
|
||||
else if (idx < PYBPIN_NUM_WAKE_PINS) {
|
||||
pybpin_wake_pin[idx].active = false;
|
||||
}
|
||||
|
||||
// all checks have passed, now we can create the callback
|
||||
self->callback = mpcallback_new (self, args[1].u_obj, &pin_cb_methods);
|
||||
if (pwrmode & PYB_PWR_MODE_LPDS) {
|
||||
pybsleep_set_gpio_lpds_callback (self->callback);
|
||||
}
|
||||
|
||||
// enable the interrupt just before leaving
|
||||
pin_extint_enable(self);
|
||||
}
|
||||
return self->callback;
|
||||
|
||||
invalid_args:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_callback_obj, 1, pin_callback);
|
||||
|
||||
|
@ -159,15 +159,15 @@ void pybsleep_remove (const mp_obj_t obj) {
|
||||
}
|
||||
}
|
||||
|
||||
void pybsleep_set_wlan_wake_callback (mp_obj_t cb_obj) {
|
||||
void pybsleep_set_wlan_lpds_callback (mp_obj_t cb_obj) {
|
||||
pybsleep_wake_cb.wlan_wake_cb = cb_obj;
|
||||
}
|
||||
|
||||
void pybsleep_set_gpio_wake_callback (mp_obj_t cb_obj) {
|
||||
void pybsleep_set_gpio_lpds_callback (mp_obj_t cb_obj) {
|
||||
pybsleep_wake_cb.gpio_wake_cb = cb_obj;
|
||||
}
|
||||
|
||||
void pybsleep_set_timer_wake_callback (mp_obj_t cb_obj) {
|
||||
void pybsleep_set_timer_lpds_callback (mp_obj_t cb_obj) {
|
||||
pybsleep_wake_cb.timer_wake_cb = cb_obj;
|
||||
}
|
||||
|
||||
@ -356,6 +356,12 @@ STATIC void PRCMInterruptHandler (void) {
|
||||
if (pybsleep_wake_cb.gpio_wake_cb) {
|
||||
mpcallback_handler(pybsleep_wake_cb.gpio_wake_cb);
|
||||
}
|
||||
// clear all pending GPIO interrupts in order to
|
||||
// avoid duplicated calls to the handler
|
||||
MAP_IntPendClear(INT_GPIOA0);
|
||||
MAP_IntPendClear(INT_GPIOA1);
|
||||
MAP_IntPendClear(INT_GPIOA2);
|
||||
MAP_IntPendClear(INT_GPIOA3);
|
||||
break;
|
||||
case PRCM_LPDS_TIMER:
|
||||
if (pybsleep_wake_cb.timer_wake_cb) {
|
||||
@ -476,6 +482,7 @@ STATIC const mp_map_elem_t pybsleep_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hibernate), (mp_obj_t)&pyb_sleep_hibernate_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SUSPENDED), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HIBERNATING), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) },
|
||||
};
|
||||
|
@ -30,9 +30,9 @@
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYB_PWR_MODE_ACTIVE_IDLE (0x00)
|
||||
#define PYB_PWR_MODE_LPDS (0x01)
|
||||
#define PYB_PWR_MODE_HIBERNATE (0x02)
|
||||
#define PYB_PWR_MODE_ACTIVE (0x01)
|
||||
#define PYB_PWR_MODE_LPDS (0x02)
|
||||
#define PYB_PWR_MODE_HIBERNATE (0x04)
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
@ -50,8 +50,8 @@ extern const mp_obj_base_t pyb_sleep_obj;
|
||||
void pyblsleep_init0 (void);
|
||||
void pybsleep_add (const mp_obj_t obj, WakeUpCB_t wakeup);
|
||||
void pybsleep_remove (const mp_obj_t obj);
|
||||
void pybsleep_set_wlan_wake_callback (mp_obj_t cb_obj);
|
||||
void pybsleep_set_gpio_wake_callback (mp_obj_t cb_obj);
|
||||
void pybsleep_set_timer_wake_callback (mp_obj_t cb_obj);
|
||||
void pybsleep_set_wlan_lpds_callback (mp_obj_t cb_obj);
|
||||
void pybsleep_set_gpio_lpds_callback (mp_obj_t cb_obj);
|
||||
void pybsleep_set_timer_lpds_callback (mp_obj_t cb_obj);
|
||||
|
||||
#endif /* PYBSLEEP_H_ */
|
||||
|
@ -251,5 +251,6 @@ Q(Sleep)
|
||||
Q(idle)
|
||||
Q(suspend)
|
||||
Q(hibernate)
|
||||
Q(ACTIVE)
|
||||
Q(SUSPENDED)
|
||||
Q(HIBERNATING)
|
||||
|
Loading…
Reference in New Issue
Block a user