Commit ea5061e4 authored by Daniel Campora's avatar Daniel Campora
Browse files

cc3200: Improve callback API.

Rename "wakes" param to "wake_from" and make "value" an object
instead of an integer.
parent 4c5bfe2d
......@@ -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();
}
......
......@@ -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_ */
......@@ -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"
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -317,7 +317,7 @@ Q(handler)
Q(mode)
Q(value)
Q(priority)
Q(wakes)
Q(wake_from)
// for Sleep class
Q(Sleep)
......
......@@ -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.
......
......@@ -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
......
......@@ -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.
......@@ -160,7 +160,7 @@ See :ref:`pyb.RTC <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 <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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment