cc3200: Add power management framework. Add mpcallback class.

Supports suspend and hibernate modes. Waking is possible throug GPIO
and WLAN.
The mpcallback class is generic and can be reused by other classes.
pull/1137/merge
danicampora 2015-03-04 13:52:39 +01:00
rodzic 73aee8da54
commit 9e44383e3f
34 zmienionych plików z 1295 dodań i 1184 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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 = \

Wyświetl plik

@ -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

Wyświetl plik

@ -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), \

Wyświetl plik

@ -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):

Wyświetl plik

@ -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)) {

Wyświetl plik

@ -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)

Wyświetl plik

@ -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 ) );

Wyświetl plik

@ -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,
};

Wyświetl plik

@ -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_ */

Wyświetl plik

@ -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));

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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) &&

Wyświetl plik

@ -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

Wyświetl plik

@ -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)

Wyświetl plik

@ -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_

Wyświetl plik

@ -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_

Wyświetl plik

@ -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

Wyświetl plik

@ -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_ */

Wyświetl plik

@ -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,6 +248,86 @@ STATIC void pin_obj_configure (const pin_obj_t *self) {
MAP_PinConfigSet(self->pin_num, self->strength, self->type);
}
STATIC void pin_extint_enable (mp_obj_t self_in) {
pin_obj_t *self = self_in;
MAP_GPIOIntClear(self->port, self->bit);
MAP_GPIOIntEnable(self->port, self->bit);
}
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:
///
/// - `af` can be in range 0-15, please check the CC3200 datasheet
/// for the details on the AFs availables on each pin (af=0, keeps it as a gpio pin).
/// - `mode` can be one of:
/// - `Pin.IN` - configure the pin for input;
/// - `Pin.OUT` - configure the pin for output;
/// - `type` can be one of:
/// - `Pin.STD` - standard without pull-up or pull-down;
/// - `Pin.STD_PU` - standard with pull-up resistor;
/// - `Pin.STD_PD` - standard with pull-down resistor.
/// - `Pin.OD` - standard without pull up or pull down;
/// - `Pin.OD_PU` - open drain with pull-up resistor;
/// - `Pin.OD_PD` - open drain with pull-down resistor.
/// - `Pin.ANALOG` - configured in analog (adc) mode
/// - `strength` can be one of:
/// - `Pin.S2MA` - 2ma drive strength;
/// - `Pin.S4MA` - 4ma drive strength;
/// - `Pin.S6MA` - 6ma drive strength;
///
/// Returns: `None`.
STATIC const mp_arg_t pin_init_args[] = {
{ MP_QSTR_af, MP_ARG_REQUIRED | MP_ARG_INT },
{ 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} },
};
#define pin_INIT_NUM_ARGS MP_ARRAY_SIZE(pin_init_args)
STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
// parse args
mp_arg_val_t args[pin_INIT_NUM_ARGS];
mp_arg_parse_all(n_args, pos_args, kw_args, pin_INIT_NUM_ARGS, pin_init_args, args);
// get the af
uint af = args[0].u_int;
if (af < PIN_MODE_0 || af > PIN_MODE_15) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
// get the io mode
uint mode = args[1].u_int;
// 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) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
}
// get the type
uint type = args[2].u_int;
if (type != PIN_TYPE_STD && type != PIN_TYPE_STD_PU && type != PIN_TYPE_STD_PD &&
type != PIN_TYPE_OD && type != PIN_TYPE_OD_PU && type != PIN_TYPE_OD_PD) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
// get the strenght
uint strength = args[3].u_int;
if (strength != PIN_STRENGTH_2MA && strength != PIN_STRENGTH_4MA && strength != PIN_STRENGTH_6MA) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
// configure the pin as requested
pin_config (self, af, mode, type, strength);
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) {
@ -270,7 +337,7 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
uint32_t strength = pin_get_strenght(self);
// pin name
print(env, "Pin(Pin.cpu.%s, af=%u", qstr_str(self->name), af);
print(env, "<Pin.cpu.%s, af=%u", qstr_str(self->name), af);
if (af == PIN_MODE_0) {
// IO mode
@ -310,7 +377,7 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
} else {
str_qst = MP_QSTR_S6MA;
}
print(env, ", strength=Pin.%s)", qstr_str(str_qst));
print(env, ", strength=Pin.%s>", qstr_str(str_qst));
}
/// \classmethod \constructor(id, ...)
@ -322,7 +389,7 @@ STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw,
// 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) {
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);
@ -332,85 +399,6 @@ STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw,
return (mp_obj_t)pin;
}
/// \method init(mode, pull=Pin.PULL_NONE, af=-1)
/// Initialise the pin:
///
/// - `af` can be in range 0-15, please check the CC3200 datasheet
/// for the details on the AFs availables on each pin (af=0, keeps it as a gpio pin).
/// - `mode` can be one of:
/// - `Pin.IN` - configure the pin for input;
/// - `Pin.OUT` - configure the pin for output;
/// - `type` can be one of:
/// - `Pin.STD` - standard without pull-up or pull-down;
/// - `Pin.STD_PU` - standard with pull-up resistor;
/// - `Pin.STD_PD` - standard with pull-down resistor.
/// - `Pin.OD` - standard without pull up or pull down;
/// - `Pin.OD_PU` - open drain with pull-up resistor;
/// - `Pin.OD_PD` - open drain with pull-down resistor.
/// - `Pin.ANALOG` - configured in analog (adc) mode
/// - `strength` can be one of:
/// - `Pin.S2MA` - 2ma drive strength;
/// - `Pin.S4MA` - 4ma drive strength;
/// - `Pin.S6MA` - 6ma drive strength;
///
/// Returns: `None`.
STATIC const mp_arg_t pin_init_args[] = {
{ MP_QSTR_af, MP_ARG_REQUIRED | MP_ARG_INT },
{ 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)
STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
// parse args
mp_arg_val_t args[pin_INIT_NUM_ARGS];
mp_arg_parse_all(n_args, pos_args, kw_args, pin_INIT_NUM_ARGS, pin_init_args, args);
// get the af
uint af = args[0].u_int;
if (af < PIN_MODE_0 || af > PIN_MODE_15) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
// 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;
}
}
// get the type
uint type = args[2].u_int;
if (type != PIN_TYPE_STD && type != PIN_TYPE_STD_PU && type != PIN_TYPE_STD_PD &&
type != PIN_TYPE_OD && type != PIN_TYPE_OD_PU && type != PIN_TYPE_OD_PD) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
// get the strenght
uint strength = args[3].u_int;
if (strength != PIN_STRENGTH_2MA && strength != PIN_STRENGTH_4MA && strength != PIN_STRENGTH_6MA) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
// 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;
}
STATIC mp_obj_t pin_obj_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
return pin_obj_init_helper(args[0], n_args - 1, args + 1, 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);
/// \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);
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 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;
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;
}
// 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;
}
// 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_VAR_BETWEEN(pin_intmode_obj, 1, 2, pin_intmode);
/// \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;
}
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);
}
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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:

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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_ */

Wyświetl plik

@ -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,85 +139,10 @@ void uart_deinit(void) {
}
}
// assumes init parameters have been set up correctly
bool uart_init2(pyb_uart_obj_t *self) {
uint uartPerh;
switch (self->uart_id) {
case PYB_UART_0:
self->reg = UARTA0_BASE;
uartPerh = PRCM_UARTA0;
MAP_UARTIntRegister(UARTA0_BASE, UART0IntHandler);
MAP_IntPrioritySet(INT_UARTA0, INT_PRIORITY_LVL_3);
break;
case PYB_UART_1:
self->reg = UARTA1_BASE;
uartPerh = PRCM_UARTA1;
MAP_UARTIntRegister(UARTA1_BASE, UART1IntHandler);
MAP_IntPrioritySet(INT_UARTA1, INT_PRIORITY_LVL_3);
break;
default:
return false;
}
// Enable the peripheral clock
MAP_PRCMPeripheralClkEnable(uartPerh, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
// Reset the uart
MAP_PRCMPeripheralReset(uartPerh);
// Initialize the UART
MAP_UARTConfigSetExpClk(self->reg, MAP_PRCMPeripheralClockGet(uartPerh),
self->baudrate, self->config);
// Enbale the FIFO
MAP_UARTFIFOEnable(self->reg);
// 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));
}
// 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) {
for (;;) {
if (uart_rx_any(self)) {
return true; // have at least 1 char ready for reading
}
if (timeout > 0) {
HAL_Delay (1);
timeout--;
}
else {
return false;
}
}
}
int uart_rx_char(pyb_uart_obj_t *self) {
if (self->read_buf_tail != self->read_buf_head) {
// buffering via IRQ
@ -261,6 +188,73 @@ void uart_tx_strn_cooked(pyb_uart_obj_t *self, const char *str, uint len) {
/******************************************************************************
DEFINE PRIVATE FUNCTIONS
******************************************************************************/
// assumes init parameters have been set up correctly
STATIC void uart_init (pyb_uart_obj_t *self) {
uint uartPerh;
switch (self->uart_id) {
case PYB_UART_0:
self->reg = UARTA0_BASE;
uartPerh = PRCM_UARTA0;
MAP_UARTIntRegister(UARTA0_BASE, UART0IntHandler);
MAP_IntPrioritySet(INT_UARTA0, INT_PRIORITY_LVL_3);
break;
case PYB_UART_1:
self->reg = UARTA1_BASE;
uartPerh = PRCM_UARTA1;
MAP_UARTIntRegister(UARTA1_BASE, UART1IntHandler);
MAP_IntPrioritySet(INT_UARTA1, INT_PRIORITY_LVL_3);
break;
default:
return;
}
// Enable the peripheral clock
MAP_PRCMPeripheralClkEnable(uartPerh, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
// Reset the uart
MAP_PRCMPeripheralReset(uartPerh);
// Initialize the UART
MAP_UARTConfigSetExpClk(self->reg, MAP_PRCMPeripheralClockGet(uartPerh),
self->baudrate, self->config);
// Enbale the FIFO
MAP_UARTFIFOEnable(self->reg);
// 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);
// 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) {
for (;;) {
if (uart_rx_any(self)) {
return true; // have at least 1 char ready for reading
}
if (timeout > 0) {
HAL_Delay (1);
timeout--;
}
else {
return false;
}
}
}
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;
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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)

Wyświetl plik

@ -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
\note
\warning
*/
unsigned long osi_TaskDisable(void);
/*!
\brief This function used to enable all tasks
\param unsigned long
\return - void
\note
\warning
*/
void osi_TaskEnable(unsigned long);
void osi_TaskDisable(void);
/*!
\brief This function used to enable all tasks
\param - void
\return - void
\note
\warning
*/
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;

Wyświetl plik

@ -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();
}

Wyświetl plik

@ -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_ */

Wyświetl plik

@ -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