diff --git a/cc3200/misc/mpcallback.c b/cc3200/misc/mpcallback.c index 35342a0ccf..ff04e713f8 100644 --- a/cc3200/misc/mpcallback.c +++ b/cc3200/misc/mpcallback.c @@ -46,8 +46,8 @@ const mp_arg_t mpcallback_init_args[] = { { MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { 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_wakes, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYB_PWR_MODE_ACTIVE} }, + { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_wake_from, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYB_PWR_MODE_ACTIVE} }, }; /****************************************************************************** @@ -58,14 +58,14 @@ void mpcallback_init0 (void) { mp_obj_list_init(&MP_STATE_PORT(mpcallback_obj_list), 0); } -mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_t *methods) { +mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_t *methods, bool enable) { mpcallback_obj_t *self = m_new_obj(mpcallback_obj_t); self->base.type = &pyb_callback_type; self->handler = handler; self->parent = parent; self->methods = (mp_cb_methods_t *)methods; - self->isenabled = true; - // remove any old callback if present + self->isenabled = enable; + // remove it in case it was already registered mpcallback_remove(self->parent); mp_obj_list_append(&MP_STATE_PORT(mpcallback_obj_list), self); return self; @@ -138,11 +138,11 @@ void mpcallback_handler (mp_obj_t self_in) { // uncaught exception; disable the callback so that it doesn't run again self->methods->disable (self->parent); self->handler = mp_const_none; - // signal the error using the heart beat led and print an - // exception message as well - mperror_signal_error(); + // signal the error using the heart beat led and + // by printing a message printf("Uncaught exception in callback handler\n"); mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); + mperror_signal_error(); } gc_unlock(); } diff --git a/cc3200/misc/mpcallback.h b/cc3200/misc/mpcallback.h index 743d73fe12..6492a2e99e 100644 --- a/cc3200/misc/mpcallback.h +++ b/cc3200/misc/mpcallback.h @@ -62,12 +62,11 @@ extern const mp_obj_type_t pyb_callback_type; DECLARE PUBLIC FUNCTIONS ******************************************************************************/ void mpcallback_init0 (void); -mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_t *methods); +mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_t *methods, bool enable); mpcallback_obj_t *mpcallback_find (mp_obj_t parent); void mpcallback_wake_all (void); void mpcallback_remove (const mp_obj_t parent); void mpcallback_handler (mp_obj_t self_in); uint mpcallback_translate_priority (uint priority); -mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_t *methods); #endif /* MPCALLBACK_H_ */ diff --git a/cc3200/mods/modpyb.c b/cc3200/mods/modpyb.c index b56502589a..d73eb31b55 100644 --- a/cc3200/mods/modpyb.c +++ b/cc3200/mods/modpyb.c @@ -56,7 +56,6 @@ #include "portable.h" #include "task.h" #include "mpexception.h" -#include "mpcallback.h" #include "random.h" #include "pybadc.h" #include "pybi2c.h" diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c index b58d4aa247..406b49a39a 100644 --- a/cc3200/mods/modwlan.c +++ b/cc3200/mods/modwlan.c @@ -1087,8 +1087,8 @@ STATIC mp_obj_t wlan_scan(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_scan_obj, wlan_scan); /// \method callback(handler, pwrmode) -/// Create a callback object associated with WLAN -/// min num of arguments is 1 (wakes) +/// Create a callback object associated with the WLAN subsystem +/// Only takes one argument (wake_from) STATIC mp_obj_t wlan_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_arg_val_t args[mpcallback_INIT_NUM_ARGS]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args); @@ -1096,7 +1096,7 @@ STATIC mp_obj_t wlan_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma wlan_obj_t *self = pos_args[0]; mp_obj_t _callback = mpcallback_find(self); // check if any parameters were passed - if (kw_args->used > 0 || !_callback) { + if (kw_args->used > 0) { // check the power mode if (args[4].u_int != PYB_PWR_MODE_LPDS) { // throw an exception since WLAN only supports LPDS mode @@ -1104,10 +1104,12 @@ STATIC mp_obj_t wlan_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma } // create the callback - _callback = mpcallback_new (self, args[1].u_obj, &wlan_cb_methods); + _callback = mpcallback_new (self, args[1].u_obj, &wlan_cb_methods, true); // enable network wakeup pybsleep_set_wlan_lpds_callback (_callback); + } else if (!_callback) { + _callback = mpcallback_new (self, mp_const_none, &wlan_cb_methods, false); } return _callback; } diff --git a/cc3200/mods/pybpin.c b/cc3200/mods/pybpin.c index 6bc430a14b..0fcb490985 100644 --- a/cc3200/mods/pybpin.c +++ b/cc3200/mods/pybpin.c @@ -599,7 +599,7 @@ STATIC mp_obj_t pin_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map pin_obj_t *self = pos_args[0]; // check if any parameters were passed mp_obj_t _callback = mpcallback_find(self); - if (kw_args->used > 0 || !_callback) { + if (kw_args->used > 0) { // convert the priority to the correct value uint priority = mpcallback_translate_priority (args[2].u_int); // verify the interrupt mode @@ -703,13 +703,15 @@ STATIC mp_obj_t pin_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map } // all checks have passed, now we can create the callback - _callback = mpcallback_new (self, args[1].u_obj, &pin_cb_methods); + _callback = mpcallback_new (self, args[1].u_obj, &pin_cb_methods, true); if (pwrmode & PYB_PWR_MODE_LPDS) { pybsleep_set_gpio_lpds_callback (_callback); } // enable the interrupt just before leaving pin_extint_enable(self); + } else if (!_callback) { + _callback = mpcallback_new (self, mp_const_none, &pin_cb_methods, false); } return _callback; diff --git a/cc3200/mods/pybrtc.c b/cc3200/mods/pybrtc.c index 7a7506f1aa..1644d8aa80 100644 --- a/cc3200/mods/pybrtc.c +++ b/cc3200/mods/pybrtc.c @@ -215,8 +215,8 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp // check if any parameters were passed mp_obj_t _callback = mpcallback_find((mp_obj_t)&pyb_rtc_obj); - if (kw_args->used > 0 || !_callback) { - uint32_t f_mseconds = MAX(1, args[3].u_int); + if (kw_args->used > 0) { + uint32_t f_mseconds = MAX(1, mp_obj_get_int(args[3].u_obj)); uint32_t seconds; uint16_t mseconds; // get the seconds and the milliseconds from the RTC @@ -238,7 +238,7 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp pybrtc_data.prwmode = args[4].u_int; // create the callback - _callback = mpcallback_new ((mp_obj_t)&pyb_rtc_obj, args[1].u_obj, &pybrtc_cb_methods); + _callback = mpcallback_new ((mp_obj_t)&pyb_rtc_obj, args[1].u_obj, &pybrtc_cb_methods, true); // set the lpds callback pybsleep_set_timer_lpds_callback(_callback); @@ -248,6 +248,8 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp // enable the interrupt (the object is not relevant here, the function already knows it) pyb_rtc_callback_enable(NULL); + } else if (!_callback) { + _callback = mpcallback_new ((mp_obj_t)&pyb_rtc_obj, mp_const_none, &pybrtc_cb_methods, false); } return _callback; } diff --git a/cc3200/mods/pybtimer.c b/cc3200/mods/pybtimer.c index 1975cb4b25..69e1c827c9 100644 --- a/cc3200/mods/pybtimer.c +++ b/cc3200/mods/pybtimer.c @@ -744,7 +744,7 @@ STATIC mp_obj_t pyb_timer_channel_callback (mp_uint_t n_args, const mp_obj_t *po pyb_timer_channel_obj_t *ch = pos_args[0]; mp_obj_t _callback = mpcallback_find(ch); - if (kw_args->used > 0 || !_callback) { + if (kw_args->used > 0) { // convert the priority to the correct value uint priority = mpcallback_translate_priority (args[2].u_int); @@ -755,10 +755,10 @@ STATIC mp_obj_t pyb_timer_channel_callback (mp_uint_t n_args, const mp_obj_t *po } uint32_t _config = (ch->channel == TIMER_B) ? ((ch->timer->config & TIMER_B) >> 8) : (ch->timer->config & TIMER_A); + uint32_t c_value = mp_obj_get_int(args[3].u_obj); // validate and set the value if we are in edge count mode if (_config == TIMER_CFG_A_CAP_COUNT) { - uint32_t c_value = args[3].u_int; if (!c_value || c_value > 0xFFFF) { // zero or exceeds the maximum value of a 16-bit timer goto invalid_args; @@ -778,7 +778,7 @@ STATIC mp_obj_t pyb_timer_channel_callback (mp_uint_t n_args, const mp_obj_t *po case TIMER_CFG_A_CAP_COUNT: ch->timer->intflags |= TIMER_CAPA_MATCH << shift; // set the match value and make 1 the minimum - MAP_TimerMatchSet(ch->timer->timer, ch->channel, MAX(1, args[3].u_int)); + MAP_TimerMatchSet(ch->timer->timer, ch->channel, MAX(1, c_value)); break; case TIMER_CFG_A_CAP_TIME: ch->timer->intflags |= TIMER_CAPA_EVENT << shift; @@ -841,7 +841,7 @@ STATIC mp_obj_t pyb_timer_channel_callback (mp_uint_t n_args, const mp_obj_t *po MAP_TimerIntRegister(ch->timer->timer, ch->channel, pfnHandler); // create the callback - _callback = mpcallback_new (ch, args[1].u_obj, &pyb_timer_channel_cb_methods); + _callback = mpcallback_new (ch, args[1].u_obj, &pyb_timer_channel_cb_methods, true); // reload the timer uint32_t period_c; @@ -851,6 +851,8 @@ STATIC mp_obj_t pyb_timer_channel_callback (mp_uint_t n_args, const mp_obj_t *po // enable the callback before returning pyb_timer_channel_callback_enable(ch); + } else if (!_callback) { + _callback = mpcallback_new (ch, mp_const_none, &pyb_timer_channel_cb_methods, false); } return _callback; diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c index f4ac2881a1..4af9de61d7 100644 --- a/cc3200/mods/pybuart.c +++ b/cc3200/mods/pybuart.c @@ -203,7 +203,7 @@ mp_obj_t uart_callback_new (pyb_uart_obj_t *self, mp_obj_t handler, uint rxbuffe } // create the callback - mp_obj_t _callback = mpcallback_new ((mp_obj_t)self, handler, &uart_cb_methods); + mp_obj_t _callback = mpcallback_new ((mp_obj_t)self, handler, &uart_cb_methods, true); // enable the interrupts now uart_callback_enable (self); @@ -520,7 +520,7 @@ STATIC mp_obj_t pyb_uart_callback (mp_uint_t n_args, const mp_obj_t *pos_args, m // check if any parameters were passed pyb_uart_obj_t *self = pos_args[0]; mp_obj_t _callback = mpcallback_find((mp_obj_t)self); - if (kw_args->used > 0 || !_callback) { + if (kw_args->used > 0) { // convert the priority to the correct value uint priority = mpcallback_translate_priority (args[2].u_int); @@ -531,7 +531,9 @@ STATIC mp_obj_t pyb_uart_callback (mp_uint_t n_args, const mp_obj_t *pos_args, m } // register a new callback - return uart_callback_new (self, args[1].u_obj, args[3].u_int, priority); + return uart_callback_new (self, args[1].u_obj, mp_obj_get_int(args[3].u_obj), priority); + } else if (!_callback) { + _callback = mpcallback_new (self, mp_const_none, &uart_cb_methods, false); } return _callback; } diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h index 497f3a2a9a..adcaf59e03 100644 --- a/cc3200/qstrdefsport.h +++ b/cc3200/qstrdefsport.h @@ -317,7 +317,7 @@ Q(handler) Q(mode) Q(value) Q(priority) -Q(wakes) +Q(wake_from) // for Sleep class Q(Sleep) diff --git a/docs/library/network.rst b/docs/library/network.rst index 99a300dbec..1b00c4f0d0 100644 --- a/docs/library/network.rst +++ b/docs/library/network.rst @@ -336,12 +336,12 @@ class WLAN Returns a list of the devices currently connected. Each item in the list is a tuple of ``(ssid, mac)``. - .. method:: wlan.callback(wakes) + .. method:: wlan.callback(wake_from) Create a callback to be triggered when a WLAN event occurs during ``pyb.Sleep.SUSPENDED`` mode. Events are triggered by socket activity or by WLAN connection/disconnection. - - ``wakes`` can only be ``pyb.Sleep.SUSPENDED``. + - ``wake_from`` must be ``pyb.Sleep.SUSPENDED``. Returns a callback object. diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst index 00a65126d9..90de1f6f81 100644 --- a/docs/library/pyb.Pin.rst +++ b/docs/library/pyb.Pin.rst @@ -284,15 +284,15 @@ Methods - ``priority`` level of the interrupt. Can take values in the range 1-7. Higher values represent higher priorities. - ``handler`` is an optional function to be called when new characters arrive. - - ``wakes`` selects the power mode in which this interrupt can wake up the + - ``wake_from`` selects the power mode in which this interrupt can wake up the board. Please note: - - If ``wakes=pyb.Sleep.ACTIVE`` any pin can wake the board. - - If ``wakes=pyb.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``, + - If ``wake_from=pyb.Sleep.ACTIVE`` any pin can wake the board. + - If ``wake_from=pyb.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``, ``GP11``, GP17`` or ``GP24`` can wake the board. Note that only 1 of this pins can be enabled as a wake source at the same time, so, only the last enabled pin as a ``pyb.Sleep.SUSPENDED`` wake source will have effect. - - If ``wakes=pyb.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``, + - If ``wake_from=pyb.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``, ``GP11``, ``GP17`` and ``GP24`` can wake the board. In this case all of the 6 pins can be enabled as a ``pyb.Sleep.HIBERNATE`` wake source at the same time. - Values can be ORed to make a pin generate interrupts in more than one power diff --git a/docs/library/pyb.RTC.rst b/docs/library/pyb.RTC.rst index 478731247a..4b5f4e6b40 100644 --- a/docs/library/pyb.RTC.rst +++ b/docs/library/pyb.RTC.rst @@ -90,12 +90,12 @@ Methods .. only:: port_wipy - .. method:: rtc.callback(\*, value, handler=None, wakes=pyb.Sleep.ACTIVE) + .. method:: rtc.callback(\*, value, handler=None, wake_from=pyb.Sleep.ACTIVE) Create a callback object triggered by a real time clock alarm. - ``value`` is the alarm timeout in milliseconds. This parameter is required. - ``handler`` is the function to be called when the callback is triggered. - - ``wakes`` specifies the power mode from where this interrupt can wake + - ``wake_from`` specifies the power mode from where this interrupt can wake up the system. diff --git a/docs/wipy/quickref.rst b/docs/wipy/quickref.rst index 3dc12a111e..2acbaa5413 100644 --- a/docs/wipy/quickref.rst +++ b/docs/wipy/quickref.rst @@ -160,7 +160,7 @@ See :ref:`pyb.RTC ` and ``pyb.Sleep``. :: rtc_obj.callback(value=30000, handler=some_handler) # create a RTC alarm that expires in 30s - rtc.callback(value=30000, handler=some_handler, wakes=Sleep.SUSPENDED) + rtc.callback(value=30000, handler=some_handler, wake_from=Sleep.SUSPENDED) # go into suspended mode waiting for the RTC alarm to expire and wake us up Sleep.suspend() @@ -195,7 +195,7 @@ See :ref:`network.WLAN ` and ``pyb.Sleep``. :: pass print(wifi.ifconfig()) # enable wake on WLAN - wifi.callback(wakes=Sleep.SUSPENDED) + wifi.callback(wake_from=Sleep.SUSPENDED) # go to sleep Sleep.suspend() # now, connect to the FTP or the Telnet server and the WiPy will wake-up