Skip to content

Commit 04749e6

Browse files
committed
cc3200: Allow separate selection of the power mode in Pin callbacks.
1 parent 10f7ef0 commit 04749e6

6 files changed

Lines changed: 181 additions & 90 deletions

File tree

cc3200/misc/mpcallback.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const mp_arg_t mpcallback_init_args[] = {
5050
{ MP_QSTR_handler, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
5151
{ MP_QSTR_priority, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
5252
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
53-
{ MP_QSTR_wake, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYB_PWR_MODE_ACTIVE_IDLE } },
53+
{ MP_QSTR_wake, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYB_PWR_MODE_ACTIVE} },
5454
};
5555

5656
/******************************************************************************

cc3200/mods/modwlan.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ STATIC void wlan_reenable (SlWlanMode_t mode);
166166
STATIC void wlan_get_sl_mac (void);
167167
STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, const char* bssid, uint8_t sec,
168168
const char* key, uint32_t key_len);
169-
STATIC void wlan_callback_enable (mp_obj_t self_in);
170-
STATIC void wlan_callback_disable (mp_obj_t self_in);
169+
STATIC void wlan_lpds_callback_enable (mp_obj_t self_in);
170+
STATIC void wlan_lpds_callback_disable (mp_obj_t self_in);
171171

172172
//*****************************************************************************
173173
//
@@ -668,12 +668,12 @@ STATIC mp_obj_t wlan_init_helper(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
668668
return mp_const_none;
669669
}
670670

671-
STATIC void wlan_callback_enable (mp_obj_t self_in) {
672-
pybsleep_set_wlan_wake_callback (wlan_obj.callback);
671+
STATIC void wlan_lpds_callback_enable (mp_obj_t self_in) {
672+
pybsleep_set_wlan_lpds_callback (wlan_obj.callback);
673673
}
674674

675-
STATIC void wlan_callback_disable (mp_obj_t self_in) {
676-
pybsleep_set_wlan_wake_callback (NULL);
675+
STATIC void wlan_lpds_callback_disable (mp_obj_t self_in) {
676+
pybsleep_set_wlan_lpds_callback (NULL);
677677
}
678678

679679
/******************************************************************************/
@@ -957,7 +957,7 @@ STATIC mp_obj_t wlan_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
957957
self->callback = mpcallback_new (self, args[1].u_obj, &wlan_cb_methods);
958958

959959
// enable network wakeup
960-
pybsleep_set_wlan_wake_callback (self->callback);
960+
pybsleep_set_wlan_lpds_callback (self->callback);
961961
}
962962
return self->callback;
963963
}
@@ -1020,8 +1020,8 @@ STATIC MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table);
10201020

10211021
STATIC const mp_cb_methods_t wlan_cb_methods = {
10221022
.init = wlan_callback,
1023-
.enable = wlan_callback_enable,
1024-
.disable = wlan_callback_disable,
1023+
.enable = wlan_lpds_callback_enable,
1024+
.disable = wlan_lpds_callback_disable,
10251025
};
10261026

10271027
/******************************************************************************/

cc3200/mods/pybpin.c

Lines changed: 154 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,36 @@ STATIC void GPIOA2IntHandler (void);
119119
STATIC void GPIOA3IntHandler (void);
120120
STATIC void EXTI_Handler(uint port);
121121
STATIC void pin_obj_configure (const pin_obj_t *self);
122+
STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *wake_pin, uint *idx);
122123
STATIC void pin_extint_enable (mp_obj_t self_in);
123124
STATIC void pin_extint_disable (mp_obj_t self_in);
124125

126+
/******************************************************************************
127+
DEFINE CONSTANTS
128+
******************************************************************************/
129+
#define PYBPIN_NUM_WAKE_PINS (6)
130+
#define PYBPIN_WAKES_NOT (-1)
131+
132+
/******************************************************************************
133+
DEFINE TYPES
134+
******************************************************************************/
135+
typedef struct {
136+
bool active;
137+
int8_t lpds;
138+
int8_t hib;
139+
} pybpin_wake_pin_t;
140+
125141
/******************************************************************************
126142
DECLARE PRIVATE DATA
127143
******************************************************************************/
128144
STATIC const mp_cb_methods_t pin_cb_methods;
145+
STATIC pybpin_wake_pin_t pybpin_wake_pin[PYBPIN_NUM_WAKE_PINS] =
146+
{ {.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
147+
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
148+
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
149+
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
150+
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
151+
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT} } ;
129152

