summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authordanicampora <danicampora@gmail.com>2015-03-04 13:52:39 +0100
committerdanicampora <danicampora@gmail.com>2015-03-11 17:00:33 +0100
commit9e44383e3f4092940a1e1b49a278978df99f7b08 (patch)
tree606ad67566b41bb037bd02e678891dfb69db6c70
parent73aee8da54f847341d0fd9718d05ca964654a6dd (diff)
downloadmicropython-9e44383e3f4092940a1e1b49a278978df99f7b08.tar.gz
micropython-9e44383e3f4092940a1e1b49a278978df99f7b08.zip
cc3200: Add power management framework. Add mpcallback class.
Supports suspend and hibernate modes. Waking is possible throug GPIO and WLAN. The mpcallback class is generic and can be reused by other classes.
-rw-r--r--cc3200/FreeRTOS/FreeRTOSConfig.h2
-rw-r--r--cc3200/application.mk4
-rw-r--r--cc3200/boards/LAUNCHXL/mpconfigboard.h2
-rw-r--r--cc3200/boards/cc3200_prefix.c2
-rw-r--r--cc3200/boards/make-pins.py5
-rw-r--r--cc3200/bootmgr/main.c8
-rw-r--r--cc3200/fatfs/src/drivers/sflash_diskio.h2
-rw-r--r--cc3200/hal/startup_gcc.c2
-rw-r--r--cc3200/misc/mpcallback.c205
-rw-r--r--cc3200/misc/mpcallback.h70
-rw-r--r--cc3200/misc/mperror.c6
-rw-r--r--cc3200/misc/pin_defs_cc3200.c25
-rw-r--r--cc3200/misc/pin_named_pins.c6
-rw-r--r--cc3200/mods/modpyb.c46
-rw-r--r--cc3200/mods/moduos.c4
-rw-r--r--cc3200/mods/moduos.h33
-rw-r--r--cc3200/mods/modutime.h5
-rw-r--r--cc3200/mods/modwlan.c71
-rw-r--r--cc3200/mods/modwlan.h5
-rw-r--r--cc3200/mods/pybpin.c436
-rw-r--r--cc3200/mods/pybpin.h41
-rw-r--r--cc3200/mods/pybrtc.c8
-rw-r--r--cc3200/mods/pybsleep.c1076
-rw-r--r--cc3200/mods/pybsleep.h28
-rw-r--r--cc3200/mods/pybuart.c193
-rw-r--r--cc3200/mods/pybuart.h1
-rw-r--r--cc3200/mods/pybwdt.c2
-rw-r--r--cc3200/mpconfigport.h1
-rw-r--r--cc3200/mptask.c17
-rw-r--r--cc3200/qstrdefsport.h31
-rw-r--r--cc3200/simplelink/oslib/osi.h10
-rw-r--r--cc3200/simplelink/oslib/osi_freertos.c6
-rw-r--r--cc3200/util/sleeprestore.h33
-rw-r--r--cc3200/util/sleeprestore.s61
34 files changed, 1279 insertions, 1168 deletions
diff --git a/cc3200/FreeRTOS/FreeRTOSConfig.h b/cc3200/FreeRTOS/FreeRTOSConfig.h
index e831b10345..2e9a514381 100644
--- a/cc3200/FreeRTOS/FreeRTOSConfig.h
+++ b/cc3200/FreeRTOS/FreeRTOSConfig.h
@@ -83,7 +83,7 @@
#define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
-#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 64 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 72 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16384 ) )
#define configMAX_TASK_NAME_LEN ( 8 )
#define configUSE_TRACE_FACILITY 0
diff --git a/cc3200/application.mk b/cc3200/application.mk
index d5b575fa40..c737baaa50 100644
--- a/cc3200/application.mk
+++ b/cc3200/application.mk
@@ -76,6 +76,7 @@ APP_MISC_SRC_C = $(addprefix misc/,\
FreeRTOSHooks.c \
pin_named_pins.c \
help.c \
+ mpcallback.c \
mperror.c \
mpexception.c \
pin_defs_cc3200.c \
@@ -89,8 +90,8 @@ APP_MODS_SRC_C = $(addprefix mods/,\
modutime.c \
modwlan.c \
pybadc.c \
- pybi2c.c \
pybpin.c \
+ pybi2c.c \
pybrtc.c \
pybsd.c \
pybsleep.c \
@@ -128,6 +129,7 @@ APP_UTIL_SRC_C = $(addprefix util/,\
APP_UTIL_SRC_S = $(addprefix util/,\
gchelper.s \
+ sleeprestore.s \
)
APP_MAIN_SRC_C = \
diff --git a/cc3200/boards/LAUNCHXL/mpconfigboard.h b/cc3200/boards/LAUNCHXL/mpconfigboard.h
index 2d12d4f6cb..7044cb003a 100644
--- a/cc3200/boards/LAUNCHXL/mpconfigboard.h
+++ b/cc3200/boards/LAUNCHXL/mpconfigboard.h
@@ -46,3 +46,5 @@
#define MICROPY_SYS_LED_PORT_PIN GPIO_PIN_1
#define MICROPY_SAFE_BOOT_PORT_PIN GPIO_PIN_6
+#define MICROPY_PORT_SFLASH_BLOCK_COUNT 32
+
diff --git a/cc3200/boards/cc3200_prefix.c b/cc3200/boards/cc3200_prefix.c
index 2b60134b52..394f8bfa6b 100644
--- a/cc3200/boards/cc3200_prefix.c
+++ b/cc3200/boards/cc3200_prefix.c
@@ -43,7 +43,7 @@
{ \
{ &pin_type }, \
.name = MP_QSTR_ ## p_pin_name, \
- .callback = NULL, \
+ .callback = mp_const_none, \
.port = PORT_A ## p_port, \
.type = PIN_TYPE_STD, \
.bit = (p_bit), \
diff --git a/cc3200/boards/make-pins.py b/cc3200/boards/make-pins.py
index 8d47171337..ebe7e6a33a 100644
--- a/cc3200/boards/make-pins.py
+++ b/cc3200/boards/make-pins.py
@@ -40,12 +40,11 @@ class Pin(object):
self.board_pin = True
def print(self):
- print('const pin_obj_t pin_{:6s} = PIN({:6s}, {:1d}, {:3d}, {:2d});'.format(
+ print('pin_obj_t pin_{:6s} = PIN({:6s}, {:1d}, {:3d}, {:2d});'.format(
self.name, self.name, self.port, self.gpio_bit, self.pin_num))
def print_header(self, hdr_file):
- hdr_file.write('extern const pin_obj_t pin_{:s};\n'.
- format(self.name))
+ hdr_file.write('extern pin_obj_t pin_{:s};\n'.format(self.name))
class Pins(object):
diff --git a/cc3200/bootmgr/main.c b/cc3200/bootmgr/main.c
index e718fd9e22..c7c149d217 100644
--- a/cc3200/bootmgr/main.c
+++ b/cc3200/bootmgr/main.c
@@ -57,7 +57,7 @@
//*****************************************************************************
// Local Constants
//*****************************************************************************
-#define SL_STOP_TIMEOUT 250
+#define SL_STOP_TIMEOUT 35
#define BOOTMGR_HASH_ALGO SHAMD5_ALGO_MD5
#define BOOTMGR_HASH_SIZE 32
#define BOOTMGR_BUFF_SIZE 512
@@ -65,8 +65,8 @@
#define BOOTMGR_WAIT_SAFE_MODE_MS 1600
#define BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS 200
-#define BOOTMGR_SAFE_MODE_ENTER_MS 700
-#define BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS 70
+#define BOOTMGR_SAFE_MODE_ENTER_MS 800
+#define BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS 80
//*****************************************************************************
// Exported functions declarations
@@ -307,7 +307,7 @@ int main (void) {
bootmgr_board_init();
// start simplelink since we need it to access the sflash
- sl_Start(NULL, NULL, NULL);
+ sl_Start(0, 0, 0);
// if a boot info file is found, load it, else, create a new one with the default boot info
if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_READ, NULL, &fhandle)) {
diff --git a/cc3200/fatfs/src/drivers/sflash_diskio.h b/cc3200/fatfs/src/drivers/sflash_diskio.h
index 26669f5898..de3093439c 100644
--- a/cc3200/fatfs/src/drivers/sflash_diskio.h
+++ b/cc3200/fatfs/src/drivers/sflash_diskio.h
@@ -2,7 +2,7 @@
#define SFLASH_DISKIO_H_
#define SFLASH_BLOCK_SIZE 2048
-#define SFLASH_BLOCK_COUNT 32 // makes for 64KB of space
+#define SFLASH_BLOCK_COUNT MICROPY_PORT_SFLASH_BLOCK_COUNT
#define SFLASH_SECTOR_SIZE 512
#define SFLASH_SECTOR_COUNT ((SFLASH_BLOCK_SIZE * SFLASH_BLOCK_COUNT) / SFLASH_SECTOR_SIZE)
#define SFLASH_SECTORS_PER_BLOCK (SFLASH_BLOCK_SIZE / SFLASH_SECTOR_SIZE)
diff --git a/cc3200/hal/startup_gcc.c b/cc3200/hal/startup_gcc.c
index 2d364f87d1..5dff9ffda4 100644
--- a/cc3200/hal/startup_gcc.c
+++ b/cc3200/hal/startup_gcc.c
@@ -65,7 +65,7 @@ void ResetISR(void);
#ifdef DEBUG
static void NmiSR(void) __attribute__( ( naked ) );
static void FaultISR( void ) __attribute__( ( naked ) );
-void HardFault_HandlerC(unsigned long *hardfault_args);
+void HardFault_HandlerC(uint32_t *pulFaultStackAddress);
static void BusFaultHandler(void) __attribute__( ( naked ) );
#endif
static void IntDefaultHandler(void) __attribute__( ( naked ) );
diff --git a/cc3200/misc/mpcallback.c b/cc3200/misc/mpcallback.c
new file mode 100644
index 0000000000..3a5611f5df
--- /dev/null
+++ b/cc3200/misc/mpcallback.c
@@ -0,0 +1,205 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Daniel Campora
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/mpconfig.h"
+#include MICROPY_HAL_H
+#include "py/obj.h"
+#include "py/runtime.h"
+#include "py/gc.h"
+#include "inc/hw_types.h"
+#include "interrupt.h"
+#include "pybsleep.h"
+#include "mpcallback.h"
+#include "mpexception.h"
+#include "mperror.h"
+
+
+/******************************************************************************
+ DECLARE PRIVATE FUNCTIONS
+ ******************************************************************************/
+STATIC mpcallback_obj_t *mpcallback_find (mp_obj_t parent);
+
+/******************************************************************************
+ DEFINE PUBLIC DATA
+ ******************************************************************************/
+const mp_arg_t mpcallback_init_args[] = {
+ { MP_QSTR_intmode, 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_wake, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYB_PWR_MODE_ACTIVE_IDLE } },
+};
+
+/******************************************************************************
+ DEFINE PUBLIC FUNCTIONS
+ ******************************************************************************/
+void mpcallback_init0 (void) {
+ // initialize the callback objects list
+ 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) {
+ 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;
+ // remove any old callback if present
+ mpcallback_remove(self->parent);
+ mp_obj_list_append(&MP_STATE_PORT(mpcallback_obj_list), self);
+ return self;
+}
+
+void mpcallback_remove (const mp_obj_t parent) {
+ mpcallback_obj_t *callback_obj;
+ if ((callback_obj = mpcallback_find(parent))) {
+ mp_obj_list_remove(&MP_STATE_PORT(mpcallback_obj_list), callback_obj);
+ }
+}
+
+uint mpcallback_translate_priority (uint priority) {
+ if (priority < 1 || priority > 7) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ }
+
+ switch (priority) {
+ case 1:
+ return INT_PRIORITY_LVL_7;
+ case 2:
+ return INT_PRIORITY_LVL_6;
+ case 3:
+ return INT_PRIORITY_LVL_5;
+ case 4:
+ return INT_PRIORITY_LVL_4;
+ case 5:
+ return INT_PRIORITY_LVL_3;
+ case 6:
+ return INT_PRIORITY_LVL_2;
+ case 7:
+ return INT_PRIORITY_LVL_1;
+ default:
+ return INT_PRIORITY_LVL_7;
+ }
+}
+
+void mpcallback_handler (mp_obj_t self_in) {
+ mpcallback_obj_t *self = self_in;
+ if (self->handler != mp_const_none) {
+ // disable interrupts to avoid nesting
+ uint primsk = disable_irq();
+ // when executing code within a handler we must lock the GC to prevent
+ // any memory allocations. We must also catch any exceptions.
+ gc_lock();
+ nlr_buf_t nlr;
+ if (nlr_push(&nlr) == 0) {
+ mp_call_function_1(self->handler, self->parent);
+ nlr_pop();
+ }
+ else {
+ // uncaught exception; disable the callback so that it doesn't run again
+ self->methods->disable (self->parent);
+ self->handler = mp_const_none;
+ // printing an exception here will cause a stack overflow that will end up in
+ // a hard fault, so is better to signal the uncaught (probably non-recoverable)
+ // exception by blinking the system led instead.
+ mperror_signal_error();
+ }
+ gc_unlock();
+ enable_irq(primsk);
+ }
+}
+
+/******************************************************************************
+ DEFINE PRIVATE FUNCTIONS
+ ******************************************************************************/
+STATIC mpcallback_obj_t *mpcallback_find (mp_obj_t parent) {
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(mpcallback_obj_list).len; i++) {
+ // search for the object and then remove it
+ mpcallback_obj_t *callback_obj = ((mpcallback_obj_t *)(MP_STATE_PORT(mpcallback_obj_list).items[i]));
+ if (callback_obj->parent == parent) {
+ return callback_obj;
+ }
+ }
+ return NULL;
+}
+
+/******************************************************************************/
+// Micro Python bindings
+
+/// \method init()
+/// Initializes the interrupt callback. With no parameters passed, everything will default
+/// to the values assigned to mpcallback_init_args[].
+STATIC mp_obj_t callback_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ mpcallback_obj_t *self = pos_args[0];
+ // this is a bit of a hack, but it let us reuse the callback_create method from our parent
+ ((mp_obj_t *)pos_args)[0] = self->parent;
+ self->methods->init (n_args, pos_args, kw_args);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(callback_init_obj, 1, callback_init);
+
+/// \method enable()
+/// Enables the interrupt callback
+STATIC mp_obj_t callback_enable (mp_obj_t self_in) {
+ mpcallback_obj_t *self = self_in;
+ self->methods->enable(self->parent);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(callback_enable_obj, callback_enable);
+
+/// \method disable()
+/// Disables the interrupt callback
+STATIC mp_obj_t callback_disable (mp_obj_t self_in) {
+ mpcallback_obj_t *self = self_in;
+ self->methods->disable(self->parent);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(callback_disable_obj, callback_disable);
+
+/// \method \call()
+/// Triggers the interrupt callback
+STATIC mp_obj_t callback_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+ mp_arg_check_num(n_args, n_kw, 0, 0, false);
+ mpcallback_handler (self_in);
+ return mp_const_none;
+}
+
+STATIC const mp_map_elem_t callback_locals_dict_table[] = {
+ // instance methods
+ { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&callback_init_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&callback_enable_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&callback_disable_obj },
+};
+
+STATIC MP_DEFINE_CONST_DICT(callback_locals_dict, callback_locals_dict_table);
+
+const mp_obj_type_t pyb_callback_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_callback,
+ .call = callback_call,
+ .locals_dict = (mp_obj_t)&callback_locals_dict,
+};
+
diff --git a/cc3200/misc/mpcallback.h b/cc3200/misc/mpcallback.h
new file mode 100644
index 0000000000..e0a9fc6a92
--- /dev/null
+++ b/cc3200/misc/mpcallback.h
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Daniel Campora
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MPCALLBACK_H_
+#define MPCALLBACK_H_
+
+/******************************************************************************
+ DEFINE CONSTANTS
+ ******************************************************************************/
+#define mpcallback_INIT_NUM_ARGS 5
+
+/******************************************************************************
+ DEFINE TYPES
+ ******************************************************************************/
+typedef void (*mp_cb_method_t) (mp_obj_t self);
+typedef mp_obj_t (*mp_cb_init_t) (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
+
+typedef struct {
+ mp_cb_init_t init;
+ mp_cb_method_t enable;
+ mp_cb_method_t disable;
+} mp_cb_methods_t;
+
+typedef struct {
+ mp_obj_base_t base;
+ mp_obj_t parent;
+ mp_obj_t handler;
+ mp_cb_methods_t *methods;
+} mpcallback_obj_t;
+
+/******************************************************************************
+ DECLARE EXPORTED DATA
+ ******************************************************************************/
+extern const mp_arg_t mpcallback_init_args[];
+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);
+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/misc/mperror.c b/cc3200/misc/mperror.c
index 522e76396f..32e04ba00c 100644
--- a/cc3200/misc/mperror.c
+++ b/cc3200/misc/mperror.c
@@ -51,8 +51,8 @@
/******************************************************************************
DEFINE CONSTANTS
******************************************************************************/
-#define MPERROR_TOOGLE_MS (200)
-#define MPERROR_SIGNAL_ERROR_MS (2000)
+#define MPERROR_TOOGLE_MS (40)
+#define MPERROR_SIGNAL_ERROR_MS (1000)
#define MPERROR_HEARTBEAT_ON_MS (80)
#define MPERROR_HEARTBEAT_OFF_MS (2920)
@@ -113,7 +113,7 @@ void mperror_deinit_sfe_pin (void) {
void mperror_signal_error (void) {
uint32_t count = 0;
- while ((MPERROR_TOOGLE_MS * count++) > MPERROR_SIGNAL_ERROR_MS) {
+ while ((MPERROR_TOOGLE_MS * count++) < MPERROR_SIGNAL_ERROR_MS) {
// toogle the led
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, ~MAP_GPIOPinRead(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN));
UtilsDelay(UTILS_DELAY_US_TO_COUNT(MPERROR_TOOGLE_MS * 1000));
diff --git a/cc3200/misc/pin_defs_cc3200.c b/cc3200/misc/pin_defs_cc3200.c
index e585161bc0..a9b9413a12 100644
--- a/cc3200/misc/pin_defs_cc3200.c
+++ b/cc3200/misc/pin_defs_cc3200.c
@@ -26,6 +26,7 @@
*/
#include "py/mpconfig.h"
+#include MICROPY_HAL_H
#include "py/obj.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
@@ -35,32 +36,20 @@
#include "gpio.h"
#include "pin.h"
#include "pybpin.h"
-#include MICROPY_HAL_H
+
// Returns the pin mode. This value returned by this macro should be one of:
// GPIO_DIR_MODE_IN or GPIO_DIR_MODE_OUT
-uint32_t pin_get_mode(const pin_obj_t *self) {
- return MAP_GPIODirModeGet(self->port, self->bit);
+uint32_t pin_get_mode (const pin_obj_t *self) {
+ return self->mode;
}
-uint32_t pin_get_type(const pin_obj_t *self) {
-
- uint32_t strenght;
- uint32_t type;
-
- MAP_PinConfigGet(self->pin_num, &strenght, &type);
-
- return type;
+uint32_t pin_get_type (const pin_obj_t *self) {
+ return self->type;
}
uint32_t pin_get_strenght (const pin_obj_t *self) {
-
- uint32_t strenght;
- uint32_t type;
-
- MAP_PinConfigGet(self->pin_num, &strenght, &type);
-
- return strenght;
+ return self->strength;
}
diff --git a/cc3200/misc/pin_named_pins.c b/cc3200/misc/pin_named_pins.c
index 67f75c3302..590e013d44 100644
--- a/cc3200/misc/pin_named_pins.c
+++ b/cc3200/misc/pin_named_pins.c
@@ -49,7 +49,7 @@ const mp_obj_type_t pin_cpu_pins_obj_type = {
.locals_dict = (mp_obj_t)&pin_cpu_pins_locals_dict,
};
-const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
+pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
mp_map_elem_t *named_elem = mp_map_lookup(named_map, name, MP_MAP_LOOKUP);
if (named_elem != NULL && named_elem->value != NULL) {
@@ -58,7 +58,7 @@ const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t na
return NULL;
}
-const pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num) {
+pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num) {
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
for (uint i = 0; i < named_map->used; i++) {
if (((pin_obj_t *)named_map->table[i].value)->pin_num == pin_num) {
@@ -68,7 +68,7 @@ const pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num) {
return NULL;
}
-const pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit) {
+pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit) {
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
for (uint i = 0; i < named_map->used; i++) {
if ((((pin_obj_t *)named_map->table[i].value)->port == port) &&
diff --git a/cc3200/mods/modpyb.c b/cc3200/mods/modpyb.c
index 0caea7b3d5..13c787cc4e 100644
--- a/cc3200/mods/modpyb.c
+++ b/cc3200/mods/modpyb.c
@@ -30,6 +30,7 @@
#include <stdint.h>
#include "py/mpstate.h"
+#include "py/runtime.h"
#include MICROPY_HAL_H
#include "irq.h"
#include "inc/hw_types.h"
@@ -45,6 +46,7 @@
#include "pybsystick.h"
#include "simplelink.h"
#include "modwlan.h"
+#include "moduos.h"
#include "telnet.h"
#include "ff.h"
#include "diskio.h"
@@ -53,11 +55,13 @@
#include "portable.h"
#include "task.h"
#include "mpexception.h"
+#include "mpcallback.h"
#include "random.h"
#include "pybadc.h"
#include "pybi2c.h"
#include "pybsd.h"
#include "pybwdt.h"
+#include "pybsleep.h"
#include "utils.h"
#include "gccollect.h"
#include "mperror.h"
@@ -69,6 +73,7 @@ extern OsiTaskHandle svTaskHandle;
extern OsiTaskHandle xSimpleLinkSpawnTaskHndl;
#endif
+
/// \module pyb - functions related to the pyboard
///
/// The `pyb` module contains specific functions related to the pyboard.
@@ -117,15 +122,6 @@ STATIC mp_obj_t pyb_info(uint n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_info_obj, 0, 1, pyb_info);
#endif
-/// \function unique_id()
-/// Returns a string of 6 bytes (48 bits), which is the unique MAC address of the SoC
-STATIC mp_obj_t pyb_mac(void) {
- uint8_t mac[6];
- wlan_get_mac (mac);
- return mp_obj_new_bytes(mac, 6);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_mac_obj, pyb_mac);
-
/// \function freq()
/// Returns the CPU frequency: (F_CPU).
STATIC mp_obj_t pyb_freq(void) {
@@ -133,14 +129,6 @@ STATIC mp_obj_t pyb_freq(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_freq_obj, pyb_freq);
-/// \function sync()
-/// Sync all file systems.
-STATIC mp_obj_t pyb_sync(void) {
- sflash_disk_flush();
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_sync_obj, pyb_sync);
-
/// \function millis()
/// Returns the number of milliseconds since the board was last reset.
///
@@ -225,18 +213,6 @@ STATIC mp_obj_t pyb_udelay(mp_obj_t usec_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay);
-STATIC mp_obj_t pyb_stop(void) {
- return mp_const_none;
-}
-
-MP_DEFINE_CONST_FUN_OBJ_0(pyb_stop_obj, pyb_stop);
-
-STATIC mp_obj_t pyb_standby(void) {
- return mp_const_none;
-}
-
-MP_DEFINE_CONST_FUN_OBJ_0(pyb_standby_obj, pyb_standby);
-
/// \function repl_uart(uart)
/// Get or set the UART object that the REPL is repeated on.
STATIC mp_obj_t pyb_repl_uart(uint n_args, const mp_obj_t *args) {
@@ -275,31 +251,26 @@ MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_hard_reset), (mp_obj_t)&pyb_hard_reset_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&pyb_hard_reset_obj },
#ifdef DEBUG
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_info_obj },
#endif
- { MP_OBJ_NEW_QSTR(MP_QSTR_mac), (mp_obj_t)&pyb_mac_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&pyb_freq_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_repl_uart), (mp_obj_t)&pyb_repl_uart_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_wfi), (mp_obj_t)&pyb_wfi_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&pyb_stop_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&pyb_standby_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&pyb_main_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_repl_uart), (mp_obj_t)&pyb_repl_uart_obj },
-
{ MP_OBJ_NEW_QSTR(MP_QSTR_millis), (mp_obj_t)&pyb_millis_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_millis), (mp_obj_t)&pyb_elapsed_millis_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_micros), (mp_obj_t)&pyb_micros_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_micros), (mp_obj_t)&pyb_elapsed_micros_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&pyb_sync_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdisk), (mp_obj_t)&pyb_mkdisk_obj },
#if MICROPY_HW_ENABLE_RNG
@@ -315,6 +286,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_Sleep), (mp_obj_t)&pyb_sleep_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_HeartBeat), (mp_obj_t)&pyb_heartbeat_obj },
#if MICROPY_HW_HAS_SDCARD
diff --git a/cc3200/mods/moduos.c b/cc3200/mods/moduos.c
index 418f3608a8..b071413d1e 100644
--- a/cc3200/mods/moduos.c
+++ b/cc3200/mods/moduos.c
@@ -282,11 +282,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
/// \function sync()
/// Sync all filesystems.
-STATIC mp_obj_t os_sync(void) {
+mp_obj_t os_sync(void) {
sflash_disk_flush();
return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
+MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
#if MICROPY_HW_ENABLE_RNG
/// \function urandom(n)
diff --git a/cc3200/mods/moduos.h b/cc3200/mods/moduos.h
new file mode 100644
index 0000000000..8ce872c4b1
--- /dev/null
+++ b/cc3200/mods/moduos.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2015 Daniel Campora
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MODUTIME_H_
+#define MODUTIME_H_
+
+MP_DECLARE_CONST_FUN_OBJ(os_sync_obj);
+
+#endif // MODUTIME_H_
diff --git a/cc3200/mods/modutime.h b/cc3200/mods/modutime.h
index 5f1e8ed746..bc2be9cfa2 100644
--- a/cc3200/mods/modutime.h
+++ b/cc3200/mods/modutime.h
@@ -25,6 +25,9 @@
* THE SOFTWARE.
*/
+#ifndef MODUOS_H_
+#define MODUOS_H_
+
typedef struct {
uint16_t tm_year; // i.e. 2014
uint8_t tm_mon; // 1..12
@@ -41,3 +44,5 @@ extern mp_uint_t mod_time_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp
mp_uint_t hour, mp_uint_t minute, mp_uint_t second);
extern void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm);
+
+#endif // MODUOS_H_
diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c
index 6cb1ec21d6..c4f9bb31ac 100644
--- a/cc3200/mods/modwlan.c
+++ b/cc3200/mods/modwlan.c
@@ -41,6 +41,8 @@
#include "serverstask.h"
#endif
#include "mpexception.h"
+#include "mpcallback.h"
+#include "pybsleep.h"
/******************************************************************************
@@ -77,6 +79,7 @@ typedef enum{
typedef struct _wlan_obj_t {
mp_obj_base_t base;
+ mp_obj_t callback;
SlWlanMode_t mode;
uint32_t status;
@@ -122,7 +125,6 @@ typedef struct _wlan_obj_t {
#define ASSERT_ON_ERROR( x ) ASSERT((x) >= 0 )
#define IPV4_ADDR_STR_LEN_MAX (16)
-#define SL_STOP_TIMEOUT 250
#define WLAN_MAX_RX_SIZE 16000
#define WLAN_MAX_TX_SIZE 1476
@@ -147,6 +149,7 @@ typedef struct _wlan_obj_t {
DECLARE PRIVATE DATA
******************************************************************************/
STATIC wlan_obj_t wlan_obj;
+STATIC const mp_cb_methods_t wlan_cb_methods;
/******************************************************************************
DECLARE PUBLIC DATA
@@ -161,7 +164,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);
//*****************************************************************************
//
@@ -555,10 +559,6 @@ void wlan_get_ip (uint32_t *ip) {
}
}
-void wlan_set_pm_policy (uint8_t policy) {
- ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_PM, policy, NULL, 0));
-}
-
void wlan_stop_servers (void) {
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
servers_disable();
@@ -657,7 +657,7 @@ STATIC mp_obj_t wlan_init_helper(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
const char *key = mp_obj_str_get_data(args[3].u_obj, &key_len);
if (key_len < 8) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_value_invalid_arguments));
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
// Force the channel to be between 1-11
@@ -670,6 +670,13 @@ 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_callback_disable (mp_obj_t self_in) {
+ pybsleep_set_wlan_wake_callback (NULL);
+}
/******************************************************************************/
// Micro Python bindings; WLAN class
@@ -714,7 +721,7 @@ STATIC mp_obj_t wlan_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_k
STATIC void wlan_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
wlan_obj_t *self = self_in;
- print(env, "<WLAN mode=%u", self->mode);
+ print(env, "<WLAN, mode=%u", self->mode);
// only print the bssid if in station mode
if (self->mode != ROLE_AP && GET_STATUS_BIT(self->status, STATUS_BIT_CONNECTION)) {
@@ -739,16 +746,6 @@ STATIC mp_obj_t wlan_getmode(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_getmode_obj, wlan_getmode);
-STATIC mp_obj_t wlan_setpm(mp_obj_t self_in, mp_obj_t pm_mode) {
- mp_int_t mode = mp_obj_get_int(pm_mode);
- if (mode < SL_NORMAL_POLICY || mode > SL_LONG_SLEEP_INTERVAL_POLICY) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
- }
- wlan_set_pm_policy((uint8_t)mode);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(wlan_setpm_obj, wlan_setpm);
-
/// \method connect(ssid, security=OPEN, key=None, bssid=None)
// if security is WPA/WPA2, the key must be a string
/// if security is WEP, the key must be binary
@@ -947,6 +944,32 @@ 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(method, intmode, value, priority, pwrmode)
+/// Creates a callback object associated with WLAN
+/// min num of arguments is 1 (intmode)
+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);
+
+ wlan_obj_t *self = pos_args[0];
+ // check if any parameters were passed
+ if (kw_args->used > 0 || self->callback == mp_const_none) {
+ // check the power mode
+ if (args[4].u_int != PYB_PWR_MODE_LPDS) {
+ // throw an exception since WLAN only supports LPDS mode
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ }
+
+ // create the callback
+ self->callback = mpcallback_new (self, args[1].u_obj, &wlan_cb_methods);
+
+ // enable network wakeup
+ pybsleep_set_wlan_wake_callback (self->callback);
+ }
+ return self->callback;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_callback_obj, 1, wlan_callback);
+
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
STATIC mp_obj_t wlan_serversstart(mp_obj_t self_in) {
servers_enable();
@@ -977,12 +1000,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(wlan_serversuserpass_obj, wlan_serversuserpass)
STATIC const mp_map_elem_t wlan_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&wlan_connect_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_getmode), (mp_obj_t)&wlan_getmode_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_setpm), (mp_obj_t)&wlan_setpm_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&wlan_scan_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_disconnect), (mp_obj_t)&wlan_disconnect_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_isconnected), (mp_obj_t)&wlan_isconnected_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ifconfig), (mp_obj_t)&wlan_ifconfig_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_urn), (mp_obj_t)&wlan_urn_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&wlan_callback_obj },
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
{ MP_OBJ_NEW_QSTR(MP_QSTR_start_servers), (mp_obj_t)&wlan_serversstart_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_stop_servers), (mp_obj_t)&wlan_serversstop_obj },
@@ -1000,14 +1023,14 @@ STATIC const mp_map_elem_t wlan_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_STA), MP_OBJ_NEW_SMALL_INT(ROLE_STA) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_AP), MP_OBJ_NEW_SMALL_INT(ROLE_AP) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_P2P), MP_OBJ_NEW_SMALL_INT(ROLE_P2P) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_NORMAL_PM), MP_OBJ_NEW_SMALL_INT(SL_NORMAL_POLICY) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_LOW_LATENCY_PM), MP_OBJ_NEW_SMALL_INT(SL_LOW_LATENCY_POLICY) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_LOW_POWER_PM), MP_OBJ_NEW_SMALL_INT(SL_LOW_POWER_POLICY) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ALWAYS_ON_PM), MP_OBJ_NEW_SMALL_INT(SL_ALWAYS_ON_POLICY) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_LONG_SLEEP_PM), MP_OBJ_NEW_SMALL_INT(SL_LONG_SLEEP_INTERVAL_POLICY) },
};
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,
+};
/******************************************************************************/
// Micro Python bindings; WLAN socket
diff --git a/cc3200/mods/modwlan.h b/cc3200/mods/modwlan.h
index 684708e647..da60d2690f 100644
--- a/cc3200/mods/modwlan.h
+++ b/cc3200/mods/modwlan.h
@@ -32,6 +32,7 @@
******************************************************************************/
#define SIMPLELINK_SPAWN_TASK_PRIORITY 3
#define SIMPLELINK_TASK_STACK_SIZE 2048
+#define SL_STOP_TIMEOUT 35
/******************************************************************************
DEFINE TYPES
@@ -40,8 +41,7 @@ typedef enum {
MODWLAN_OK = 0,
MODWLAN_ERROR_INVALID_PARAMS = -1,
MODWLAN_ERROR_TIMEOUT = -2,
- MODWLAN_ERROR_UNKNOWN = -3
-
+ MODWLAN_ERROR_UNKNOWN = -3,
}modwlan_Status_t;
/******************************************************************************
@@ -60,7 +60,6 @@ extern void wlan_start (void);
extern SlWlanMode_t wlan_get_mode (void);
extern void wlan_get_mac (uint8_t *macAddress);
extern void wlan_get_ip (uint32_t *ip);
-extern void wlan_set_pm_policy (uint8_t policy);
extern void wlan_stop_servers (void);
#endif /* MODWLAN_H_ */
diff --git a/cc3200/mods/pybpin.c b/cc3200/mods/pybpin.c
index 493446d533..7e561064ce 100644
--- a/cc3200/mods/pybpin.c
+++ b/cc3200/mods/pybpin.c
@@ -34,6 +34,7 @@
#include "py/obj.h"
#include "py/runtime.h"
#include "py/gc.h"
+#include "py/mpstate.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
@@ -45,6 +46,7 @@
#include "interrupt.h"
#include "pybpin.h"
#include "pybsleep.h"
+#include "mpcallback.h"
#include "mpexception.h"
#include "mperror.h"
@@ -87,10 +89,15 @@
///
/// Example callback:
///
-/// def pincb(pin):
-/// print(pin.pin())
+/// def pincb(pin):
+/// print(pin.pin())
///
-/// extint = pyb.Pin('GPIO10', 0, pyb.Pin.INT_FALLING, pyb.GPIO.STD_PU, pyb.S2MA, callback=pincb)
+/// extint = pyb.Pin('GPIO10', 0, pyb.Pin.INT_RISING, pyb.GPIO.STD_PD, pyb.S2MA)
+/// extint.callback (intmode=pyb.Pin.INT_RISING, handler=pincb)
+/// # the callback can be triggered manually
+/// extint.callback()()
+/// # to disable the callback
+/// extint.callback().disable()
///
/// Now every time a falling edge is seen on the gpio pin, the callback will be
/// called. Caution: mechanical pushbuttons have "bounce" and pushing or
@@ -101,33 +108,34 @@
/// All pin objects go through the pin mapper to come up with one of the
/// gpio pins.
///
-/// extint = pyb.Pin(pin, af, mode, pull, strength, callback)
-///
/// There is also a C API, so that drivers which require Pin interrupts
/// can also use this code. See pybextint.h for the available functions.
/******************************************************************************
DECLARE PRIVATE FUNCTIONS
******************************************************************************/
-STATIC void ExecuteIntCallback (pin_obj_t *self);
STATIC void GPIOA0IntHandler (void);
STATIC void GPIOA1IntHandler (void);
STATIC void GPIOA2IntHandler (void);
STATIC void GPIOA3IntHandler (void);
STATIC void EXTI_Handler(uint port);
-STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *pin, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
STATIC void pin_obj_configure (const pin_obj_t *self);
+STATIC void pin_extint_enable (mp_obj_t self_in);
+STATIC void pin_extint_disable (mp_obj_t self_in);
+/******************************************************************************
+DECLARE PRIVATE DATA
+******************************************************************************/
+STATIC const mp_cb_methods_t pin_cb_methods;
/******************************************************************************
DEFINE PUBLIC FUNCTIONS
******************************************************************************/
void pin_init0(void) {
-
}
// C API used to convert a user-supplied pin name into an ordinal pin number.
-const pin_obj_t *pin_find(mp_obj_t user_obj) {
- const pin_obj_t *pin_obj;
+pin_obj_t *pin_find(mp_obj_t user_obj) {
+ pin_obj_t *pin_obj;
// If a pin was provided, then use it
if (MP_OBJ_IS_TYPE(user_obj, &pin_type)) {
@@ -162,25 +170,21 @@ void pin_verify_af (uint af) {
void pin_config (pin_obj_t *self, uint af, uint mode, uint type, uint strength) {
// configure the pin in analog mode
- ((pin_obj_t *)self)->af = af;
- ((pin_obj_t *)self)->mode = mode;
- ((pin_obj_t *)self)->type = type;
- ((pin_obj_t *)self)->strength = strength;
+ self->af = af;
+ self->mode = mode;
+ self->type = type;
+ self->strength = strength;
pin_obj_configure ((const pin_obj_t *)self);
// mark the pin as used
- ((pin_obj_t *)self)->used = true;
+ self->used = true;
// register it with the sleep module
- pybsleep_add (self, (WakeUpCB_t)pin_obj_configure);
+ pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pin_obj_configure);
}
-void pin_extint_register(pin_obj_t *self, uint32_t intmode, mp_obj_t callback) {
+void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t priority) {
void *handler;
uint32_t intnum;
- // we need to update the callback atomically, so we disable the line
- // before we update anything.
- pin_extint_disable(self);
-
// configure the interrupt type
MAP_GPIOIntTypeSet(self->port, self->bit, intmode);
switch (self->port) {
@@ -205,24 +209,7 @@ void pin_extint_register(pin_obj_t *self, uint32_t intmode, mp_obj_t callback) {
MAP_GPIOIntRegister(self->port, handler);
// set the interrupt to the lowest priority, to make sure that
// no other ISRs will be preemted by this one
- MAP_IntPrioritySet(intnum, INT_PRIORITY_LVL_7);
- // set the callback
- self->callback = callback;
- // enable the interrupt just before leaving
- pin_extint_enable(self);
-}
-
-void pin_extint_enable(pin_obj_t *self) {
- MAP_GPIOIntClear(self->port, self->bit);
- MAP_GPIOIntEnable(self->port, self->bit);
-}
-
-void pin_extint_disable(pin_obj_t *self) {
- MAP_GPIOIntDisable(self->port, self->bit);
-}
-
-void pin_extint_swint(pin_obj_t *self) {
- ExecuteIntCallback(self);
+ MAP_IntPrioritySet(intnum, priority);
}
/******************************************************************************
@@ -261,77 +248,20 @@ STATIC void pin_obj_configure (const pin_obj_t *self) {
MAP_PinConfigSet(self->pin_num, self->strength, self->type);
}
-/// \method print()
-/// Return a string describing the pin object.
-STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
+STATIC void pin_extint_enable (mp_obj_t self_in) {
pin_obj_t *self = self_in;
- uint32_t af = MAP_PinModeGet(self->pin_num);
- uint32_t type = pin_get_type(self);
- uint32_t strength = pin_get_strenght(self);
-
- // pin name
- print(env, "Pin(Pin.cpu.%s, af=%u", qstr_str(self->name), af);
-
- if (af == PIN_MODE_0) {
- // IO mode
- qstr mode_qst;
- uint32_t mode = pin_get_mode(self);
- if (mode == GPIO_DIR_MODE_IN) {
- mode_qst = MP_QSTR_IN;
- } else {
- mode_qst = MP_QSTR_OUT;
- }
- print(env, ", mode=Pin.%s", qstr_str(mode_qst)); // safe because mode_qst has no formatting chars
- }
-
- // pin type
- qstr type_qst;
- if (type == PIN_TYPE_STD) {
- type_qst = MP_QSTR_STD;
- } else if (type == PIN_TYPE_STD_PU) {
- type_qst = MP_QSTR_STD_PU;
- } else if (type == PIN_TYPE_STD_PD) {
- type_qst = MP_QSTR_STD_PD;
- } else if (type == PIN_TYPE_OD) {
- type_qst = MP_QSTR_OD;
- } else if (type == PIN_TYPE_OD_PU) {
- type_qst = MP_QSTR_OD_PU;
- } else {
- type_qst = MP_QSTR_OD_PD;
- }
- print(env, ", pull=Pin.%s", qstr_str(type_qst));
-
- // Strength
- qstr str_qst;
- if (strength == PIN_STRENGTH_2MA) {
- str_qst = MP_QSTR_S2MA;
- } else if (strength == PIN_STRENGTH_4MA) {
- str_qst = MP_QSTR_S4MA;
- } else {
- str_qst = MP_QSTR_S6MA;
- }
- print(env, ", strength=Pin.%s)", qstr_str(str_qst));
+ MAP_GPIOIntClear(self->port, self->bit);
+ MAP_GPIOIntEnable(self->port, self->bit);
}
-/// \classmethod \constructor(id, ...)
-/// Create a new Pin object associated with the id. If additional arguments are given,
-/// they are used to initialise the pin. See `init`.
-STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
-
- // Run an argument through the mapper and return the result.
- pin_obj_t *pin = (pin_obj_t *)pin_find(args[0]);
-
- if (n_args > 1) {
- // pin af given, so configure it
- mp_map_t kw_args;
- mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- pin_obj_init_helper(pin, n_args - 1, args + 1, &kw_args);
- }
-
- return (mp_obj_t)pin;
+STATIC void pin_extint_disable (mp_obj_t self_in) {
+ pin_obj_t *self = self_in;
+ MAP_GPIOIntDisable(self->port, self->bit);
}
+/******************************************************************************/
+// Micro Python bindings
+
/// \method init(mode, pull=Pin.PULL_NONE, af=-1)
/// Initialise the pin:
///
@@ -359,7 +289,6 @@ STATIC const mp_arg_t pin_init_args[] = {
{ MP_QSTR_mode, MP_ARG_INT, {.u_int = GPIO_DIR_MODE_OUT} },
{ MP_QSTR_type, MP_ARG_INT, {.u_int = PIN_TYPE_STD} },
{ MP_QSTR_str, MP_ARG_INT, {.u_int = PIN_STRENGTH_4MA} },
- { MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
#define pin_INIT_NUM_ARGS MP_ARRAY_SIZE(pin_init_args)
@@ -375,17 +304,10 @@ STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_
}
// get the io mode
uint mode = args[1].u_int;
- uint intmode = 0xFF;
// checking the mode only makes sense if af == GPIO
if (af == PIN_MODE_0) {
if (mode != GPIO_DIR_MODE_IN && mode != GPIO_DIR_MODE_OUT) {
- if (mode != GPIO_FALLING_EDGE && mode != GPIO_RISING_EDGE && mode != GPIO_BOTH_EDGES &&
- mode != GPIO_LOW_LEVEL && mode != GPIO_HIGH_LEVEL) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
- }
- // select input mode for interrupt triggering
- intmode = mode;
- mode = GPIO_DIR_MODE_IN;
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
}
// get the type
@@ -403,12 +325,78 @@ STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_
// configure the pin as requested
pin_config (self, af, mode, type, strength);
- // register the interrupt if the mode says so
- if (intmode != 0xFF) {
- pin_extint_register(self, intmode, args[4].u_obj);
+ return mp_const_none;
+}
+
+/// \method print()
+/// Return a string describing the pin object.
+STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
+ pin_obj_t *self = self_in;
+ uint32_t af = MAP_PinModeGet(self->pin_num);
+ uint32_t type = pin_get_type(self);
+ uint32_t strength = pin_get_strenght(self);
+
+ // pin name
+ print(env, "<Pin.cpu.%s, af=%u", qstr_str(self->name), af);
+
+ if (af == PIN_MODE_0) {
+ // IO mode
+ qstr mode_qst;
+ uint32_t mode = pin_get_mode(self);
+ if (mode == GPIO_DIR_MODE_IN) {
+ mode_qst = MP_QSTR_IN;
+ } else {
+ mode_qst = MP_QSTR_OUT;
+ }
+ print(env, ", mode=Pin.%s", qstr_str(mode_qst)); // safe because mode_qst has no formatting chars
}
- return mp_const_none;
+ // pin type
+ qstr type_qst;
+ if (type == PIN_TYPE_STD) {
+ type_qst = MP_QSTR_STD;
+ } else if (type == PIN_TYPE_STD_PU) {
+ type_qst = MP_QSTR_STD_PU;
+ } else if (type == PIN_TYPE_STD_PD) {
+ type_qst = MP_QSTR_STD_PD;
+ } else if (type == PIN_TYPE_OD) {
+ type_qst = MP_QSTR_OD;
+ } else if (type == PIN_TYPE_OD_PU) {
+ type_qst = MP_QSTR_OD_PU;
+ } else {
+ type_qst = MP_QSTR_OD_PD;
+ }
+ print(env, ", pull=Pin.%s", qstr_str(type_qst));
+
+ // Strength
+ qstr str_qst;
+ if (strength == PIN_STRENGTH_2MA) {
+ str_qst = MP_QSTR_S2MA;
+ } else if (strength == PIN_STRENGTH_4MA) {
+ str_qst = MP_QSTR_S4MA;
+ } else {
+ str_qst = MP_QSTR_S6MA;
+ }
+ print(env, ", strength=Pin.%s>", qstr_str(str_qst));
+}
+
+/// \classmethod \constructor(id, ...)
+/// Create a new Pin object associated with the id. If additional arguments are given,
+/// they are used to initialise the pin. See `init`.
+STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+ mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
+
+ // Run an argument through the mapper and return the result.
+ pin_obj_t *pin = (pin_obj_t *)pin_find(args[0]);
+
+ if (n_args > 1 || n_kw > 0) {
+ // pin af given, so configure it
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
+ pin_obj_init_helper(pin, n_args - 1, args + 1, &kw_args);
+ }
+
+ return (mp_obj_t)pin;
}
STATIC mp_obj_t pin_obj_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
@@ -419,7 +407,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pin_init_obj, 1, pin_obj_init);
/// \method value([value])
/// Get or set the digital logic level of the pin:
///
-/// - With no argument, return 0 or 1 depending on the logic level of the pin.
+/// - With no arguments, return 0 or 1 depending on the logic level of the pin.
/// - With `value` given, set the logic level of the pin. `value` can be
/// anything that converts to a boolean. If it converts to `True`, the pin
/// is set high, otherwise it is set low.
@@ -527,51 +515,142 @@ STATIC mp_obj_t pin_af(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_obj, pin_af);
-/// \method int_enable()
-/// Enable a disabled interrupt.
-STATIC mp_obj_t pin_int_enable(mp_obj_t self_in) {
- pin_obj_t *self = self_in;
- pin_extint_enable(self);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_int_enable_obj, pin_int_enable);
+/// \method callback(method, intmode, value, priority, pwrmode)
+/// Creates a callback object associated to a pin
+/// min num of arguments is 1 (intmode)
+STATIC mp_obj_t pin_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);
+
+ pin_obj_t *self = pos_args[0];
+ // check if any parameters were passed
+ if (kw_args->used > 0 || self->callback == mp_const_none) {
+ // convert the priority to the correct value
+ uint priority = mpcallback_translate_priority (args[2].u_int);
+ // verify the interrupt mode
+ uint intmode = args[0].u_int;
+ if (intmode != GPIO_FALLING_EDGE && intmode != GPIO_RISING_EDGE && intmode != GPIO_BOTH_EDGES &&
+ intmode != GPIO_LOW_LEVEL && intmode != GPIO_HIGH_LEVEL) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ }
-/// \method int_disable()
-/// Disable the interrupt associated with the Pin object.
-/// This could be useful for debouncing.
-STATIC mp_obj_t pin_int_disable(mp_obj_t self_in) {
- pin_obj_t *self = self_in;
- pin_extint_disable(self);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_int_disable_obj, pin_int_disable);
+ 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;
+ }
-/// \method intmode([mode])
-/// Get or set the interrupt mode of the pin:
-///
-/// - With no argument, returns the configured interrupt mode
-/// - With `mode` given, sets the interrupt mode of the pin
-STATIC mp_obj_t pin_intmode(mp_uint_t n_args, const mp_obj_t *args) {
- pin_obj_t *self = args[0];
- if (n_args == 1) {
- // get the interrupt mode
- return MP_OBJ_NEW_SMALL_INT(MAP_GPIOIntTypeGet(self->port, self->bit));
- } else {
- // set the interrupt mode
- MAP_GPIOIntTypeSet(self->port, self->bit, mp_obj_get_int(args[1]));
- return mp_const_none;
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_intmode_obj, 1, 2, pin_intmode);
+ // intmodes are different in LDPS
+ switch (intmode) {
+ case GPIO_FALLING_EDGE:
+ wake_mode = PRCM_LPDS_FALL_EDGE;
+ break;
+ case GPIO_RISING_EDGE:
+ wake_mode = PRCM_LPDS_RISE_EDGE;
+ break;
+ case GPIO_LOW_LEVEL:
+ wake_mode = PRCM_LPDS_LOW_LEVEL;
+ break;
+ case GPIO_HIGH_LEVEL:
+ wake_mode = PRCM_LPDS_HIGH_LEVEL;
+ break;
+ default:
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ break;
+ }
-/// \method swint()
-/// Trigger the interrupt callback from software.
-STATIC mp_obj_t pin_swint(mp_obj_t self_in) {
- pin_obj_t *self = self_in;
- pin_extint_swint(self);
- return mp_const_none;
+ // enable GPIO as a wake source during LPDS
+ MAP_PRCMLPDSWakeUpGPIOSelect(wake_pin, wake_mode);
+ MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_GPIO);
+ }
+
+ 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;
+ }
+
+ // intmodes are bit different in hibernate
+ switch (intmode) {
+ case GPIO_FALLING_EDGE:
+ wake_mode = PRCM_HIB_FALL_EDGE;
+ break;
+ case GPIO_RISING_EDGE:
+ wake_mode = PRCM_HIB_RISE_EDGE;
+ break;
+ case GPIO_LOW_LEVEL:
+ wake_mode = PRCM_HIB_LOW_LEVEL;
+ break;
+ case GPIO_HIGH_LEVEL:
+ wake_mode = PRCM_HIB_HIGH_LEVEL;
+ break;
+ default:
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ break;
+ }
+
+ // enable GPIO as a wake source during hibernate
+ MAP_PRCMHibernateWakeUpGPIOSelect(wake_pin, wake_mode);
+ MAP_PRCMHibernateWakeupSourceEnable(wake_pin);
+ }
+
+ // 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
+ self->callback = mpcallback_new (self, args[1].u_obj, &pin_cb_methods);
+ // enable the interrupt just before leaving
+ pin_extint_enable(self);
+ }
+ return self->callback;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_swint_obj, pin_swint);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_callback_obj, 1, pin_callback);
STATIC const mp_map_elem_t pin_locals_dict_table[] = {
// instance methods
@@ -587,10 +666,7 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_type), (mp_obj_t)&pin_type_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_strength), (mp_obj_t)&pin_strenght_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_af), (mp_obj_t)&pin_af_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_intenable), (mp_obj_t)&pin_int_enable_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_intdisable), (mp_obj_t)&pin_int_disable_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_intmode), (mp_obj_t)&pin_intmode_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_swint), (mp_obj_t)&pin_swint_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pin_callback_obj },
// class attributes
{ MP_OBJ_NEW_QSTR(MP_QSTR_cpu), (mp_obj_t)&pin_cpu_pins_obj_type },
@@ -641,30 +717,11 @@ const mp_obj_type_t pin_type = {
.locals_dict = (mp_obj_t)&pin_locals_dict,
};
-STATIC void ExecuteIntCallback (pin_obj_t *self) {
- if (self->callback != mp_const_none) {
- // disable interrupts to avoid nesting
- uint primsk = disable_irq();
- // when executing code within a handler we must lock the GC to prevent
- // any memory allocations. We must also catch any exceptions.
- gc_lock();
- nlr_buf_t nlr;
- if (nlr_push(&nlr) == 0) {
- mp_call_function_1(self->callback, self);
- nlr_pop();
- } else {
- // uncaught exception; disable the callback so that it doesn't run again
- self->callback = mp_const_none;
- pin_extint_disable(self);
- // printing an exception here will cause a stack overflow that ends up in a
- // hard fault so, is better to signal the uncaught (probably non-recoverable)
- // exception by blinkg the system led
- mperror_signal_error();
- }
- gc_unlock();
- enable_irq(primsk);
- }
-}
+STATIC const mp_cb_methods_t pin_cb_methods = {
+ .init = pin_callback,
+ .enable = pin_extint_enable,
+ .disable = pin_extint_disable,
+};
STATIC void GPIOA0IntHandler (void) {
EXTI_Handler(GPIOA0_BASE);
@@ -689,6 +746,7 @@ STATIC void EXTI_Handler(uint port) {
MAP_GPIOIntClear(port, bit);
if (NULL != (self = (pin_obj_t *)pin_find_pin_by_port_bit(&pin_cpu_pins_locals_dict, port, bit))) {
- ExecuteIntCallback(self);
+ mpcallback_handler(self->callback);
}
}
+
diff --git a/cc3200/mods/pybpin.h b/cc3200/mods/pybpin.h
index 6228fa2ec3..9cc0243d1a 100644
--- a/cc3200/mods/pybpin.h
+++ b/cc3200/mods/pybpin.h
@@ -33,24 +33,24 @@
#define PYBPIN_ANALOG_TYPE 0xFF
typedef struct {
- mp_obj_base_t base;
- qstr name;
- mp_obj_t callback;
- uint32_t port;
- uint16_t type;
- uint8_t bit;
- uint8_t pin_num;
- uint8_t af;
- uint8_t strength;
- uint8_t mode;
- bool used;
+ const mp_obj_base_t base;
+ const qstr name;
+ mp_obj_t callback;
+ const uint32_t port;
+ uint16_t type;
+ const uint8_t bit;
+ const uint8_t pin_num;
+ uint8_t af;
+ uint8_t strength;
+ uint8_t mode;
+ bool used;
} pin_obj_t;
extern const mp_obj_type_t pin_type;
typedef struct {
- const char *name;
- const pin_obj_t *pin;
+ const char *name;
+ const pin_obj_t *pin;
} pin_named_pin_t;
typedef struct {
@@ -62,19 +62,14 @@ typedef struct {
extern const mp_obj_type_t pin_cpu_pins_obj_type;
extern const mp_obj_dict_t pin_cpu_pins_locals_dict;
-MP_DECLARE_CONST_FUN_OBJ(pin_init_obj);
-
void pin_init0(void);
void pin_verify_af (uint af);
void pin_config(pin_obj_t *self, uint af, uint mode, uint type, uint strength);
-void pin_extint_register(pin_obj_t *self, uint32_t intmode, mp_obj_t callback);
-void pin_extint_enable(pin_obj_t *self);
-void pin_extint_disable(pin_obj_t *self);
-void pin_extint_swint(pin_obj_t *self);
-const pin_obj_t *pin_find(mp_obj_t user_obj);
-const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name);
-const pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num);
-const pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit);
+void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t priority);
+pin_obj_t *pin_find(mp_obj_t user_obj);
+pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name);
+pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num);
+pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit);
uint32_t pin_get_mode(const pin_obj_t *self);
uint32_t pin_get_type(const pin_obj_t *self);
uint32_t pin_get_strenght(const pin_obj_t *self);
diff --git a/cc3200/mods/pybrtc.c b/cc3200/mods/pybrtc.c
index 1844a6d7f3..5744662018 100644
--- a/cc3200/mods/pybrtc.c
+++ b/cc3200/mods/pybrtc.c
@@ -53,16 +53,16 @@
__attribute__ ((section (".boot")))
void pybrtc_init(void) {
- // if RTC was previously set leave it alone
+ // if the RTC was previously set, leave it alone
if (MAP_PRCMSysResetCauseGet() == PRCM_POWER_ON) {
- // fresh reset; configure RTC Calendar
+ // fresh reset; configure the RTC Calendar
// set the date to 1st Jan 2015
// set the time to 00:00:00
uint32_t seconds = mod_time_seconds_since_2000(2015, 1, 1, 0, 0, 0);
MAP_PRCMRTCSet(seconds, 0);
- // Mark that the RTC is in use
+ // Mark the RTC in use
MAP_PRCMRTCInUseSet();
}
}
@@ -90,7 +90,7 @@ STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n
/// Get or set the date and time of the RTC.
///
/// With no arguments, this method returns an 8-tuple with the current
-/// date and time. With 1 argument (being an 8-tuple) it sets the date
+/// date and time. With 1 argument (being an 8-tuple) it sets the date
/// and time.
///
/// The 8-tuple has the following format:
diff --git a/cc3200/mods/pybsleep.c b/cc3200/mods/pybsleep.c
index 8e94100a91..833c5882f1 100644
--- a/cc3200/mods/pybsleep.c
+++ b/cc3200/mods/pybsleep.c
@@ -30,13 +30,41 @@
#include "py/mpstate.h"
#include MICROPY_HAL_H
-#include "hw_types.h"
+#include "py/runtime.h"
+#include "inc/hw_types.h"
+#include "inc/hw_ints.h"
+#include "inc/hw_nvic.h"
+#include "inc/hw_common_reg.h"
+#include "inc/hw_memmap.h"
+#include "cc3200_asm.h"
+#include "rom_map.h"
+#include "interrupt.h"
+#include "systick.h"
+#include "prcm.h"
+#include "spi.h"
+#include "pin.h"
#include "pybsleep.h"
-
-/* Storage memory for Cortex M4 registers. To make implementation independent of
- CPU, register specific constructs must be made part of platform services.
-*/
-
+#include "pybpin.h"
+#include "simplelink.h"
+#include "modwlan.h"
+#include "osi.h"
+#include "debug.h"
+#include "mpexception.h"
+#include "mpcallback.h"
+#include "mperror.h"
+#include "sleeprestore.h"
+
+/******************************************************************************
+ DECLARE PRIVATE CONSTANTS
+ ******************************************************************************/
+#define SPIFLASH_INSTR_READ_STATUS (0x05)
+#define SPIFLASH_INSTR_DEEP_POWER_DOWN (0xB9)
+#define SPIFLASH_STATUS_BUSY (0x01)
+
+/******************************************************************************
+ DECLARE PRIVATE TYPES
+ ******************************************************************************/
+// storage memory for Cortex M4 registers
typedef struct {
uint32_t msp;
uint32_t psp;
@@ -45,189 +73,132 @@ typedef struct {
uint32_t faultmask;
uint32_t basepri;
uint32_t control;
-}arm_cm4_core_regs;
-
-//static arm_cm4_core_regs vault_arm_registers;
-
-
-#define BACK_UP_ARM_REGISTERS() { \
- __asm(" push {r0-r12, LR} \n" \
- " ldr r1, pxVaultRegistersSave \n" \
- " mrs r0, msp \n" \
- " str r0, [r1] \n" \
- " mrs r0, psp \n" \
- " str r0, [r1, #4] \n" \
- " mrs r0, primask \n" \
- " str r0, [r1, #12] \n" \
- " mrs r0, faultmask \n" \
- " str r0, [r1, #16] \n" \
- " mrs r0, basepri \n" \
- " str r0, [r1, #20] \n" \
- " mrs r0, control \n" \
- " str r0, [r1, #24] \n" \
- "pxVaultRegistersSave: .word vault_arm_registers \n"); \
-}
+} arm_cm4_core_regs_t;
-#define RESTORE_ARM_REGISTERS() { \
- __asm(" ldr r1, pxVaultRegistersLoad \n" \
- " ldr r0, [r1, #24] \n" \
- " msr control, r0 \n" \
- " ldr r0, [r1] \n" \
- " msr msp, r0 \n" \
- " ldr r0, [r1,#4] \n" \
- " msr psp, r0 \n" \
- " ldr r0, [r1, #12] \n" \
- " msr primask, r0 \n" \
- " ldr r0, [r1, #16] \n" \
- " msr faultmask, r0 \n" \
- " ldr r0, [r1, #20] \n" \
- " msr basepri, r0 \n" \
- " pop {r0-r12, LR} \n" \
- "pxVaultRegistersLoad: .word vault_arm_registers \n"); \
-}
+// storage memory for the NVIC registers
+typedef struct {
+ uint32_t vector_table; // Vector Table Offset
+ uint32_t aux_ctrl; // Auxiliary control register
+ uint32_t int_ctrl_state; // Interrupt Control and State
+ uint32_t app_int; // Application Interrupt Reset control
+ uint32_t sys_ctrl; // System control
+ uint32_t config_ctrl; // Configuration control
+ uint32_t sys_pri_1; // System Handler Priority 1
+ uint32_t sys_pri_2; // System Handler Priority 2
+ uint32_t sys_pri_3; // System Handler Priority 3
+ uint32_t sys_hcrs; // System Handler control and state register
+ uint32_t systick_ctrl; // SysTick Control Status
+ uint32_t systick_reload; // SysTick Reload
+ uint32_t systick_calib; // SysTick Calibration
+ uint32_t int_en[6]; // Interrupt set enable
+ uint32_t int_priority[49]; // Interrupt priority
+} nvic_reg_store_t;
-#if 0
-/* Called directly by boot ROM after waking from S3 state */
-void resume_from_S3(void)
-{
- /* Jump from ROM context hence introduce the sync barriers */
- INTRODUCE_SYNC_BARRIER(); /* Data and instruction sync barriers */
+typedef struct {
+ mp_obj_base_t base;
+ mp_obj_t obj;
+ WakeUpCB_t wakeup;
+} pybsleep_obj_t;
- RESTORE_ARM_REGISTERS(); /* Core registers and code is in assembly */
+typedef struct {
+ mp_obj_t wlan_wake_cb;
+ mp_obj_t timer_wake_cb;
+ mp_obj_t gpio_wake_cb;
+} pybsleep_wake_cb_t;
+
+/******************************************************************************
+ DECLARE PRIVATE DATA
+ ******************************************************************************/
+STATIC const mp_obj_type_t pybsleep_type;
+STATIC nvic_reg_store_t *nvic_reg_store;
+STATIC pybsleep_wake_cb_t pybsleep_wake_cb;
+volatile arm_cm4_core_regs_t vault_arm_registers;
+
+/******************************************************************************
+ DECLARE PRIVATE FUNCTIONS
+ ******************************************************************************/
+STATIC pybsleep_obj_t *pybsleep_find (mp_obj_t obj);
+STATIC void pybsleep_flash_powerdown (void);
+STATIC NORETURN void pybsleep_suspend_enter (void);
+void pybsleep_suspend_exit (void);
+STATIC void pybsleep_obj_wakeup (void);
+STATIC void PRCMInterruptHandler (void);
+STATIC void pybsleep_iopark (void);
+
+/******************************************************************************
+ DEFINE PUBLIC FUNCTIONS
+ ******************************************************************************/
+void pyblsleep_init0 (void) {
+ // initialize the sleep objects list
+ mp_obj_list_init(&MP_STATE_PORT(pybsleep_obj_list), 0);
- INTRODUCE_SYNC_BARRIER(); /* Data and instruction sync barriers */
+ // allocate memory for nvic registers vault
+ ASSERT ((nvic_reg_store = mem_Malloc(sizeof(nvic_reg_store_t))) != NULL);
- pform->pm_ops->restore_soc_data();
- make_modules_to_M0_no_irq(pform->used_list_len); /* Wake up all */
- pform->pm_ops->handle_S3_wakeup(); /* Should be last statement */
- return;
+ // enable and register the PRCM interrupt
+ osi_InterruptRegister(INT_PRCM, (P_OSI_INTR_ENTRY)PRCMInterruptHandler, INT_PRIORITY_LVL_1);
+ MAP_IntPendClear(INT_PRCM);
+ MAP_PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR);
}
-static void enter_into_S3(void)
-{
- pform->pm_ops->back_up_soc_data();
-
- INTRODUCE_SYNC_BARRIER(); /* Data and instruction sync barriers */
-
- BACK_UP_ARM_REGISTERS(); /* Core registers and code is in assembly */
-
- cc_enter_S3(resume_from_S3, vault_arm_registers.psp/*save_restore[1]*/);
-
- /* Introducing delays to facilitate CPU to fade away ........ */
- asm(" NOP"); asm(" NOP"); asm(" NOP"); asm(" NOP"); asm(" NOP");
- asm(" NOP"); asm(" NOP"); asm(" NOP"); asm(" NOP"); asm(" NOP");
- asm(" NOP"); asm(" NOP"); asm(" NOP"); asm(" NOP"); asm(" NOP");
+void pybsleep_add (const mp_obj_t obj, WakeUpCB_t wakeup) {
+ pybsleep_obj_t * sleep_obj = m_new_obj(pybsleep_obj_t);
+ sleep_obj->base.type = &pybsleep_type;
+ sleep_obj->obj = obj;
+ sleep_obj->wakeup = wakeup;
+ // only add objects once
+ if (!pybsleep_find(sleep_obj)) {
+ mp_obj_list_append(&MP_STATE_PORT(pybsleep_obj_list), sleep_obj);
+ }
}
-static void apply_io_park(u8 pin_num,
- enum io_park_state park_value)
-{
- u32 pin_strength, pin_type;
-
- if(DONT_CARE != park_value) {
- /* Change the pin mode to GPIO to be safe */
- //MAP_PinModeSet(pin_num, PIN_MODE_0);
-
- /* First apply PullUp/PullDn (or no pull) according
- to the default levels specified in the user supplied
- parking table */
- MAP_PinConfigGet(pin_num, &pin_strength, &pin_type);
-
- if(NO_PULL_HIZ != park_value) {
- MAP_PinConfigSet(pin_num, pin_strength, park_value);
- } else {
- MAP_PinConfigSet(pin_num, pin_strength, PIN_TYPE_STD);
- }
-
- /* One by one HiZ all the IOs,
- by writing the register that drives IOEN_N control
- pin of the IOs. This register and the signal path is
- always-on and hence not get lost during True-LPDS */
- MAP_PinDirModeSet(pin_num, PIN_DIR_MODE_IN);
-
- /* Once all the digital IOs has been made HiZ,
- the desired default PAD levels would be held by
- the weak-pulls. Input buffers would be alive
- (such as auto-SPI or wake-GPIOs) and would not
- have Iddq issue since pulls are present. */
- }
- return;
+void pybsleep_remove (const mp_obj_t obj) {
+ pybsleep_obj_t *sleep_obj;
+ if ((sleep_obj = pybsleep_find(obj))) {
+ mp_obj_list_remove(&MP_STATE_PORT(pybsleep_obj_list), sleep_obj);
+ }
}
-i32 cc_io_park_safe(struct soc_io_park *io_park_choice,
- u8 num_pins)
-{
- i32 loopcnt;
-
- if(NULL == io_park_choice) {
- return -1;
- }
+void pybsleep_set_wlan_wake_callback (mp_obj_t cb_obj) {
+ if (cb_obj) {
+ MAP_PRCMLPDSWakeupSourceEnable (PRCM_LPDS_HOST_IRQ);
+ }
+ else {
+ MAP_PRCMLPDSWakeupSourceDisable (PRCM_LPDS_HOST_IRQ);
+ }
+ pybsleep_wake_cb.wlan_wake_cb = cb_obj;
+}
- /* Park the IOs safely as specified by the application */
- for(loopcnt = 0; loopcnt < num_pins; loopcnt++) {
- switch(io_park_choice[loopcnt].pin_num) {
- /* Shared SPI pins for SFLASH */
- case PIN_11:
- case PIN_12:
- case PIN_13:
- case PIN_14:
-#ifdef DEBUG_MODE
- /* JTAG pins */
- case PIN_16:
- case PIN_17:
- case PIN_19:
- case PIN_20:
-#endif
- /* Do not park these pins as they may
- have external dependencies */
- break;
- default:
- /* Apply the specified IO parking scheme */
- apply_io_park(io_park_choice[loopcnt].pin_num,
- io_park_choice[loopcnt].park_val);
+void pybsleep_set_gpio_wake_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) {
+ pybsleep_wake_cb.timer_wake_cb = cb_obj;
+}
+/******************************************************************************
+ DEFINE PRIVATE FUNCTIONS
+ ******************************************************************************/
+STATIC pybsleep_obj_t *pybsleep_find (mp_obj_t obj) {
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(pybsleep_obj_list).len; i++) {
+ // search for the object and then remove it
+ pybsleep_obj_t *sleep_obj = ((pybsleep_obj_t *)(MP_STATE_PORT(pybsleep_obj_list).items[i]));
+ if (sleep_obj->obj == obj) {
+ return sleep_obj;
}
-
- /* parking the SFLASH IOs */
- HWREG(0x4402E0E8) &= ~(0x3 << 8);
- HWREG(0x4402E0E8) |= (0x2 << 8);
- HWREG(0x4402E0EC) &= ~(0x3 << 8);
- HWREG(0x4402E0EC) |= (0x2 << 8);
- HWREG(0x4402E0F0) &= ~(0x3 << 8);
- HWREG(0x4402E0F0) |= (0x2 << 8);
- HWREG(0x4402E0F4) &= ~(0x3 << 8);
- HWREG(0x4402E0F4) |= (0x1 << 8);
-
- return 0;
+ }
+ return NULL;
}
-
-
-#define INSTR_READ_STATUS 0x05
-#define INSTR_DEEP_POWER_DOWN 0xB9
-#define STATUS_BUSY 0x01
-//****************************************************************************
-//
-//! Put SPI flash into Deep Power Down mode
-//!
-//! Note:SPI flash is a shared resource between MCU and Network processing
-//! units. This routine should only be exercised after all the network
-//! processing has been stopped. To stop network processing use sl_stop API
-//! \param None
-//!
-//! \return Status, 0:Pass, -1:Fail
-//
-//****************************************************************************
-void SpiFlashDeepPowerDown(void) {
+STATIC void pybsleep_flash_powerdown (void) {
uint32_t status;
// Enable clock for SSPI module
- MAP_PRCMPeripheralClkEnable(PRCM_SSPI, PRCM_RUN_MODE_CLK);
+ MAP_PRCMPeripheralClkEnable(PRCM_SSPI, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
// Reset SSPI at PRCM level and wait for reset to complete
MAP_PRCMPeripheralReset(PRCM_SSPI);
- while(!MAP_PRCMPeripheralStatusGet(PRCM_SSPI);
+ while(!MAP_PRCMPeripheralStatusGet(PRCM_SSPI));
// Reset SSPI at module level
MAP_SPIReset(SSPI_BASE);
@@ -247,599 +218,272 @@ void SpiFlashDeepPowerDown(void) {
// Wait for the spi flash
do {
// Send the status register read instruction and read back a dummy byte.
- MAP_SPIDataPut(SSPI_BASE, INSTR_READ_STATUS);
+ MAP_SPIDataPut(SSPI_BASE, SPIFLASH_INSTR_READ_STATUS);
MAP_SPIDataGet(SSPI_BASE, &status);
// Write a dummy byte then read back the actual status.
MAP_SPIDataPut(SSPI_BASE, 0xFF);
MAP_SPIDataGet(SSPI_BASE, &status);
- } while ((status & 0xFF) == STATUS_BUSY);
+ } while ((status & 0xFF) == SPIFLASH_STATUS_BUSY);
// Disable chip select for the spi flash.
MAP_SPICSDisable(SSPI_BASE);
// Start another CS enable sequence for Power down command.
MAP_SPICSEnable(SSPI_BASE);
// Send Deep Power Down command to spi flash
- MAP_SPIDataPut(SSPI_BASE, INSTR_DEEP_POWER_DOWN);
+ MAP_SPIDataPut(SSPI_BASE, SPIFLASH_INSTR_DEEP_POWER_DOWN);
// Disable chip select for the spi flash.
MAP_SPICSDisable(SSPI_BASE);
}
+STATIC NORETURN void pybsleep_suspend_enter (void) {
+ // enable full RAM retention
+ MAP_PRCMSRAMRetentionEnable(PRCM_SRAM_COL_1 | PRCM_SRAM_COL_2 | PRCM_SRAM_COL_3 | PRCM_SRAM_COL_4, PRCM_SRAM_LPDS_RET);
+
+ // save the NVIC control registers
+ nvic_reg_store->vector_table = HWREG(NVIC_VTABLE);
+ nvic_reg_store->aux_ctrl = HWREG(NVIC_ACTLR);
+ nvic_reg_store->int_ctrl_state = HWREG(NVIC_INT_CTRL);
+ nvic_reg_store->app_int = HWREG(NVIC_APINT);
+ nvic_reg_store->sys_ctrl = HWREG(NVIC_SYS_CTRL);
+ nvic_reg_store->config_ctrl = HWREG(NVIC_CFG_CTRL);
+ nvic_reg_store->sys_pri_1 = HWREG(NVIC_SYS_PRI1);
+ nvic_reg_store->sys_pri_2 = HWREG(NVIC_SYS_PRI2);
+ nvic_reg_store->sys_pri_3 = HWREG(NVIC_SYS_PRI3);
+ nvic_reg_store->sys_hcrs = HWREG(NVIC_SYS_HND_CTRL);
+
+ // save the systick registers
+ nvic_reg_store->systick_ctrl = HWREG(NVIC_ST_CTRL);
+ nvic_reg_store->systick_reload = HWREG(NVIC_ST_RELOAD);
+ nvic_reg_store->systick_calib = HWREG(NVIC_ST_CAL);
+
+ // save the interrupt enable registers
+ uint32_t *base_reg_addr = (uint32_t *)NVIC_EN0;
+ for(int32_t i = 0; i < (sizeof(nvic_reg_store->int_en) / 4); i++) {
+ nvic_reg_store->int_en[i] = base_reg_addr[i];
+ }
-#define DBG_PRINT Report
-#define NUM_NVIC_PEND_REG 6
-#define ERR_TIMER_TO_WAKE (-2)
-#define MAX_GPIO_WAKESOURCE 6
-
-struct {
- u32 vector_table; // Vector Table Offset
- u32 aux_ctrl; // Auxiliary control register
- u32 int_ctrl_state; // Interrupt Control and State
- u32 app_int; // Application Interrupt Reset control
- u32 sys_ctrl; // System control
- u32 config_ctrl; // Configuration control
- u32 sys_pri_1; // System Handler Priority 1
- u32 sys_pri_2; // System Handler Priority 2
- u32 sys_pri_3; // System Handler Priority 3
- u32 sys_hcrs; // System Handler control and state register
- u32 systick_ctrl; // SysTick Control Status
- u32 systick_reload; // SysTick Reload
- u32 systick_calib; // SysTick Calibration
- u32 int_en[6]; // Interrupt set enable
- u32 int_priority[49]; // Interrupt priority
-} nvic_reg_store;
-
-u8 gpio_wake_src[] = {2, 4, 13, 17, 11, 24};
-u8 gpio_lpds_inttype[] = {1, 1, 2, 0xFF, 3, 0xFF, 0};
-u8 gpio_hib_inttype[] = {2, 2, 0, 0xFF, 3, 0xFF, 1};
-
-u32 nvic_int_mask[] = {NVIC_PEND0_MASK, NVIC_PEND1_MASK, NVIC_PEND2_MASK,
- NVIC_PEND3_MASK, NVIC_PEND4_MASK, NVIC_PEND5_MASK};
-
-volatile i32 debug = 0;
-
-
-/* Network (Host IRQ) based wakeup from S3(LPDS) */
-static i32 setup_S3_wakeup_from_nw()
-{
-#define IS_NWPIC_INTR_SET() (HWREG(NVIC_EN5) & (1 << ((INT_NWPIC - 16) & 31)))
-
- /* Check if the NWP->APPs interrupt is enabled */
- if(IS_NWPIC_INTR_SET()) {
- /* Set LPDS Wakeup source as NWP request */
- MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_HOST_IRQ);
- return 0;
- } else {
- return -1;
- }
-}
-
-
-
-/* GPIO based wakeup from S3(LPDS) */
-static i32 check_n_setup_S3_wakeup_from_gpio()
-{
- i32 retval, indx;
- u8 gpio_num[MAX_GPIO_WAKESOURCE];
- u8 int_type[MAX_GPIO_WAKESOURCE];
-
- /* Check for any special purpose GPIO usage */
- retval = cc_gpio_get_spl_purpose(&gpio_num[0],
- &int_type[0],
- MAX_GPIO_WAKESOURCE);
-
- if(retval > 0) {
- for(indx = 0; indx < sizeof(gpio_wake_src); indx++) {
- if(gpio_wake_src[indx] == gpio_num[0]) {
- /* Setup the GPIO to be the wake source */
- MAP_PRCMLPDSWakeUpGPIOSelect(
- indx, gpio_lpds_inttype[int_type[0]]);
- MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_GPIO);
- /* Save the GPIO number wake from LPDS */
- cc_pm_ctrl.spl_gpio_wakefrom_lpds = gpio_num[0];
- break;
- }
- }
- } else {
- return -1;
- }
+ // save the interrupt priority registers
+ base_reg_addr = (uint32_t *)NVIC_PRI0;
+ for(int32_t i = 0; i < (sizeof(nvic_reg_store->int_priority) / 4); i++) {
+ nvic_reg_store->int_priority[i] = base_reg_addr[i];
+ }
- return 0;
-}
+ // park the io pins
+ pybsleep_iopark();
+
+ sleep_store();
+
+ // save the restore info and enter LPDS
+ MAP_PRCMLPDSRestoreInfoSet(vault_arm_registers.psp, (uint32_t)sleep_restore);
+ MAP_PRCMLPDSEnter();
+
+ // let the cpu fade away...
+ for ( ; ; );
+}
+
+void pybsleep_suspend_exit (void) {
+ // take the I2C semaphore
+ uint32_t reg = HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register);
+ reg = (reg & ~0x3) | 0x1;
+ HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register) = reg;
+
+ // take the GPIO semaphore
+ reg = HWREG(COMMON_REG_BASE + COMMON_REG_O_GPIO_properties_register);
+ reg = (reg & ~0x3FF) | 0x155;
+ HWREG(COMMON_REG_BASE + COMMON_REG_O_GPIO_properties_register) = reg;
+
+ // restore de NVIC control registers
+ HWREG(NVIC_VTABLE) = nvic_reg_store->vector_table;
+ HWREG(NVIC_ACTLR) = nvic_reg_store->aux_ctrl;
+ HWREG(NVIC_INT_CTRL) = nvic_reg_store->int_ctrl_state;
+ HWREG(NVIC_APINT) = nvic_reg_store->app_int;
+ HWREG(NVIC_SYS_CTRL) = nvic_reg_store->sys_ctrl;
+ HWREG(NVIC_CFG_CTRL) = nvic_reg_store->config_ctrl;
+ HWREG(NVIC_SYS_PRI1) = nvic_reg_store->sys_pri_1;
+ HWREG(NVIC_SYS_PRI2) = nvic_reg_store->sys_pri_2;
+ HWREG(NVIC_SYS_PRI3) = nvic_reg_store->sys_pri_3;
+ HWREG(NVIC_SYS_HND_CTRL) = nvic_reg_store->sys_hcrs;
+
+ // restore the systick register
+ HWREG(NVIC_ST_CTRL) = nvic_reg_store->systick_ctrl;
+ HWREG(NVIC_ST_RELOAD) = nvic_reg_store->systick_reload;
+ HWREG(NVIC_ST_CAL) = nvic_reg_store->systick_calib;
+
+ // restore the interrupt priority registers
+ uint32_t *base_reg_addr = (uint32_t *)NVIC_PRI0;
+ for (uint32_t i = 0; i < (sizeof(nvic_reg_store->int_priority) / 4); i++) {
+ base_reg_addr[i] = nvic_reg_store->int_priority[i];
+ }
-/* Timer based wakeup from S3 (LPDS) */
-static i32 check_n_setup_S3_wakeup_from_timer()
-{
- u64 scc_match, scc_curr, scc_remaining;
-
- /* Check if there is an alarm set */
- if(cc_rtc_has_alarm()) {
- /* Get the time remaining for the RTC timer to expire */
- scc_match = MAP_PRCMSlowClkCtrMatchGet();
- scc_curr = MAP_PRCMSlowClkCtrGet();
-
- if(scc_match > scc_curr) {
- /* Get the time remaining in terms of slow clocks */
- scc_remaining = (scc_match - scc_curr);
- if(scc_remaining > WAKEUP_TIME_LPDS) {
- /* Subtract the time it takes for wakeup
- from S3 (LPDS) */
- scc_remaining -= WAKEUP_TIME_LPDS;
- scc_remaining = (scc_remaining > 0xFFFFFFFF)?
- 0xFFFFFFFF: scc_remaining;
- /* Setup the LPDS wake time */
- MAP_PRCMLPDSIntervalSet(
- (u32)scc_remaining);
- /* Enable the wake source to be timer */
- MAP_PRCMLPDSWakeupSourceEnable(
- PRCM_LPDS_TIMER);
- } else {
- /* Cannot enter LPDS */
- return ERR_TIMER_TO_WAKE;
- }
- } else {
- return ERR_TIMER_TO_WAKE;
- }
- } else {
- /* Disable timer as the wake source */
- MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER);
- return -1;
- }
+ // restore the interrupt enable registers
+ base_reg_addr = (uint32_t *)NVIC_EN0;
+ for(uint32_t i = 0; i < (sizeof(nvic_reg_store->int_en) / 4); i++) {
+ base_reg_addr[i] = nvic_reg_store->int_en[i];
+ }
- return 0;
-}
+ HAL_INTRODUCE_SYNC_BARRIER();
-/* Setup the HIBernate wakr source as apecified GPIO */
-static void setup_hib_gpio_wake(u32 gpio_num,
- u32 gpio_wake_type)
-{
- MAP_PRCMHibernateWakeUpGPIOSelect(gpio_num, gpio_wake_type);
- MAP_PRCMHibernateWakeupSourceEnable(gpio_num);
+ // ungate the clock to the shared spi bus
+ MAP_PRCMPeripheralClkEnable(PRCM_SSPI, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
+ MAP_PRCMIntEnable (PRCM_INT_SLOW_CLK_CTR);
- return;
-}
+ // reinitialize simplelink's bus
+ sl_IfOpen (NULL, 0);
-/* GPIO based wakeup from S4 (HIB) */
-static i32 check_n_setup_S4_wakeup_from_gpio()
-{
- i32 retval, indx;
- u8 gpio_num[MAX_GPIO_WAKESOURCE];
- u8 int_type[MAX_GPIO_WAKESOURCE];
-
- /* Check for any special purpose GPIO usage */
- retval = cc_gpio_get_spl_purpose(&gpio_num[0],
- &int_type[0],
- MAX_GPIO_WAKESOURCE);
-
- if(retval > 0) {
- for(indx = 0; indx < retval; indx++) {
- switch(gpio_num[indx]) {
- case 2:
- setup_hib_gpio_wake(PRCM_HIB_GPIO2,
- gpio_hib_inttype[int_type[indx]]);
- break;
- case 4:
- setup_hib_gpio_wake(PRCM_HIB_GPIO4,
- gpio_hib_inttype[int_type[indx]]);
- break;
- case 13:
- setup_hib_gpio_wake(PRCM_HIB_GPIO13,
- gpio_hib_inttype[int_type[indx]]);
- break;
- case 17:
- setup_hib_gpio_wake(PRCM_HIB_GPIO17,
- gpio_hib_inttype[int_type[indx]]);
-
- break;
- case 11:
- setup_hib_gpio_wake(PRCM_HIB_GPIO11,
- gpio_hib_inttype[int_type[indx]]);
- break;
- case 24:
- setup_hib_gpio_wake(PRCM_HIB_GPIO24,
- gpio_hib_inttype[int_type[indx]]);
- break;
- default:
- break;
- }
- }
- } else {
- return -1;
- }
+ // initialize the system led
+ mperror_init0();
- return 0;
-}
+ // restore the configuration of all active peripherals
+ pybsleep_obj_wakeup();
-/* Timer based wakeup from S4 (HIB) */
-static i32 check_n_setup_S4_wakeup_from_timer()
-{
- u64 scc_match, scc_curr, scc_remaining;
-
- /* Check if there is an alarm set */
- if(cc_rtc_has_alarm()) {
- /* Get the time remaining for the RTC timer to expire */
- scc_match = MAP_PRCMSlowClkCtrMatchGet();
- scc_curr = MAP_PRCMSlowClkCtrGet();
-
- if(scc_match > scc_curr) {
- /* Get the time remaining in terms of slow clocks */
- scc_remaining = (scc_match - scc_curr);
- if(scc_remaining > WAKEUP_TIME_HIB) {
- /* Subtract the time it takes for wakeup
- from S4 (HIB) */
- scc_remaining -= WAKEUP_TIME_HIB;
- /* Setup the HIB wake time */
- MAP_PRCMHibernateIntervalSet(scc_remaining);
- /* Enable the wake source to be RTC */
- MAP_PRCMHibernateWakeupSourceEnable(
- PRCM_HIB_SLOW_CLK_CTR);
- } else {
- /* Cannot enter HIB */
- return ERR_TIMER_TO_WAKE;
- }
- } else {
- return -1;
- }
- } else {
- /* Disable Timer as wake source */
- MAP_PRCMHibernateWakeupSourceDisable(PRCM_HIB_SLOW_CLK_CTR);
- return -1;
- }
+ // trigger a sw interrupt
+ MAP_IntPendSet(INT_PRCM);
- return 0;
+ // force an exception to go back to the point where suspend mode was entered
+ nlr_raise(mp_obj_new_exception(&mp_type_SystemExit));
}
-/* Sets up wake-up sources for indicated power mode */
-i32 cc_set_up_wkup_srcs(enum soc_pm target)
-{
- i32 nw_ret = -1, gpio_ret = -1, timer_ret = -1;
- switch(target) {
- case e_pm_S0:
- case e_pm_S1:
- case e_pm_S2:
- /* These handle the cases of run, sleep, deepsleep.
- Wake source is configured outside this scope in
- individual peripherals */
- break;
- case e_pm_S3:
- /* Low power deep sleep condition */
- /* Network (Host IRQ) based wakeup is always enabled */
- nw_ret = setup_S3_wakeup_from_nw();
- /* Check and enable GPIO based wakeup */
- gpio_ret = check_n_setup_S3_wakeup_from_gpio();
- /* Check and enable LRT based wakeup */
- timer_ret = check_n_setup_S3_wakeup_from_timer();
- break;
- case e_pm_S4:
- /* Hibernate condition */
- /* Check and enable GPIO based wakeup */
- gpio_ret = check_n_setup_S4_wakeup_from_gpio();
- /* Check and enable LRT based wakeup */
- timer_ret = check_n_setup_S4_wakeup_from_timer();
- break;
- default:
- break;
- }
-
- if(ERR_TIMER_TO_WAKE == timer_ret) {
- return -1;
+STATIC void PRCMInterruptHandler (void) {
+ // reading the interrupt status automatically clears the interrupt
+ if (PRCM_INT_SLOW_CLK_CTR == MAP_PRCMIntStatus()) {
+ if (pybsleep_wake_cb.timer_wake_cb) {
+ mpcallback_handler(pybsleep_wake_cb.timer_wake_cb);
}
- if((nw_ret < 0) && (gpio_ret < 0) && (timer_ret < 0)) {
- return -1;
- }
- else if((gpio_ret < 0) && (timer_ret < 0)) {
- /* Setup the LPDS wake time */
- MAP_PRCMLPDSIntervalSet(LPDS_WDOG_TIME);
- /* Enable the wake source to be timer */
- MAP_PRCMLPDSWakeupSourceEnable(
- PRCM_LPDS_TIMER);
- }
- return 0;
-}
-
-/* LPDS wake SW interrupt handler */
-void wake_interrupt_handler()
-{
- i32 wake_source;
-
- /* Identify the wakeup source */
- wake_source = MAP_PRCMLPDSWakeupCauseGet();
-
- switch(wake_source) {
+ }
+ else {
+ switch (MAP_PRCMLPDSWakeupCauseGet()) {
case PRCM_LPDS_HOST_IRQ:
- break;
+ if (pybsleep_wake_cb.wlan_wake_cb) {
+ mpcallback_handler(pybsleep_wake_cb.wlan_wake_cb);
+ }
+ break;
case PRCM_LPDS_GPIO:
- /* Invoke the callback with the last GPIO num
- used to enter LPDS (S3) */
- gpio_wake_interrupt_handler(
- &cc_pm_ctrl.spl_gpio_wakefrom_lpds);
- break;
+ if (pybsleep_wake_cb.gpio_wake_cb) {
+ mpcallback_handler(pybsleep_wake_cb.gpio_wake_cb);
+ }
+ break;
case PRCM_LPDS_TIMER:
- break;
- }
-
- return;
-}
-
-/* Process events that have woken up system from S3 (LPDS) */
-i32 cc_handle_S3_wakeup()
-{
- /* Trigger the SW interrupt */
- MAP_IntPendSet(INT_PRCM);
- return 0;
-}
-
-/* Are there interrupts pending in system? TRUE -> yes else no */
-bool cc_are_irqs_pending(void)
-{
- i32 indx = 0;
- u32 *base_reg_addr;
-
- /* Check if there are any interrupts pending */
- base_reg_addr = (u32 *)NVIC_PEND0;
- for(indx = 0; indx < NUM_NVIC_PEND_REG; indx++) {
- if(base_reg_addr[indx] & nvic_int_mask[indx]) {
- return true;
- }
+ if (pybsleep_wake_cb.timer_wake_cb) {
+ mpcallback_handler(pybsleep_wake_cb.timer_wake_cb);
+ }
+ break;
+ default:
+ break;
}
-
- return false;
-}
-
-/* Must push system to low power state of S4 (Hibernate) */
-i32 cc_enter_S4(void)
-{
- /* Invoke the driverlib API to enter HIBernate */
- MAP_PRCMHibernateEnter();
-
- return 0;
-}
-
-/* Must push system to low power state of S3 (LPDS) */
-i32 cc_enter_S3(void(*resume_fn)(void), u32 stack_ptr)
-{
- MAP_PRCMLPDSRestoreInfoSet(stack_ptr, (u32)resume_fn);
-
- /* Enter LPDS */
- MAP_PRCMLPDSEnter();
- return 0;
-}
-
-/* Must push system to low power state of S2 (Deepsleep) */
-i32 cc_enter_S2(void)
-{
- /* Enter deepsleep */
- //MAP_PRCMDeepSleepEnter();
-
- return 0;
-}
-volatile i32 sleep_count = 0;
-/* Must push system to low power state of S1 */
-i32 cc_enter_S1(void)
-{
- //MAP_PRCMSleepEnter();
- return 0;
-}
-
-/* Save the NVIC registers */
-void back_up_nvic_regs()
-{
- i32 indx = 0;
- u32 *base_reg_addr;
- /* Save the NVIC control registers */
- nvic_reg_store.vector_table = HWREG(NVIC_VTABLE);
- nvic_reg_store.aux_ctrl = HWREG(NVIC_ACTLR);
- nvic_reg_store.int_ctrl_state = HWREG(NVIC_INT_CTRL);
- nvic_reg_store.app_int = HWREG(NVIC_APINT);
- nvic_reg_store.sys_ctrl = HWREG(NVIC_SYS_CTRL);
- nvic_reg_store.config_ctrl = HWREG(NVIC_CFG_CTRL);
- nvic_reg_store.sys_pri_1 = HWREG(NVIC_SYS_PRI1);
- nvic_reg_store.sys_pri_2 = HWREG(NVIC_SYS_PRI2);
- nvic_reg_store.sys_pri_3 = HWREG(NVIC_SYS_PRI3);
- nvic_reg_store.sys_hcrs = HWREG(NVIC_SYS_HND_CTRL);
-
- /* Systick registers */
- nvic_reg_store.systick_ctrl = HWREG(NVIC_ST_CTRL);
- nvic_reg_store.systick_reload = HWREG(NVIC_ST_RELOAD);
- nvic_reg_store.systick_calib = HWREG(NVIC_ST_CAL);
-
- /* Save the interrupt enable registers */
- base_reg_addr = (u32 *)NVIC_EN0;
- for(indx = 0; indx < (sizeof(nvic_reg_store.int_en) / 4); indx++) {
- nvic_reg_store.int_en[indx] = base_reg_addr[indx];
- }
-
- /* Save the interrupt priority registers */
- base_reg_addr = (u32 *)NVIC_PRI0;
- for(indx = 0; indx < (sizeof(nvic_reg_store.int_priority) / 4); indx++) {
- nvic_reg_store.int_priority[indx] = base_reg_addr[indx];
- }
-
- return;
-}
-
-/* Reestore the NVIC registers */
-void restore_nvic_regs()
-{
- i32 indx = 0;
- u32 *base_reg_addr;
-
- /* Restore the NVIC control registers */
- HWREG(NVIC_VTABLE) = nvic_reg_store.vector_table;
- HWREG(NVIC_ACTLR) = nvic_reg_store.aux_ctrl;
- HWREG(NVIC_APINT) = nvic_reg_store.app_int;
- HWREG(NVIC_SYS_CTRL) = nvic_reg_store.sys_ctrl;
- HWREG(NVIC_CFG_CTRL) = nvic_reg_store.config_ctrl;
- HWREG(NVIC_SYS_PRI1) = nvic_reg_store.sys_pri_1;
- HWREG(NVIC_SYS_PRI2) = nvic_reg_store.sys_pri_2;
- HWREG(NVIC_SYS_PRI3) = nvic_reg_store.sys_pri_3;
- HWREG(NVIC_SYS_HND_CTRL) = nvic_reg_store.sys_hcrs;
-
- /* Systick registers */
- HWREG(NVIC_ST_CTRL) = nvic_reg_store.systick_ctrl;
- HWREG(NVIC_ST_RELOAD) = nvic_reg_store.systick_reload;
- HWREG(NVIC_ST_CAL) = nvic_reg_store.systick_calib;
-
- /* Restore the interrupt priority registers */
- base_reg_addr = (u32 *)NVIC_PRI0;
- for(indx = 0; indx < (sizeof(nvic_reg_store.int_priority) / 4); indx++) {
- base_reg_addr[indx] = nvic_reg_store.int_priority[indx];
- }
-
- /* Restore the interrupt enable registers */
- base_reg_addr = (u32 *)NVIC_EN0;
- for(indx = 0; indx < (sizeof(nvic_reg_store.int_en) / 4); indx++) {
- base_reg_addr[indx] = nvic_reg_store.int_en[indx];
- }
-
- INTRODUCE_SYNC_BARRIER(); /* Data and instruction sync barriers */
-
- return;
-}
-
-/* S3 (LPDS): Back-up system regs & data */
-void cc_back_up_soc_data(void) {
- /* Enable the RAM retention */
- MAP_PRCMSRAMRetentionEnable(PRCM_SRAM_COL_1 | PRCM_SRAM_COL_2 | PRCM_SRAM_COL_3 | PRCM_SRAM_COL_4, PRCM_SRAM_LPDS_RET);
- /* Store the NVIC registers */
- back_up_nvic_regs();
-
- // Park all IO pins
-
- // Park antenna selection pins
- HWREG(0x4402E108) = 0x00000E61;
- HWREG(0x4402E10C) = 0x00000E61;
-
- INTRODUCE_SYNC_BARRIER(); /* Data and instruction sync barriers */
-
- BACK_UP_ARM_REGISTERS(); /* Core registers and code is in assembly */
-
- return;
-}
-
-/* S3 (LPDS): Restore system regs & data */
-void cc_restore_soc_data(void)
-{
- uint32_t reg;
- /* Check if any of the registers/data need to be restored */
- /* Take I2C semaphore */
- reg = HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register);
- reg = (reg & ~0x3) | 0x1;
- HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register) = reg;
-
- /* Take GPIO semaphore */
- reg = HWREG(COMMON_REG_BASE + COMMON_REG_O_GPIO_properties_register);
- reg = (reg & ~0x3FF) | 0x155;
- HWREG(COMMON_REG_BASE + COMMON_REG_O_GPIO_properties_register) = reg;
-
- /* Restore the NVIC registers */
- restore_nvic_regs();
-
- /* ungates the clk for the shared SPI*/
- MAP_PRCMPeripheralClkEnable(PRCM_SSPI, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
- MAP_PRCMIntEnable (PRCM_INT_SLOW_CLK_CTR);
-
- return;
+ }
}
-
-void prcm_interrupt_handler(void *intr_param)
-{
- int status;
-
- /* Read the interrupt status, also clears the status */
- status = MAP_PRCMIntStatus();
-
- if((PRCM_INT_SLOW_CLK_CTR == status) || (sw_simulate_rtc)) {
- sw_simulate_rtc = 0;
- /* Invoke the RTC interrupt handler */
- cc_rtc_isr();
- } else if(0 == status) {
- /* Invoke the wake from LPDS interrupt handler */
- wake_interrupt_handler();
- } else {
- }
+STATIC void pybsleep_obj_wakeup (void) {
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(pybsleep_obj_list).len; i++) {
+ pybsleep_obj_t *sleep_obj = ((pybsleep_obj_t *)MP_STATE_PORT(pybsleep_obj_list).items[i]);
+ sleep_obj->wakeup(sleep_obj->obj);
+ }
}
-/* LPDS wake SW interrupt handler */
-void wake_interrupt_handler()
-{
- i32 wake_source;
-
- /* Identify the wakeup source */
- wake_source = MAP_PRCMLPDSWakeupCauseGet();
-
- switch(wake_source) {
- case PRCM_LPDS_HOST_IRQ:
- break;
- case PRCM_LPDS_GPIO:
- /* Invoke the callback with the last GPIO num
- used to enter LPDS (S3) */
- gpio_wake_interrupt_handler(
- &cc_pm_ctrl.spl_gpio_wakefrom_lpds);
- break;
- case PRCM_LPDS_TIMER:
- break;
+STATIC void pybsleep_iopark (void) {
+ mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_cpu_pins_locals_dict);
+ for (uint i = 0; i < named_map->used; i++) {
+ pin_obj_t * pin = (pin_obj_t *)named_map->table[i].value;
+ // skip the sflash pins since these are shared with the network processor
+ switch (pin->pin_num) {
+ case PIN_11:
+ case PIN_12:
+ case PIN_13:
+ case PIN_14:
+#ifdef DEBUG
+ // also skip the JTAG pins
+ case PIN_16:
+ case PIN_17:
+ case PIN_19:
+ case PIN_20:
+#endif
+ break;
+ default:
+ if (!pin->used) {
+ // enable the pull-down in unused pins
+ MAP_PinConfigSet(pin->pin_num, pin->strength, PIN_TYPE_STD_PD);
+ }
+ // make the pin an input
+ MAP_PinDirModeSet(pin->pin_num, PIN_DIR_MODE_IN);
+ break;
}
+ }
- return;
-}
-
-/* Invoked in interrupt context */
-void cc_rtc_isr(void) {
- struct u64_time alarm, value;
- u32 status;
-
- /* Read the interrupt status, also clears the status */
- status = MAP_PRCMIntStatus();
+ // park the sflash pins
+ HWREG(0x4402E0E8) &= ~(0x3 << 8);
+ HWREG(0x4402E0E8) |= (0x2 << 8);
+ HWREG(0x4402E0EC) &= ~(0x3 << 8);
+ HWREG(0x4402E0EC) |= (0x2 << 8);
+ HWREG(0x4402E0F0) &= ~(0x3 << 8);
+ HWREG(0x4402E0F0) |= (0x2 << 8);
+ HWREG(0x4402E0F4) &= ~(0x3 << 8);
+ HWREG(0x4402E0F4) |= (0x1 << 8);
+
+ // park the antenna selection pins
+ HWREG(0x4402E108) = 0x00000E61;
+ HWREG(0x4402E10C) = 0x00000E61;
+}
+
+/******************************************************************************/
+// Micro Python bindings; Sleep class
+
+/// \function idle()
+/// Gates the processor clock until an interrupt is triggered
+STATIC mp_obj_t pyb_sleep_idle (mp_obj_t self_in) {
+ __WFI();
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_idle_obj, pyb_sleep_idle);
+
+/// \function suspend()
+/// Enters suspended mode. Wake up sources should have been enable prior to
+// calling this method.
+STATIC mp_obj_t pyb_sleep_suspend (mp_obj_t self_in) {
+ nlr_buf_t nlr;
+
+ // entering and exiting suspend mode must be an atomic operation
+ // therefore interrupts must be disabled
+ uint primsk = disable_irq();
+ if (nlr_push(&nlr) == 0) {
+ pybsleep_suspend_enter();
+ nlr_pop();
+ }
+ // an exception is always raised when exiting suspend mode
+ enable_irq(primsk);
- // call the python RTC callback interrupt handler
+ return mp_const_none;
}
-#endif
-
-
-typedef struct {
- mp_obj_t obj;
- WakeUpCB_t wakeup;
-}pybsleep_obj_t;
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_suspend_obj, pyb_sleep_suspend);
-
-STATIC pybsleep_obj_t * pybsleep_find (mp_obj_t obj) {
- for (mp_uint_t i = 0; i < MP_STATE_PORT(pybsleep_obj_list).len; i++) {
- // search for the object and then remove it
- pybsleep_obj_t *sleep_obj = ((pybsleep_obj_t *)MP_STATE_PORT(pybsleep_obj_list).items[i]);
- if (sleep_obj->obj == obj) {
- return sleep_obj;
- }
- }
- return NULL;
+/// \function hibernate()
+/// Enters hibernate mode. Wake up sources should have been enable prior to
+// calling this method.
+STATIC mp_obj_t pyb_sleep_hibernate (mp_obj_t self_in) {
+ wlan_stop();
+ pybsleep_flash_powerdown();
+ MAP_PRCMHibernateEnter();
+ return mp_const_none;
}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_hibernate_obj, pyb_sleep_hibernate);
-void pyblsleep_init0 (void) {
- mp_obj_list_init(&MP_STATE_PORT(pybsleep_obj_list), 0);
-}
+STATIC const mp_map_elem_t pybsleep_locals_dict_table[] = {
+ // instance methods
+ { MP_OBJ_NEW_QSTR(MP_QSTR_idle), (mp_obj_t)&pyb_sleep_idle_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_suspend), (mp_obj_t)&pyb_sleep_suspend_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_hibernate), (mp_obj_t)&pyb_sleep_hibernate_obj },
-void pybsleep_add (mp_obj_t obj, WakeUpCB_t wakeup) {
- pybsleep_obj_t * sleep_obj = m_new_obj(pybsleep_obj_t);
- sleep_obj->obj = obj;
- sleep_obj->wakeup = wakeup;
- // only add objects once
- if (!pybsleep_find(sleep_obj)) {
- mp_obj_list_append(&MP_STATE_PORT(pybsleep_obj_list), sleep_obj);
- }
-}
+ // class constants
+ { 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) },
+};
-void pybsleep_remove (mp_obj_t obj) {
- pybsleep_obj_t *sleep_obj;
- if ((sleep_obj = pybsleep_find(obj))) {
- mp_obj_list_remove(&MP_STATE_PORT(pybsleep_obj_list), sleep_obj);
- }
-}
+STATIC MP_DEFINE_CONST_DICT(pybsleep_locals_dict, pybsleep_locals_dict_table);
-void pybsleep_wakeup (void) {
- for (mp_uint_t i = 0; i < MP_STATE_PORT(pybsleep_obj_list).len; i++) {
- pybsleep_obj_t *sleep_obj = ((pybsleep_obj_t *)MP_STATE_PORT(pybsleep_obj_list).items[i]);
- sleep_obj->wakeup(sleep_obj->obj);
- }
-}
+STATIC const mp_obj_type_t pybsleep_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_sleep,
+ .locals_dict = (mp_obj_t)&pybsleep_locals_dict,
+};
+const mp_obj_base_t pyb_sleep_obj = {&pybsleep_type};
diff --git a/cc3200/mods/pybsleep.h b/cc3200/mods/pybsleep.h
index d91437ffa2..97997080d8 100644
--- a/cc3200/mods/pybsleep.h
+++ b/cc3200/mods/pybsleep.h
@@ -27,11 +27,31 @@
#ifndef PYBSLEEP_H_
#define PYBSLEEP_H_
-typedef void (*WakeUpCB_t)(mp_obj_t self);
+/******************************************************************************
+ DEFINE CONSTANTS
+ ******************************************************************************/
+#define PYB_PWR_MODE_ACTIVE_IDLE (0x00)
+#define PYB_PWR_MODE_LPDS (0x01)
+#define PYB_PWR_MODE_HIBERNATE (0x02)
+/******************************************************************************
+ DEFINE TYPES
+ ******************************************************************************/
+typedef void (*WakeUpCB_t)(const mp_obj_t self);
+
+/******************************************************************************
+ DECLARE EXPORTED VARIABLES
+ ******************************************************************************/
+extern const mp_obj_base_t pyb_sleep_obj;
+
+/******************************************************************************
+ DECLARE FUNCTIONS
+ ******************************************************************************/
void pyblsleep_init0 (void);
-void pybsleep_add (mp_obj_t obj, WakeUpCB_t wakeup);
-void pybsleep_remove (mp_obj_t obj);
-void pybsleep_wakeup (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);
#endif /* PYBSLEEP_H_ */
diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c
index 8d054bb088..ccaf3a31e0 100644
--- a/cc3200/mods/pybuart.c
+++ b/cc3200/mods/pybuart.c
@@ -93,6 +93,8 @@
/******************************************************************************
DECLARE PRIVATE FUNCTIONS
******************************************************************************/
+STATIC void uart_init (pyb_uart_obj_t *self);
+STATIC bool uart_rx_wait (pyb_uart_obj_t *self, uint32_t timeout);
STATIC pyb_uart_obj_t* pyb_uart_add (pyb_uart_id_t uart_id);
STATIC pyb_uart_obj_t* pyb_uart_find (pyb_uart_id_t uart_id);
STATIC void UARTGenericIntHandler(uint32_t uart_id);
@@ -137,8 +139,57 @@ void uart_deinit(void) {
}
}
+bool uart_rx_any(pyb_uart_obj_t *self) {
+ return (self->read_buf_tail != self->read_buf_head || MAP_UARTCharsAvail(self->reg));
+}
+
+int uart_rx_char(pyb_uart_obj_t *self) {
+ if (self->read_buf_tail != self->read_buf_head) {
+ // buffering via IRQ
+ int data = self->read_buf[self->read_buf_tail];
+ self->read_buf_tail = (self->read_buf_tail + 1) % self->read_buf_len;
+ return data;
+ } else {
+ // no buffering
+ return MAP_UARTCharGetNonBlocking(self->reg);
+ }
+}
+
+bool uart_tx_char(pyb_uart_obj_t *self, int c) {
+ uint32_t timeout = 0;
+
+ while (!MAP_UARTCharPutNonBlocking(self->reg, c)) {
+ if (timeout++ > (PYBUART_TX_MAX_TIMEOUT_MS / PYBUART_TX_WAIT_MS)) {
+ return false;
+ }
+ HAL_Delay (PYBUART_TX_WAIT_MS);
+ }
+ return true;
+}
+
+bool uart_tx_strn(pyb_uart_obj_t *self, const char *str, uint len) {
+ for (const char *top = str + len; str < top; str++) {
+ if (!uart_tx_char(self, *str)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void uart_tx_strn_cooked(pyb_uart_obj_t *self, const char *str, uint len) {
+ for (const char *top = str + len; str < top; str++) {
+ if (*str == '\n') {
+ uart_tx_char(self, '\r');
+ }
+ uart_tx_char(self, *str);
+ }
+}
+
+/******************************************************************************
+ DEFINE PRIVATE FUNCTIONS
+ ******************************************************************************/
// assumes init parameters have been set up correctly
-bool uart_init2(pyb_uart_obj_t *self) {
+STATIC void uart_init (pyb_uart_obj_t *self) {
uint uartPerh;
switch (self->uart_id) {
@@ -155,7 +206,7 @@ bool uart_init2(pyb_uart_obj_t *self) {
MAP_IntPrioritySet(INT_UARTA1, INT_PRIORITY_LVL_3);
break;
default:
- return false;
+ return;
}
// Enable the peripheral clock
@@ -173,35 +224,23 @@ bool uart_init2(pyb_uart_obj_t *self) {
// Configure the FIFO interrupt levels
MAP_UARTFIFOLevelSet(self->reg, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
-
+
// Configure the flow control mode
UARTFlowControlSet(self->reg, self->flowcontrol);
- // Enable the RX and RX timeout interrupts
- MAP_UARTIntEnable(self->reg, UART_INT_RX | UART_INT_RT);
-
- self->enabled = true;
-
- // register it with the sleep module
- pybsleep_add (self, (WakeUpCB_t)uart_init2);
- return true;
-}
-
-bool uart_init(pyb_uart_obj_t *self, uint baudrate) {
- self->baudrate = baudrate;
- self->config = UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE;
- self->flowcontrol = UART_FLOWCONTROL_NONE;
- return uart_init2(self);
-}
-
-bool uart_rx_any(pyb_uart_obj_t *self) {
- return (self->read_buf_tail != self->read_buf_head || MAP_UARTCharsAvail(self->reg));
+ // Setup the RX interrupts
+ if (self->read_buf != NULL) {
+ MAP_UARTIntEnable(self->reg, UART_INT_RX | UART_INT_RT);
+ }
+ else {
+ MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT);
+ }
}
// Waits at most timeout milliseconds for at least 1 char to become ready for
// reading (from buf or for direct reading).
// Returns true if something available, false if not.
-STATIC bool uart_rx_wait(pyb_uart_obj_t *self, uint32_t timeout) {
+STATIC bool uart_rx_wait (pyb_uart_obj_t *self, uint32_t timeout) {
for (;;) {
if (uart_rx_any(self)) {
return true; // have at least 1 char ready for reading
@@ -216,51 +255,6 @@ STATIC bool uart_rx_wait(pyb_uart_obj_t *self, uint32_t timeout) {
}
}
-int uart_rx_char(pyb_uart_obj_t *self) {
- if (self->read_buf_tail != self->read_buf_head) {
- // buffering via IRQ
- int data = self->read_buf[self->read_buf_tail];
- self->read_buf_tail = (self->read_buf_tail + 1) % self->read_buf_len;
- return data;
- } else {
- // no buffering
- return MAP_UARTCharGetNonBlocking(self->reg);
- }
-}
-
-bool uart_tx_char(pyb_uart_obj_t *self, int c) {
- uint32_t timeout = 0;
-
- while (!MAP_UARTCharPutNonBlocking(self->reg, c)) {
- if (timeout++ > (PYBUART_TX_MAX_TIMEOUT_MS / PYBUART_TX_WAIT_MS)) {
- return false;
- }
- HAL_Delay (PYBUART_TX_WAIT_MS);
- }
- return true;
-}
-
-bool uart_tx_strn(pyb_uart_obj_t *self, const char *str, uint len) {
- for (const char *top = str + len; str < top; str++) {
- if (!uart_tx_char(self, *str)) {
- return false;
- }
- }
- return true;
-}
-
-void uart_tx_strn_cooked(pyb_uart_obj_t *self, const char *str, uint len) {
- for (const char *top = str + len; str < top; str++) {
- if (*str == '\n') {
- uart_tx_char(self, '\r');
- }
- uart_tx_char(self, *str);
- }
-}
-
-/******************************************************************************
- DEFINE PRIVATE FUNCTIONS
- ******************************************************************************/
STATIC pyb_uart_obj_t* pyb_uart_add (pyb_uart_id_t uart_id) {
// create a new uart object
pyb_uart_obj_t *self = m_new_obj(pyb_uart_obj_t);
@@ -327,7 +321,7 @@ STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void
if (!self->enabled) {
print(env, "<UART%u>", self->uart_id);
} else {
- print(env, "<UART%u baudrate=%u, bits=", self->uart_id, self->baudrate);
+ print(env, "<UART%u, baudrate=%u, bits=", self->uart_id, self->baudrate);
switch (self->config & UART_CONFIG_WLEN_MASK) {
case UART_CONFIG_WLEN_5:
print(env, "5");
@@ -380,15 +374,35 @@ STATIC const mp_arg_t pyb_uart_init_args[] = {
};
STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- bool success;
-
// parse args
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_uart_init_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(pyb_uart_init_args), pyb_uart_init_args, args);
+ // set timeouts
+ self->timeout = args[5].u_int;
+ self->timeout_char = args[6].u_int;
+
+ // setup the read buffer
+ m_del(byte, self->read_buf, self->read_buf_len);
+ self->read_buf_head = 0;
+ self->read_buf_tail = 0;
+
+ if (args[7].u_int <= 0) {
+ // no read buffer
+ self->read_buf_len = 0;
+ self->read_buf = NULL;
+ }
+ else {
+ // read buffer using interrupts
+ self->read_buf_len = args[7].u_int;
+ self->read_buf = m_new(byte, args[7].u_int);
+ }
+
+ // get the baudrate
+ self->baudrate = args[0].u_int;
+
// set the UART configuration values
if (n_args > 1) {
- self->baudrate = args[0].u_int;
switch (args[1].u_int) {
case 5:
self->config = UART_CONFIG_WLEN_5;
@@ -417,36 +431,17 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
// Flow control
self->flowcontrol = args[4].u_int;
- success = uart_init2(self);
- } else {
- success = uart_init(self, args[0].u_int);
}
-
- // init UART (if it fails, something weird happened)
- if (!success) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ else {
+ self->config = UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE;
+ self->flowcontrol = UART_FLOWCONTROL_NONE;
}
+ // initialize and enable the uart
+ uart_init (self);
+ self->enabled = true;
+ // register it with the sleep module
+ pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)uart_init);
- // set timeouts
- self->timeout = args[5].u_int;
- self->timeout_char = args[6].u_int;
-
- // setup the read buffer
- m_del(byte, self->read_buf, self->read_buf_len);
- self->read_buf_head = 0;
- self->read_buf_tail = 0;
-
- if (args[7].u_int <= 0) {
- // no read buffer
- self->read_buf_len = 0;
- self->read_buf = NULL;
- MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT);
- } else {
- // read buffer using interrupts
- self->read_buf_len = args[7].u_int;
- self->read_buf = m_new(byte, args[7].u_int);
- }
-
return mp_const_none;
}
diff --git a/cc3200/mods/pybuart.h b/cc3200/mods/pybuart.h
index e648225843..e628b2903b 100644
--- a/cc3200/mods/pybuart.h
+++ b/cc3200/mods/pybuart.h
@@ -36,7 +36,6 @@ typedef struct _pyb_uart_obj_t pyb_uart_obj_t;
extern const mp_obj_type_t pyb_uart_type;
void uart_init0(void);
-bool uart_init(pyb_uart_obj_t *uart_obj, uint baudrate);
void uart_deinit (void);
bool uart_rx_any(pyb_uart_obj_t *uart_obj);
int uart_rx_char(pyb_uart_obj_t *uart_obj);
diff --git a/cc3200/mods/pybwdt.c b/cc3200/mods/pybwdt.c
index 97d284d066..68213de6e6 100644
--- a/cc3200/mods/pybwdt.c
+++ b/cc3200/mods/pybwdt.c
@@ -47,7 +47,7 @@
DECLARE CONSTANTS
******************************************************************************/
#define PYBWDT_MILLISECONDS_TO_TICKS(ms) ((80000000 / 1000) * (ms))
-#define PYBWDT_MIN_TIMEOUT_MS (500)
+#define PYBWDT_MIN_TIMEOUT_MS (1000)
/******************************************************************************
DECLARE TYPES
diff --git a/cc3200/mpconfigport.h b/cc3200/mpconfigport.h
index 344e8249c9..52bbf530dd 100644
--- a/cc3200/mpconfigport.h
+++ b/cc3200/mpconfigport.h
@@ -123,6 +123,7 @@ extern const struct _mp_obj_module_t mp_module_network;
mp_obj_list_t pyb_uart_list; \
mp_obj_list_t mod_network_nic_list; \
mp_obj_list_t pybsleep_obj_list; \
+ mp_obj_list_t mpcallback_obj_list; \
// type definitions for the specific machine
diff --git a/cc3200/mptask.c b/cc3200/mptask.c
index 3e51199fb2..6f0a3a0540 100644
--- a/cc3200/mptask.c
+++ b/cc3200/mptask.c
@@ -59,6 +59,7 @@
#include "pybsd.h"
#include "pins.h"
#include "pybsleep.h"
+#include "mpcallback.h"
/******************************************************************************
DECLARE PRIVATE CONSTANTS
@@ -118,11 +119,19 @@ soft_reset:
mp_obj_list_init(mp_sys_argv, 0);
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
+ // execute all basic initializations
mperror_init0();
mpexception_init0();
+ mpcallback_init0();
pyblsleep_init0();
uart_init0();
pin_init0();
+ readline_init0();
+ mod_network_init0();
+ wlan_init0();
+#if MICROPY_HW_ENABLE_RNG
+ rng_init0();
+#endif
// configure stdio uart pins with the correct af
// param 3 ("mode") is DON'T CARE" for AFs others than GPIO
@@ -135,13 +144,6 @@ soft_reset:
};
pyb_stdio_uart = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args);
- readline_init0();
- mod_network_init0();
- wlan_init0();
-#if MICROPY_HW_ENABLE_RNG
- rng_init0();
-#endif
-
mperror_enable_heartbeat();
mptask_enter_ap_mode();
@@ -328,7 +330,6 @@ STATIC void mptask_enter_ap_mode (void) {
// Enable simplelink in low power mode
wlan_sl_enable (ROLE_AP, SERVERS_DEF_AP_SSID, strlen(SERVERS_DEF_AP_SSID), SERVERS_DEF_AP_SECURITY,
SERVERS_DEF_AP_KEY, strlen(SERVERS_DEF_AP_KEY), SERVERS_DEF_AP_CHANNEL);
- wlan_set_pm_policy (SL_NORMAL_POLICY);
}
STATIC void mptask_create_main_py (void) {
diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h
index 1ae4b0b172..3c6c2b253c 100644
--- a/cc3200/qstrdefsport.h
+++ b/cc3200/qstrdefsport.h
@@ -3,9 +3,7 @@ Q(__name__)
Q(help)
Q(pyb)
Q(info)
-Q(hard_reset)
-Q(stop)
-Q(standby)
+Q(reset)
Q(main)
Q(sync)
Q(gc)
@@ -22,10 +20,8 @@ Q(readall)
Q(readline)
Q(input)
Q(os)
-Q(mac)
Q(freq)
Q(repl_info)
-Q(wfi)
Q(disable_irq)
Q(enable_irq)
Q(millis)
@@ -85,7 +81,6 @@ Q(pull)
Q(index)
Q(strength)
Q(af)
-Q(callback)
Q(intenable)
Q(intdisable)
Q(intmode)
@@ -220,7 +215,6 @@ Q(getmode)
Q(channel)
Q(ifconfig)
Q(urn)
-Q(setpm)
Q(start_servers)
Q(stop_servers)
Q(servers_enabled)
@@ -234,11 +228,6 @@ Q(WPA_WPA2)
Q(WPA_ENT)
Q(WPS_PBC)
Q(WPS_PIN)
-Q(NORMAL_PM)
-Q(LOW_LATENCY_PM)
-Q(LOW_POWER_PM)
-Q(ALWAYS_ON_PM)
-Q(LONG_SLEEP_PM)
// for WDT class
Q(WDT)
@@ -247,3 +236,21 @@ Q(kick)
// for HeartBeat class
Q(HeartBeat)
+// for callback class
+Q(init)
+Q(enable)
+Q(disable)
+Q(callback)
+Q(handler)
+Q(intmode)
+Q(value)
+Q(priority)
+Q(wake)
+
+// for Sleep class
+Q(Sleep)
+Q(idle)
+Q(suspend)
+Q(hibernate)
+Q(SUSPENDED)
+Q(HIBERNATING)
diff --git a/cc3200/simplelink/oslib/osi.h b/cc3200/simplelink/oslib/osi.h
index cf2574b1ec..11fe61bb63 100644
--- a/cc3200/simplelink/oslib/osi.h
+++ b/cc3200/simplelink/oslib/osi.h
@@ -538,26 +538,26 @@ void osi_Sleep(unsigned int MilliSecs);
/*!
\brief This function used to disable the tasks
\param - void
- \return - Key with the suspended tasks
+ \return - void
\note
\warning
*/
-unsigned long osi_TaskDisable(void);
+void osi_TaskDisable(void);
/*!
\brief This function used to enable all tasks
- \param unsigned long
+ \param - void
\return - void
\note
\warning
*/
-void osi_TaskEnable(unsigned long);
+void osi_TaskEnable(void);
+
/*!
\brief structure definition for simple link spawn message
\note On each porting or platform the type could be whatever is needed - integer, pointer to structure etc.
*/
-
typedef struct
{
P_OSI_SPAWN_ENTRY pEntry;
diff --git a/cc3200/simplelink/oslib/osi_freertos.c b/cc3200/simplelink/oslib/osi_freertos.c
index 2f00ab2689..196672de70 100644
--- a/cc3200/simplelink/oslib/osi_freertos.c
+++ b/cc3200/simplelink/oslib/osi_freertos.c
@@ -693,11 +693,9 @@ void osi_Sleep(unsigned int MilliSecs)
\note
\warning
*/
-unsigned long osi_TaskDisable(void)
+void osi_TaskDisable(void)
{
vTaskSuspendAll();
-
- return OSI_OK;
}
@@ -708,7 +706,7 @@ unsigned long osi_TaskDisable(void)
\note
\warning
*/
-void osi_TaskEnable(unsigned long key)
+void osi_TaskEnable(void)
{
xTaskResumeAll();
}
diff --git a/cc3200/util/sleeprestore.h b/cc3200/util/sleeprestore.h
new file mode 100644
index 0000000000..51416f0fce
--- /dev/null
+++ b/cc3200/util/sleeprestore.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Daniel Campora
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SLEEPRESTORE_H_
+#define SLEEPRESTORE_H_
+
+extern void sleep_store(void);
+extern void sleep_restore(void);
+
+#endif /* SLEEPRESTORE_H_ */
diff --git a/cc3200/util/sleeprestore.s b/cc3200/util/sleeprestore.s
new file mode 100644
index 0000000000..decc6994ec
--- /dev/null
+++ b/cc3200/util/sleeprestore.s
@@ -0,0 +1,61 @@
+ .syntax unified
+ .cpu cortex-m4
+ .thumb
+ .text
+ .align 2
+
+@ global variable with the backup registers
+ .extern vault_arm_registers
+@ global function that performs the wake up actions
+ .extern pybsleep_suspend_exit
+
+@ uint sleep_store(void)
+ .global sleep_store
+ .thumb
+ .thumb_func
+ .type sleep_store, %function
+sleep_store:
+ dsb
+ isb
+ push {r0-r12, lr}
+ ldr r1, =vault_arm_registers
+ mrs r0, msp
+ str r0, [r1]
+ mrs r0, psp
+ str r0, [r1, #4]
+ mrs r0, primask
+ str r0, [r1, #12]
+ mrs r0, faultmask
+ str r0, [r1, #16]
+ mrs r0, basepri
+ str r0, [r1, #20]
+ mrs r0, control
+ str r0, [r1, #24]
+ dsb
+ isb
+ bx lr
+
+@ uint sleep_restore(void)
+ .global sleep_restore
+ .thumb
+ .thumb_func
+ .type sleep_restore, %function
+sleep_restore:
+ dsb
+ isb
+ mrs r0, msp
+ msr psp, r0
+ ldr r1, =vault_arm_registers
+ ldr r0, [r1, #24]
+ msr control, r0
+ ldr r0, [r1]
+ msr msp, r0
+ ldr r0, [r1, #12]
+ msr primask, r0
+ ldr r0, [r1, #16]
+ msr faultmask, r0
+ ldr r0, [r1, #20]
+ msr basepri, r0
+ dsb
+ isb
+ bl pybsleep_suspend_exit