summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-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