130153
/******************************************************************************
131154
DEFINE PUBLIC FUNCTIONS
@@ -248,14 +271,83 @@ STATIC void pin_obj_configure (const pin_obj_t *self) {
248271
MAP_PinConfigSet(self->pin_num, self->strength, self->type);
249272
}
250273

274+
STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *hib_pin, uint *idx) {
275+
// pin_num is actually : (package_pin - 1)
276+
switch (self->pin_num) {
277+
case 56: // GPIO2
278+
*hib_pin = PRCM_HIB_GPIO2;
279+
*idx = 0;
280+
break;
281+
case 58: // GPIO4
282+
*hib_pin = PRCM_HIB_GPIO4;
283+
*idx = 1;
284+
break;
285+
case 3: // GPIO13
286+
*hib_pin = PRCM_HIB_GPIO13;
287+
*idx = 2;
288+
break;
289+
case 7: // GPIO17
290+
*hib_pin = PRCM_HIB_GPIO17;
291+
*idx = 3;
292+
break;
293+
case 1: // GPIO11
294+
*hib_pin = PRCM_HIB_GPIO11;
295+
*idx = 4;
296+
break;
297+
case 16: // GPIO24
298+
*hib_pin = PRCM_HIB_GPIO24;
299+
*idx = 5;
300+
break;
301+
default:
302+
*idx = 0xFF;
303+
break;
304+
}
305+
}
306+
251307
STATIC void pin_extint_enable (mp_obj_t self_in) {
252-
pin_obj_t *self = self_in;
253-
MAP_GPIOIntClear(self->port, self->bit);
254-
MAP_GPIOIntEnable(self->port, self->bit);
308+
const pin_obj_t *self = self_in;
309+
uint hib_pin, idx;
310+
311+
pin_get_hibernate_pin_and_idx (self, &hib_pin, &idx);
312+
if (idx < PYBPIN_NUM_WAKE_PINS) {
313+
if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) {
314+
// enable GPIO as a wake source during LPDS
315+
MAP_PRCMLPDSWakeUpGPIOSelect(idx, pybpin_wake_pin[idx].lpds);
316+
MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_GPIO);
317+
}
318+
319+
if (pybpin_wake_pin[idx].hib != PYBPIN_WAKES_NOT) {
320+
// enable GPIO as a wake source during hibernate
321+
MAP_PRCMHibernateWakeUpGPIOSelect(hib_pin, pybpin_wake_pin[idx].hib);
322+
MAP_PRCMHibernateWakeupSourceEnable(hib_pin);
323+
}
324+
else {
325+
MAP_PRCMHibernateWakeupSourceDisable(hib_pin);
326+
}
327+
}
328+
// if idx is invalid, the the pin supports active_idle interrupts for sure
329+
if (idx >= PYBPIN_NUM_WAKE_PINS || pybpin_wake_pin[idx].active) {
330+
MAP_GPIOIntClear(self->port, self->bit);
331+
MAP_GPIOIntEnable(self->port, self->bit);
332+
}
255333
}
256334

257335
STATIC void pin_extint_disable (mp_obj_t self_in) {
258-
pin_obj_t *self = self_in;
336+
const pin_obj_t *self = self_in;
337+
uint hib_pin, idx;
338+
339+
pin_get_hibernate_pin_and_idx (self, &hib_pin, &idx);
340+
if (idx < PYBPIN_NUM_WAKE_PINS) {
341+
if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) {
342+
// disable GPIO as a wake source during LPDS
343+
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_GPIO);
344+
}
345+
if (pybpin_wake_pin[idx].hib != PYBPIN_WAKES_NOT) {
346+
// disable GPIO as a wake source during hibernate
347+
MAP_PRCMHibernateWakeupSourceDisable(hib_pin);
348+
}
349+
}
350+
// not need to check for the active flag, it's safe to disable it anyway
259351
MAP_GPIOIntDisable(self->port, self->bit);
260352
}
261353

@@ -534,35 +626,20 @@ STATIC mp_obj_t pin_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map
534626
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
535627
}
536628

537-
if (args[4].u_int & PYB_PWR_MODE_LPDS) {
538-
uint wake_pin;
539-
uint wake_mode;
540-
// pin_num is actually : (package_pin - 1)
541-
switch (self->pin_num) {
542-
case 56: // GPIO2
543-
wake_pin = PRCM_LPDS_GPIO2;
544-
break;
545-
case 58: // GPIO4
546-
wake_pin = PRCM_LPDS_GPIO4;
547-
break;
548-
case 3: // GPIO13
549-
wake_pin = PRCM_LPDS_GPIO13;
550-
break;
551-
case 7: // GPIO17
552-
wake_pin = PRCM_LPDS_GPIO17;
553-
break;
554-
case 1: // GPIO11
555-
wake_pin = PRCM_LPDS_GPIO11;
556-
break;
557-
case 16: // GPIO24
558-
wake_pin = PRCM_LPDS_GPIO24;
559-
break;
560-
default:
561-
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
562-
break;
563-
}
629+
uint pwrmode = args[4].u_int;
630+
if (pwrmode > (PYB_PWR_MODE_ACTIVE | PYB_PWR_MODE_LPDS | PYB_PWR_MODE_HIBERNATE)) {
631+
goto invalid_args;
632+
}
564633

565-
// intmodes are different in LDPS
634+
// get the wake info from this pin
635+
uint hib_pin, idx;
636+
pin_get_hibernate_pin_and_idx ((const pin_obj_t *)self, &hib_pin, &idx);
637+
if (pwrmode & PYB_PWR_MODE_LPDS) {
638+
if (idx >= PYBPIN_NUM_WAKE_PINS) {
639+
goto invalid_args;
640+
}
641+
// wake modes are different in LDPS
642+
uint wake_mode;
566643
switch (intmode) {
567644
case GPIO_FALLING_EDGE:
568645
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
577654
wake_mode = PRCM_LPDS_HIGH_LEVEL;
578655
break;
579656
default:
580-
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
657+
goto invalid_args;
581658
break;
582659
}
583660

584-
// enable GPIO as a wake source during LPDS
585-
MAP_PRCMLPDSWakeUpGPIOSelect(wake_pin, wake_mode);
586-
MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_GPIO);
587-
}
661+
// first clear the lpds value from all wake-able pins
662+
for (uint i = 0; i < PYBPIN_NUM_WAKE_PINS; i++) {
663+
pybpin_wake_pin[i].lpds = PYBPIN_WAKES_NOT;
664+
}
588665

589-
if (args[4].u_int & PYB_PWR_MODE_HIBERNATE) {
590-
uint wake_pin;
591-
uint wake_mode;
592-
// pin_num is actually : (package_pin - 1)
593-
switch (self->pin_num) {
594-
case 56: // GPIO2
595-
wake_pin = PRCM_HIB_GPIO2;
596-
break;
597-
case 58: // GPIO4
598-
wake_pin = PRCM_HIB_GPIO4;
599-
break;
600-
case 3: // GPIO13
601-
wake_pin = PRCM_HIB_GPIO13;
602-
break;
603-
case 7: // GPIO17
604-
wake_pin = PRCM_HIB_GPIO17;
605-
break;
606-
case 1: // GPIO11
607-
wake_pin = PRCM_HIB_GPIO11;
608-
break;
609-
case 16: // GPIO24
610-
wake_pin = PRCM_HIB_GPIO24;
611-
break;
612-
default:
613-
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
614-
break;
666+
// enable this pin as a wake-up source during LPDS
667+
pybpin_wake_pin[idx].lpds = wake_mode;
668+
}
669+
else {
670+
// this pin was the previous LPDS wake source, so disable it completely
671+
if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) {
672+
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_GPIO);
615673
}
674+
pybpin_wake_pin[idx].lpds = PYBPIN_WAKES_NOT;
675+
}
616676

617-
// intmodes are bit different in hibernate
677+
if (pwrmode & PYB_PWR_MODE_HIBERNATE) {
678+
if (idx >= PYBPIN_NUM_WAKE_PINS) {
679+
goto invalid_args;
680+
}
681+
// wake modes are different in hibernate
682+
uint wake_mode;
618683
switch (intmode) {
619684
case GPIO_FALLING_EDGE:
620685
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
629694
wake_mode = PRCM_HIB_HIGH_LEVEL;
630695
break;
631696
default:
632-
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
697+
goto invalid_args;
633698
break;
634699
}
635700

636-
// enable GPIO as a wake source during hibernate
637-
MAP_PRCMHibernateWakeUpGPIOSelect(wake_pin, wake_mode);
638-
MAP_PRCMHibernateWakeupSourceEnable(wake_pin);
701+
// enable this pin as wake-up source during hibernate
702+
pybpin_wake_pin[idx].hib = wake_mode;
703+
}
704+
else {
705+
pybpin_wake_pin[idx].hib = PYBPIN_WAKES_NOT;
639706
}
640707

641708
// we need to update the callback atomically, so we disable the
642709
// interrupt before we update anything.
643710
pin_extint_disable(self);
644-
// register the interrupt
645-
pin_extint_register((pin_obj_t *)self, intmode, priority);
646-
// create the callback
711+
if (pwrmode & PYB_PWR_MODE_ACTIVE) {
712+
// register the interrupt
713+
pin_extint_register((pin_obj_t *)self, intmode, priority);
714+
if (idx < PYBPIN_NUM_WAKE_PINS) {
715+
pybpin_wake_pin[idx].active = true;
716+
}
717+
}
718+
else if (idx < PYBPIN_NUM_WAKE_PINS) {
719+
pybpin_wake_pin[idx].active = false;
720+
}
721+
722+
// all checks have passed, now we can create the callback
647723
self->callback = mpcallback_new (self, args[1].u_obj, &pin_cb_methods);
724+
if (pwrmode & PYB_PWR_MODE_LPDS) {
725+
pybsleep_set_gpio_lpds_callback (self->callback);
726+
}
727+
648728
// enable the interrupt just before leaving
649729
pin_extint_enable(self);
650730
}
651731
return self->callback;
732+
733+
invalid_args:
734+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
652735
}
653736
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_callback_obj, 1, pin_callback);
654737

cc3200/mods/pybsleep.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,15 @@ void pybsleep_remove (const mp_obj_t obj) {
159159
}
160160
}
161161

162-
void pybsleep_set_wlan_wake_callback (mp_obj_t cb_obj) {
162+
void pybsleep_set_wlan_lpds_callback (mp_obj_t cb_obj) {
163163
pybsleep_wake_cb.wlan_wake_cb = cb_obj;
164164
}
165165

166-
void pybsleep_set_gpio_wake_callback (mp_obj_t cb_obj) {
166+
void pybsleep_set_gpio_lpds_callback (mp_obj_t cb_obj) {
167167
pybsleep_wake_cb.gpio_wake_cb = cb_obj;
168168
}
169169

170-
void pybsleep_set_timer_wake_callback (mp_obj_t cb_obj) {
170+
void pybsleep_set_timer_lpds_callback (mp_obj_t cb_obj) {
171171
pybsleep_wake_cb.timer_wake_cb = cb_obj;
172172
}
173173

@@ -356,6 +356,12 @@ STATIC void PRCMInterruptHandler (void) {
356356
if (pybsleep_wake_cb.gpio_wake_cb) {
357357
mpcallback_handler(pybsleep_wake_cb.gpio_wake_cb);
358358
}
359+
// clear all pending GPIO interrupts in order to
360+
// avoid duplicated calls to the handler
361+
MAP_IntPendClear(INT_GPIOA0);
362+
MAP_IntPendClear(INT_GPIOA1);
363+
MAP_IntPendClear(INT_GPIOA2);
364+
MAP_IntPendClear(INT_GPIOA3);
359365
break;
360366
case PRCM_LPDS_TIMER:
361367
if (pybsleep_wake_cb.timer_wake_cb) {
@@ -476,6 +482,7 @@ STATIC const mp_map_elem_t pybsleep_locals_dict_table[] = {
476482
{ MP_OBJ_NEW_QSTR(MP_QSTR_hibernate), (mp_obj_t)&pyb_sleep_hibernate_obj },
477483

478484
// class constants
485+
{ MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) },
479486
{ MP_OBJ_NEW_QSTR(MP_QSTR_SUSPENDED), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) },
480487
{ MP_OBJ_NEW_QSTR(MP_QSTR_HIBERNATING), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) },
481488
};

0 commit comments

Comments
 (0)