aboutsummaryrefslogtreecommitdiff
path: root/cc3200/mods
diff options
context:
space:
mode:
authorDaniel Campora2015-09-16 14:09:51 +0200
committerDaniel Campora2015-09-21 22:30:32 +0200
commitdffa9f6da65cd03e834b2ed3914f40428f72e49f (patch)
tree1f2e51f17c511f884db77e47d481c0f9c1b6bed2 /cc3200/mods
parent660f8613fd8e38863998a9758d97eada0eebc47d (diff)
cc3200: New SD and RTC API plus os and time modules' extensions.
Diffstat (limited to 'cc3200/mods')
-rw-r--r--cc3200/mods/modpyb.c107
-rw-r--r--cc3200/mods/moduos.c421
-rw-r--r--cc3200/mods/moduos.h15
-rw-r--r--cc3200/mods/modussl.c14
-rw-r--r--cc3200/mods/modutime.c95
-rw-r--r--cc3200/mods/modwlan.c4
-rw-r--r--cc3200/mods/pybi2c.c2
-rw-r--r--cc3200/mods/pybrtc.c352
-rw-r--r--cc3200/mods/pybrtc.h5
-rw-r--r--cc3200/mods/pybsd.c236
-rw-r--r--cc3200/mods/pybsd.h19
-rw-r--r--cc3200/mods/pybspi.c2
-rw-r--r--cc3200/mods/pybuart.c2
-rw-r--r--cc3200/mods/pybwdt.c26
14 files changed, 752 insertions, 548 deletions
diff --git a/cc3200/mods/modpyb.c b/cc3200/mods/modpyb.c
index 3e71d658c..c32ea6c90 100644
--- a/cc3200/mods/modpyb.c
+++ b/cc3200/mods/modpyb.c
@@ -40,6 +40,9 @@
#include "rom_map.h"
#include "prcm.h"
#include "pyexec.h"
+#include "ff.h"
+#include "diskio.h"
+#include "sflash_diskio.h"
#include "pybuart.h"
#include "pybpin.h"
#include "pybrtc.h"
@@ -49,9 +52,6 @@
#include "modwlan.h"
#include "moduos.h"
#include "telnet.h"
-#include "ff.h"
-#include "diskio.h"
-#include "sflash_diskio.h"
#include "FreeRTOS.h"
#include "portable.h"
#include "task.h"
@@ -141,90 +141,6 @@ STATIC mp_obj_t pyb_unique_id(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_unique_id_obj, pyb_unique_id);
-/// \function millis()
-/// Returns the number of milliseconds since the board was last reset.
-///
-/// The result is always a micropython smallint (31-bit signed number), so
-/// after 2^30 milliseconds (about 12.4 days) this will start to return
-/// negative numbers.
-STATIC mp_obj_t pyb_millis(void) {
- // We want to "cast" the 32 bit unsigned into a small-int. This means
- // copying the MSB down 1 bit (extending the sign down), which is
- // equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
- return MP_OBJ_NEW_SMALL_INT(HAL_GetTick());
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_millis_obj, pyb_millis);
-
-/// \function elapsed_millis(start)
-/// Returns the number of milliseconds which have elapsed since `start`.
-///
-/// This function takes care of counter wrap, and always returns a positive
-/// number. This means it can be used to measure periods upto about 12.4 days.
-///
-/// Example:
-/// start = pyb.millis()
-/// while pyb.elapsed_millis(start) < 1000:
-/// # Perform some operation
-STATIC mp_obj_t pyb_elapsed_millis(mp_obj_t start) {
- uint32_t startMillis = mp_obj_get_int(start);
- uint32_t currMillis = HAL_GetTick();
- return MP_OBJ_NEW_SMALL_INT((currMillis - startMillis) & 0x3fffffff);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_millis_obj, pyb_elapsed_millis);
-
-/// \function micros()
-/// Returns the number of microseconds since the board was last reset.
-///
-/// The result is always a micropython smallint (31-bit signed number), so
-/// after 2^30 microseconds (about 17.8 minutes) this will start to return
-/// negative numbers.
-STATIC mp_obj_t pyb_micros(void) {
- // We want to "cast" the 32 bit unsigned into a small-int. This means
- // copying the MSB down 1 bit (extending the sign down), which is
- // equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
- return MP_OBJ_NEW_SMALL_INT(sys_tick_get_microseconds());
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_micros_obj, pyb_micros);
-
-/// \function elapsed_micros(start)
-/// Returns the number of microseconds which have elapsed since `start`.
-///
-/// This function takes care of counter wrap, and always returns a positive
-/// number. This means it can be used to measure periods upto about 17.8 minutes.
-///
-/// Example:
-/// start = pyb.micros()
-/// while pyb.elapsed_micros(start) < 1000:
-/// # Perform some operation
-STATIC mp_obj_t pyb_elapsed_micros(mp_obj_t start) {
- uint32_t startMicros = mp_obj_get_int(start);
- uint32_t currMicros = sys_tick_get_microseconds();
- return MP_OBJ_NEW_SMALL_INT((currMicros - startMicros) & 0x3fffffff);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_micros_obj, pyb_elapsed_micros);
-
-/// \function delay(ms)
-/// Delay for the given number of milliseconds.
-STATIC mp_obj_t pyb_delay(mp_obj_t ms_in) {
- mp_int_t ms = mp_obj_get_int(ms_in);
- if (ms > 0) {
- HAL_Delay(ms);
- }
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_delay_obj, pyb_delay);
-
-/// \function udelay(us)
-/// Delay for the given number of microseconds.
-STATIC mp_obj_t pyb_udelay(mp_obj_t usec_in) {
- mp_int_t usec = mp_obj_get_int(usec_in);
- if (usec > 0) {
- UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec));
- }
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay);
-
/// \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) {
@@ -258,29 +174,15 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
#endif
{ MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&pyb_freq_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_unique_id), (mp_obj_t)&pyb_unique_id_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_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_main), (mp_obj_t)&pyb_main_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 },
-
-#if MICROPY_HW_ENABLE_RNG
{ MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj },
-#endif
-#if MICROPY_HW_ENABLE_RTC
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_type },
-#endif
-
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type },
@@ -290,10 +192,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_type },
{ 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_type },
-
-#if MICROPY_HW_HAS_SDCARD
{ MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sd_type },
-#endif
};
STATIC MP_DEFINE_CONST_DICT(pyb_module_globals, pyb_module_globals_table);
diff --git a/cc3200/mods/moduos.c b/cc3200/mods/moduos.c
index 0d62a96e8..8dc7716b5 100644
--- a/cc3200/mods/moduos.c
+++ b/cc3200/mods/moduos.c
@@ -28,21 +28,22 @@
#include <stdint.h>
#include <string.h>
-#include "py/mpconfig.h"
+#include "py/mpstate.h"
#include "py/nlr.h"
-#include "py/obj.h"
#include "py/objtuple.h"
#include "py/objstr.h"
+#include "py/runtime.h"
#include "genhdr/mpversion.h"
#include "ff.h"
#include "diskio.h"
#include "sflash_diskio.h"
#include "file.h"
#include "random.h"
-#include "pybsd.h"
#include "mpexception.h"
#include "version.h"
#include "timeutils.h"
+#include "moduos.h"
+#include "pybsd.h"
/// \module os - basic "operating system" services
///
@@ -52,15 +53,155 @@
/// drives are accessible from here. They are currently:
///
/// /flash -- the serial flash filesystem
-/// /sd -- the SD card (if it exists)
///
-/// On boot up, the current directory is `/flash` if no SD card is inserted,
-/// otherwise it is `/sd`.
+/// On boot up, the current directory is `/flash`.
+
+/******************************************************************************
+ DECLARE PRIVATE DATA
+ ******************************************************************************/
+STATIC uint32_t os_num_mounted_devices;
+
+/******************************************************************************
+ DEFINE PUBLIC FUNCTIONS
+ ******************************************************************************/
+
+void moduos_init0 (void) {
+ // initialize the mount objects list
+ mp_obj_list_init(&MP_STATE_PORT(mount_obj_list), 0);
+ os_num_mounted_devices = 0;
+}
+
+os_fs_mount_t *osmount_find_by_path (const char *path) {
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
+ os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
+ if (!strcmp(path, mount_obj->path)) {
+ return mount_obj;
+ }
+ }
+ return NULL;
+}
+
+os_fs_mount_t *osmount_find_by_volume (uint8_t vol) {
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
+ os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
+ if (vol == mount_obj->vol) {
+ return mount_obj;
+ }
+ }
+ return NULL;
+}
+
+os_fs_mount_t *osmount_find_by_device (mp_obj_t device) {
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
+ os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
+ if (device == mount_obj->device) {
+ return mount_obj;
+ }
+ }
+ return NULL;
+}
/******************************************************************************
DEFINE PRIVATE FUNCTIONS
******************************************************************************/
+// Checks for path equality, ignoring trailing slashes:
+// path_equal(/, /) -> true
+// path_equal(/flash//, /flash) -> true
+// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
+STATIC bool path_equal(const char *path, const char *path_canonical) {
+ for (; *path_canonical != '\0' && *path == *path_canonical; ++path, ++path_canonical) {
+ }
+ if (*path_canonical != '\0') {
+ return false;
+ }
+ for (; *path == '/'; ++path) {
+ }
+ return *path == '\0';
+}
+
+STATIC void append_dir_item (mp_obj_t dirlist, const char *item, bool string) {
+ // make a string object for this entry
+ mp_obj_t entry_o;
+ if (string) {
+ entry_o = mp_obj_new_str(item, strlen(item), false);
+ } else {
+ entry_o = mp_obj_new_bytes((const byte*)item, strlen(item));
+ }
+
+ // add the entry to the list
+ mp_obj_list_append(dirlist, entry_o);
+}
+
+STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonly) {
+ // is the mount point already in use?
+ FILINFO fno;
+#if _USE_LFN
+ fno.lfname = NULL;
+ fno.lfsize = 0;
+#endif
+ // cannot mount twice or on existing paths
+ if (f_stat(path, &fno) == FR_OK || osmount_find_by_device(device)) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ }
+
+ // create a new object
+ os_fs_mount_t *self = m_new_obj(os_fs_mount_t);
+ self->device = device;
+ self->path = path;
+ self->pathlen = pathlen;
+ self->vol = os_num_mounted_devices + 1; // '/flash' is volume 0
+
+ if (device == (mp_obj_t)&pybsd_obj) {
+ // need to make it different to NULL, otherwise it's read only by default
+ self->writeblocks[0] = mp_const_none;
+ self->sync[0] = MP_OBJ_NULL; // no need to sync the SD card
+ self->count[0] = MP_OBJ_NULL;
+ } else {
+ // load block protocol methods
+ mp_load_method(device, MP_QSTR_readblocks, self->readblocks);
+ mp_load_method_maybe(device, MP_QSTR_writeblocks, self->writeblocks);
+ mp_load_method_maybe(device, MP_QSTR_sync, self->sync);
+ mp_load_method(device, MP_QSTR_count, self->count);
+ }
+
+ // Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
+ // User can specify read-only device by:
+ // 1. readonly=True keyword argument
+ // 2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already)
+ if (readonly) {
+ self->writeblocks[0] = MP_OBJ_NULL;
+ }
+
+ // we need to add it before doing the actual mount, so that the volume can be found
+ mp_obj_list_append(&MP_STATE_PORT(mount_obj_list), self);
+
+ // actually mount it
+ if (f_mount(&self->fatfs, self->path, 1) != FR_OK) {
+ // remove it and raise
+ mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), self);
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ }
+
+ // mount succeeded, increment the count
+ os_num_mounted_devices++;
+}
+
+STATIC void unmount (const char *path) {
+ if (FR_OK != f_mount (NULL, path, 1)) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ }
+
+ // remove from the list after the actual unmount
+ os_fs_mount_t *mount_obj;
+ if ((mount_obj = osmount_find_by_path(path))) {
+ mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), mount_obj);
+ os_num_mounted_devices--;
+ } else {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ }
+}
+
/******************************************************************************/
// Micro Python bindings
//
@@ -110,25 +251,20 @@ STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir);
-/// \function getcwd()
-/// Get the current directory.
STATIC mp_obj_t os_getcwd(void) {
char buf[MICROPY_ALLOC_PATH_MAX + 1];
FRESULT res = f_getcwd(buf, sizeof buf);
-
if (res != FR_OK) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
}
-
return mp_obj_new_str(buf, strlen(buf), false);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
-/// \function listdir([dir])
-/// With no argument, list the current directory. Otherwise list the given directory.
STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
bool is_str_type = true;
const char *path;
+ mp_obj_t dir_list = mp_obj_new_list(0, NULL);
if (n_args == 1) {
if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
@@ -139,66 +275,51 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
path = "";
}
- // "hack" to list root directory
+ // "hack" to list the root directory
if (path[0] == '/' && path[1] == '\0') {
- mp_obj_t dir_list = mp_obj_new_list(0, NULL);
- mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_flash));
-#if MICROPY_HW_HAS_SDCARD
- if (pybsd_is_mounted()) {
- mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_sd));
+ // add 'flash' to the list
+ append_dir_item (dir_list, "flash", is_str_type);
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
+ os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
+ append_dir_item (dir_list, &mount_obj->path[1], is_str_type);
+ }
+ } else {
+ FRESULT res;
+ DIR dir;
+ FILINFO fno;
+ #if _USE_LFN
+ char lfn_buf[_MAX_LFN + 1];
+ fno.lfname = lfn_buf;
+ fno.lfsize = sizeof(lfn_buf);
+ #endif
+
+ res = f_opendir(&dir, path); /* Open the directory */
+ if (res != FR_OK) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
}
-#endif
- return dir_list;
- }
-
- FRESULT res;
- DIR dir;
- FILINFO fno;
-#if _USE_LFN
- char lfn_buf[_MAX_LFN + 1];
- fno.lfname = lfn_buf;
- fno.lfsize = sizeof(lfn_buf);
-#endif
-
- res = f_opendir(&dir, path); /* Open the directory */
- if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
- }
-
- mp_obj_t dir_list = mp_obj_new_list(0, NULL);
- for (;;) {
- res = f_readdir(&dir, &fno); /* Read a directory item */
- if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
- if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
- if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
+ for ( ; ; ) {
+ res = f_readdir(&dir, &fno); /* Read a directory item */
+ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
+ if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
+ if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
-#if _USE_LFN
- char *fn = *fno.lfname ? fno.lfname : fno.fname;
-#else
- char *fn = fno.fname;
-#endif
+ #if _USE_LFN
+ char *fn = *fno.lfname ? fno.lfname : fno.fname;
+ #else
+ char *fn = fno.fname;
+ #endif
- // make a string object for this entry
- mp_obj_t entry_o;
- if (is_str_type) {
- entry_o = mp_obj_new_str(fn, strlen(fn), false);
- } else {
- entry_o = mp_obj_new_bytes((const byte*)fn, strlen(fn));
+ // add the entry to the list
+ append_dir_item (dir_list, fn, is_str_type);
}
-
- // add the entry to the list
- mp_obj_list_append(dir_list, entry_o);
+ f_closedir(&dir);
}
- f_closedir(&dir);
-
return dir_list;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
-/// \function mkdir(path)
-/// Create a new directory.
STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
const char *path = mp_obj_str_get_str(path_o);
FRESULT res = f_mkdir(path);
@@ -214,8 +335,6 @@ STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
-/// \function rename(old_path, new_path)
-/// Rename a file
STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
const char *old_path = mp_obj_str_get_str(path_in);
const char *new_path = mp_obj_str_get_str(path_out);
@@ -226,12 +345,9 @@ STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
default:
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
}
-
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
-/// \function remove(path)
-/// Remove a file or a directory
STATIC mp_obj_t os_remove(mp_obj_t path_o) {
const char *path = mp_obj_str_get_str(path_o);
FRESULT res = f_unlink(path);
@@ -244,55 +360,35 @@ STATIC mp_obj_t os_remove(mp_obj_t path_o) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
-// Checks for path equality, ignoring trailing slashes:
-// path_equal(/, /) -> true
-// path_equal(/flash//, /flash) -> true
-// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
-STATIC bool path_equal(const char *path, const char *path_canonical) {
- for (; *path_canonical != '\0' && *path == *path_canonical; ++path, ++path_canonical) {
- }
- if (*path_canonical != '\0') {
- return false;
- }
- for (; *path == '/'; ++path) {
- }
- return *path == '\0';
-}
-
-/// \function stat(path)
-/// Get the status of a file or directory.
STATIC mp_obj_t os_stat(mp_obj_t path_in) {
const char *path = mp_obj_str_get_str(path_in);
-
- FRESULT res;
+ bool isbuilt_in = false;
FILINFO fno;
+ FRESULT res;
#if _USE_LFN
fno.lfname = NULL;
fno.lfsize = 0;
#endif
- if (path_equal(path, "/") || path_equal(path, "/flash") || path_equal(path, "/sd")) {
- // stat built-in directory
-#if MICROPY_HW_HAS_SDCARD
- if (path[1] == 's' && !pybsd_is_mounted()) {
-#else
- if (path[1] == 's') {
-#endif
- // no /sd directory
- res = FR_NO_PATH;
- goto error;
- }
- fno.fsize = 0;
- fno.fdate = 0;
- fno.ftime = 0;
- fno.fattrib = AM_DIR;
- } else {
- res = f_stat(path, &fno);
- if (res != FR_OK) {
- goto error;
+ // check on the user mounted devices
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
+ os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
+ if (path_equal(path, mount_obj->path)) {
+ isbuilt_in = true;
+ break;
}
}
+ if (path_equal(path, "/") || path_equal(path, "/flash") || isbuilt_in) {
+ // stat built-in directory
+ fno.fsize = 0;
+ fno.fdate = 0;
+ fno.ftime = 0;
+ fno.fattrib = AM_DIR;
+ } else if ((res = f_stat(path, &fno)) != FR_OK) {
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ }
+
mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
mp_int_t mode = 0;
if (fno.fattrib & AM_DIR) {
@@ -318,26 +414,16 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
t->items[7] = mp_obj_new_int(seconds); // st_atime
t->items[8] = t->items[7]; // st_mtime
t->items[9] = t->items[7]; // st_ctime
-
return t;
-
-error:
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
-/// \function sync()
-/// Sync all filesystems.
STATIC 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);
-#if MICROPY_HW_ENABLE_RNG
-/// \function urandom(n)
-/// Return a bytes object with n random bytes, generated by the hardware
-/// random number generator.
STATIC mp_obj_t os_urandom(mp_obj_t num) {
mp_int_t n = mp_obj_get_int(num);
vstr_t vstr;
@@ -348,23 +434,102 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
-#endif
-/// \function mkfs('drive')
-/// Formats the selected drive, useful when the filesystem has been damaged beyond repair.
-/// Path must be either '/sd' or '/flash'
-STATIC mp_obj_t os_mkfs(mp_obj_t path_o) {
+STATIC mp_obj_t os_mount(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ static const mp_arg_t mount_args[] = {
+ { MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ };
+
+ // parse args
+ mp_obj_t device = pos_args[0];
+ mp_obj_t mount_point = pos_args[1];
+ mp_arg_val_t args[MP_ARRAY_SIZE(mount_args)];
+ mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(mount_args), mount_args, args);
+
+ // get the mount point
+ mp_uint_t pathlen;
+ const char *path_in = mp_obj_str_get_data(mount_point, &pathlen);
+ if (pathlen == 0) {
+ goto invalid_args;
+ }
+
+ char *path = m_new(char, pathlen + 1);
+ memcpy(path, path_in, pathlen);
+ path[pathlen] = '\0';
+
+ // "remove" any extra slahes at the end
+ while (path[(pathlen - 1)] == '/') {
+ path[--pathlen] = '\0';
+ }
+
+ // is the mount point valid?
+ if (pathlen < 2 || path[0] !='/' || strchr(&path[1], '/')) {
+ goto invalid_args;
+ }
+
+ // now mount it
+ mount(device, path, pathlen, args[0].u_bool);
+
+ return mp_const_none;
+
+invalid_args:
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(os_mount_obj, 2, os_mount);
+
+STATIC mp_obj_t os_unmount(mp_obj_t path_o) {
const char *path = mp_obj_str_get_str(path_o);
- uint8_t sfd;
- if (!strcmp(path, "/flash")) {
+ // '/flash' cannot be unmounted, also not the current working directory
+ if (path_equal(path, "/flash")) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ }
+
+ // now unmount it
+ unmount (path);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_unmount_obj, os_unmount);
+
+STATIC mp_obj_t os_mkfs(mp_obj_t device) {
+ const char *path = "/__mkfs__mnt__";
+ bool unmt = false;
+ FRESULT res;
+
+ if (MP_OBJ_IS_STR_OR_BYTES(device)) {
+ path = mp_obj_str_get_str(device);
+ // otherwise the relative path check will pass...
+ if (path[0] != '/') {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
+ }
+ } else {
+ // mount it and unmount it briefly
+ unmt = true;
+ mount(device, path, strlen(path), false);
+ }
+
+ byte sfd = 0;
+ if (!memcmp(path, "/flash", strlen("/flash"))) {
sfd = 1;
- } else if (!strcmp(path, "/sd")) {
- sfd = 0;
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ os_fs_mount_t *mount_obj;
+ if ((mount_obj = osmount_find_by_path(path))) {
+ if (mount_obj->device != (mp_obj_t)&pybsd_obj &&
+ mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count)) < 2048) {
+ sfd = 1;
+ }
+ }
}
- if (FR_OK != f_mkfs(path, sfd, 0)) {
+
+ // now format the device
+ res = f_mkfs(path, sfd, 0);
+
+ if (unmt) {
+ unmount (path);
+ }
+
+ if (res != FR_OK) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
}
return mp_const_none;
@@ -381,13 +546,13 @@ STATIC const mp_map_elem_t os_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_rename), (mp_obj_t)&os_rename_obj},
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_remove_obj }, // rmdir aliases to remove
+ { MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_remove_obj }, // rmdir aliases to remove
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
+ { MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
-#if MICROPY_HW_ENABLE_RNG
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
-#endif
+ { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&os_mount_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_unmount), (mp_obj_t)&os_unmount_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkfs), (mp_obj_t)&os_mkfs_obj },
/// \constant sep - separation character used in paths
diff --git a/cc3200/mods/moduos.h b/cc3200/mods/moduos.h
index 7e01148d7..99172b706 100644
--- a/cc3200/mods/moduos.h
+++ b/cc3200/mods/moduos.h
@@ -28,5 +28,20 @@
#ifndef MODUOS_H_
#define MODUOS_H_
+typedef struct _os_fs_mount_t {
+ mp_obj_t device;
+ const char *path;
+ mp_uint_t pathlen;
+ mp_obj_t readblocks[4];
+ mp_obj_t writeblocks[4];
+ mp_obj_t sync[2];
+ mp_obj_t count[2];
+ FATFS fatfs;
+ uint8_t vol;
+} os_fs_mount_t;
+
+void moduos_init0 (void);
+os_fs_mount_t *osmount_find_by_path (const char *path);
+os_fs_mount_t *osmount_find_by_volume (uint8_t vol);
#endif // MODUOS_H_
diff --git a/cc3200/mods/modussl.c b/cc3200/mods/modussl.c
index 70116c5b7..e6271e391 100644
--- a/cc3200/mods/modussl.c
+++ b/cc3200/mods/modussl.c
@@ -74,12 +74,12 @@ STATIC const mp_obj_type_t ssl_socket_type = {
STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
STATIC const mp_arg_t allowed_args[] = {
- { MP_QSTR_sock, MP_ARG_REQUIRED | MP_ARG_OBJ, },
- { MP_QSTR_keyfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_certfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_false} },
- { MP_QSTR_cert_reqs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SSL_CERT_NONE} },
- { MP_QSTR_ca_certs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_sock, MP_ARG_REQUIRED | MP_ARG_OBJ, },
+ { MP_QSTR_keyfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_certfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_cert_reqs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SSL_CERT_NONE} },
+ { MP_QSTR_ca_certs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
// parse arguments
@@ -98,7 +98,7 @@ STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args,
NULL : &(mp_obj_str_get_str(args[5].u_obj)[6]);
// server side requires both certfile and keyfile
- if (mp_obj_is_true(args[3].u_obj) && (!keyfile || !certfile)) {
+ if (args[3].u_bool && (!keyfile || !certfile)) {
goto arg_error;
}
diff --git a/cc3200/mods/modutime.c b/cc3200/mods/modutime.c
index 2282b876b..189956599 100644
--- a/cc3200/mods/modutime.c
+++ b/cc3200/mods/modutime.c
@@ -38,14 +38,20 @@
#include "inc/hw_memmap.h"
#include "rom_map.h"
#include "prcm.h"
+#include "systick.h"
#include "pybrtc.h"
+#include "mpsystick.h"
#include "mpexception.h"
+#include "utils.h"
/// \module time - time related functions
///
/// The `time` module provides functions for getting the current time and date,
/// and for sleeping.
+/******************************************************************************/
+// Micro Python bindings
+
/// \function localtime([secs])
/// Convert a time expressed in seconds since Jan 1, 2000 into an 8-tuple which
/// contains: (year, month, mday, hour, minute, second, weekday, yearday)
@@ -99,11 +105,6 @@ STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime);
-
-/// \function mktime()
-/// This is inverse function of localtime. It's argument is a full 8-tuple
-/// which expresses a time as per localtime. It returns an integer which is
-/// the number of seconds since Jan 1, 2000.
STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
mp_uint_t len;
mp_obj_t *elem;
@@ -115,15 +116,16 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
}
- return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]),
- mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]),
- mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])));
+ return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]),
+ mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])));
}
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
+STATIC mp_obj_t time_time(void) {
+ return mp_obj_new_int(pyb_rtc_get_seconds());
+}
+MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
-/// \function sleep(seconds)
-/// Sleep for the given number of seconds.
STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
int32_t sleep_s = mp_obj_get_int(seconds_o);
if (sleep_s > 0) {
@@ -133,20 +135,71 @@ STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
}
MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep);
-/// \function time()
-/// Returns the number of seconds, as an integer, since 1/1/2000.
-STATIC mp_obj_t time_time(void) {
- return mp_obj_new_int(pybrtc_get_seconds());
+STATIC mp_obj_t time_sleep_ms (mp_obj_t ms_in) {
+ mp_int_t ms = mp_obj_get_int(ms_in);
+ if (ms > 0) {
+ HAL_Delay(ms);
+ }
+ return mp_const_none;
}
-MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_ms_obj, time_sleep_ms);
-STATIC const mp_map_elem_t time_module_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
+STATIC mp_obj_t time_sleep_us (mp_obj_t usec_in) {
+ mp_int_t usec = mp_obj_get_int(usec_in);
+ if (usec > 0) {
+ UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec));
+ }
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us);
+
+STATIC mp_obj_t time_ticks_ms(void) {
+ // We want to "cast" the 32 bit unsigned into a small-int. This means
+ // copying the MSB down 1 bit (extending the sign down), which is
+ // equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
+ return MP_OBJ_NEW_SMALL_INT(HAL_GetTick());
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms);
+
+STATIC mp_obj_t time_ticks_us(void) {
+ // We want to "cast" the 32 bit unsigned into a small-int. This means
+ // copying the MSB down 1 bit (extending the sign down), which is
+ // equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
+ return MP_OBJ_NEW_SMALL_INT(sys_tick_get_microseconds());
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us);
- { MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj },
+STATIC mp_obj_t time_ticks_cpu(void) {
+ // We want to "cast" the 32 bit unsigned into a small-int. This means
+ // copying the MSB down 1 bit (extending the sign down), which is
+ // equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
+ return MP_OBJ_NEW_SMALL_INT(SysTickValueGet());
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_cpu_obj, time_ticks_cpu);
+
+STATIC mp_obj_t time_ticks_diff(mp_obj_t t0, mp_obj_t t1) {
+ // We want to "cast" the 32 bit unsigned into a small-int. This means
+ // copying the MSB down 1 bit (extending the sign down), which is
+ // equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
+ uint32_t start = mp_obj_get_int(t0);
+ uint32_t end = mp_obj_get_int(t1);
+ return MP_OBJ_NEW_SMALL_INT((end > start) ? (end - start) : (start - end));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff);
+
+STATIC const mp_map_elem_t time_module_globals_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&time_ticks_us_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&time_ticks_cpu_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj },
};
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c
index 010cf88d4..1c3e63710 100644
--- a/cc3200/mods/modwlan.c
+++ b/cc3200/mods/modwlan.c
@@ -533,7 +533,7 @@ void wlan_sl_enable (int8_t mode, const char *ssid, uint8_t ssid_len, uint8_t se
}
// set current time and date (needed to validate certificates)
- wlan_set_current_time (pybrtc_get_seconds());
+ wlan_set_current_time (pyb_rtc_get_seconds());
// start the servers before returning
wlan_servers_start();
@@ -993,7 +993,7 @@ STATIC mp_obj_t wlan_ifconfig (mp_uint_t n_args, const mp_obj_t *args) {
}
}
// set current time and date (needed to validate certificates)
- wlan_set_current_time (pybrtc_get_seconds());
+ wlan_set_current_time (pyb_rtc_get_seconds());
return mp_const_none;
}
}
diff --git a/cc3200/mods/pybi2c.c b/cc3200/mods/pybi2c.c
index 8692a2f58..5369aa97e 100644
--- a/cc3200/mods/pybi2c.c
+++ b/cc3200/mods/pybi2c.c
@@ -279,7 +279,7 @@ STATIC void pyb_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki
}
}
-STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, mp_arg_val_t *args) {
+STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, const mp_arg_val_t *args) {
// verify that mode is master
if (args[0].u_int != PYBI2C_MASTER) {
goto invalid_args;
diff --git a/cc3200/mods/pybrtc.c b/cc3200/mods/pybrtc.c
index 14a610a67..cc2e26f3a 100644
--- a/cc3200/mods/pybrtc.c
+++ b/cc3200/mods/pybrtc.c
@@ -43,70 +43,86 @@
#include "simplelink.h"
#include "modnetwork.h"
#include "modwlan.h"
+#include "mpexception.h"
/// \moduleref pyb
/// \class RTC - real time clock
-///
-/// The RTC is and independent clock that keeps track of the date
-/// and time.
-///
-/// Example usage:
-///
-/// rtc = pyb.RTC()
-/// rtc.datetime((2014, 5, 1, 4, 13, 0, 0, 0))
-/// print(rtc.datetime())
-
-/******************************************************************************
- DECLARE CONSTANTS
- ******************************************************************************/
-#define PYBRTC_CLOCK_FREQUENCY_HZ 32768
-#define PYBRTC_MIN_INTERVAL_VALUE 25
/******************************************************************************
DEFINE TYPES
******************************************************************************/
-typedef struct {
+typedef struct _pyb_rtc_obj_t {
+ mp_obj_base_t base;
byte prwmode;
-} pybrtc_data_t;
+ bool alarmset;
+ bool repeat;
+} pyb_rtc_obj_t;
/******************************************************************************
DECLARE PRIVATE DATA
******************************************************************************/
-STATIC pybrtc_data_t pybrtc_data;
STATIC const mp_cb_methods_t pybrtc_cb_methods;
-STATIC const mp_obj_base_t pyb_rtc_obj = {&pyb_rtc_type};
+STATIC pyb_rtc_obj_t pyb_rtc_obj = {.prwmode = 0, .alarmset = false, .repeat = false};
+
+/******************************************************************************
+ DECLARE PRIVATE FUNCTIONS
+ ******************************************************************************/
+STATIC uint32_t pyb_rtc_reset (mp_obj_t self_in);
+STATIC void pyb_rtc_callback_enable (mp_obj_t self_in);
+STATIC void pyb_rtc_callback_disable (mp_obj_t self_in);
+STATIC mp_obj_t pyb_rtc_datetime(mp_obj_t self, const mp_obj_t datetime);
/******************************************************************************
DECLARE PUBLIC FUNCTIONS
******************************************************************************/
__attribute__ ((section (".boot")))
-void pybrtc_pre_init(void) {
+void pyb_rtc_pre_init(void) {
// if the RTC was previously set, leave it alone
if (MAP_PRCMSysResetCauseGet() == PRCM_POWER_ON) {
- // fresh reset; configure the RTC Calendar
- // set the date to 1st Jan 2015
- // set the time to 00:00:00
- uint32_t seconds = timeutils_seconds_since_2000(2015, 1, 1, 0, 0, 0);
-
// Mark the RTC in use first
MAP_PRCMRTCInUseSet();
-
- // Now set the RTC calendar seconds
- MAP_PRCMRTCSet(seconds, 0);
+ // reset the time and date
+ pyb_rtc_reset((mp_obj_t)&pyb_rtc_obj);
}
}
-uint32_t pybrtc_get_seconds (void) {
+uint32_t pyb_rtc_get_seconds (void) {
uint32_t seconds;
uint16_t mseconds;
-
MAP_PRCMRTCGet(&seconds, &mseconds);
return seconds;
}
-void pyb_rtc_callback_disable (mp_obj_t self_in) {
+/******************************************************************************
+ DECLARE PRIVATE FUNCTIONS
+ ******************************************************************************/
+STATIC uint32_t pyb_rtc_reset (mp_obj_t self_in) {
+ // fresh reset; configure the RTC Calendar
+ // set the date to 1st Jan 2015
+ // set the time to 00:00:00
+ uint32_t seconds = timeutils_seconds_since_2000(2015, 1, 1, 0, 0, 0);
+ // Now set the RTC calendar seconds
+ MAP_PRCMRTCSet(seconds, 0);
+ return seconds;
+}
+
+STATIC void pyb_rtc_callback_enable (mp_obj_t self_in) {
+ pyb_rtc_obj_t *self = self_in;
// check the wake from param
- if (pybrtc_data.prwmode & PYB_PWR_MODE_ACTIVE) {
+ if (self->prwmode & PYB_PWR_MODE_ACTIVE) {
+ // enable the slow clock interrupt
+ MAP_PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR);
+ } else {
+ // just in case it was already enabled before
+ MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
+ }
+ pybsleep_configure_timer_wakeup (self->prwmode);
+}
+
+STATIC void pyb_rtc_callback_disable (mp_obj_t self_in) {
+ pyb_rtc_obj_t *self = self_in;
+ // check the wake from param
+ if (self->prwmode & PYB_PWR_MODE_ACTIVE) {
// disable the slow clock interrupt
MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
}
@@ -116,102 +132,219 @@ void pyb_rtc_callback_disable (mp_obj_t self_in) {
(void)MAP_PRCMIntStatus();
}
-/******************************************************************************
- DECLARE PRIVATE FUNCTIONS
- ******************************************************************************/
-STATIC void pyb_rtc_callback_enable (mp_obj_t self_in) {
- // check the wake from param
- if (pybrtc_data.prwmode & PYB_PWR_MODE_ACTIVE) {
- // enable the slow clock interrupt
- MAP_PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR);
+STATIC uint pyb_rtc_datetime_s_us(const mp_obj_t datetime, uint32_t *seconds) {
+ timeutils_struct_time_t tm;
+ uint32_t useconds;
+
+ // set date and time
+ mp_obj_t *items;
+ uint len;
+ mp_obj_get_array(datetime, &len, &items);
+
+ // verify the tuple
+ if (len < 3 || len > 8) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
- else {
- // just in case it was already enabled before
- MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
+
+ tm.tm_year = mp_obj_get_int(items[0]);
+ tm.tm_mon = mp_obj_get_int(items[1]);
+ tm.tm_mday = mp_obj_get_int(items[2]);
+ if (len < 7) {
+ useconds = 0;
+ } else {
+ useconds = mp_obj_get_int(items[6]);
}
- pybsleep_configure_timer_wakeup (pybrtc_data.prwmode);
+ if (len < 6) {
+ tm.tm_sec = 0;
+ } else {
+ tm.tm_sec = mp_obj_get_int(items[5]);
+ }
+ if (len < 5) {
+ tm.tm_min = 0;
+ } else {
+ tm.tm_min = mp_obj_get_int(items[4]);
+ }
+ if (len < 4) {
+ tm.tm_hour = 0;
+ } else {
+ tm.tm_hour = mp_obj_get_int(items[3]);
+ }
+ *seconds = timeutils_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+ return useconds;
+}
+
+/// The 8-tuple has the same format as CPython's datetime object:
+///
+/// (year, month, day, hours, minutes, seconds, milliseconds, tzinfo=None)
+///
+STATIC mp_obj_t pyb_rtc_datetime(mp_obj_t self, const mp_obj_t datetime) {
+ uint32_t seconds;
+ uint32_t useconds;
+
+ if (datetime != MP_OBJ_NULL) {
+ useconds = pyb_rtc_datetime_s_us(datetime, &seconds);
+ MAP_PRCMRTCSet(seconds, RTC_U16MS_CYCLES(useconds / 1000));
+ } else {
+ seconds = pyb_rtc_reset(self);
+ }
+
+ // set WLAN time and date, this is needed to verify certificates
+ wlan_set_current_time(seconds);
+ return mp_const_none;
}
/******************************************************************************/
// Micro Python bindings
-/// \classmethod \constructor()
-/// Create an RTC object.
-STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
- // check arguments
- mp_arg_check_num(n_args, n_kw, 0, 0, false);
+STATIC const mp_arg_t pyb_rtc_init_args[] = {
+ { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
+ { MP_QSTR_datetime, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+};
+STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+ // parse args
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
+ mp_arg_val_t args[MP_ARRAY_SIZE(pyb_rtc_init_args)];
+ mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_rtc_init_args, args);
+
+ // check the peripheral id
+ if (args[0].u_int != 0) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ }
+
+ // setup the object
+ pyb_rtc_obj_t *self = &pyb_rtc_obj;
+ self->base.type = &pyb_rtc_type;
+
+ // set the time and date
+ pyb_rtc_datetime((mp_obj_t)&pyb_rtc_obj, args[1].u_obj);
// return constant object
return (mp_obj_t)&pyb_rtc_obj;
}
-/// \method datetime([datetimetuple])
-/// 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
-/// and time.
-///
-/// The 8-tuple has the following format:
-///
-/// (year, month, day, weekday, hours, minutes, seconds, milliseconds)
-///
-/// `weekday` is 0-6 for Monday through Sunday.
-///
-mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_rtc_init (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ // parse args
+ mp_arg_val_t args[MP_ARRAY_SIZE(pyb_rtc_init_args) - 1];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_rtc_init_args[1], args);
+ return pyb_rtc_datetime(pos_args[0], args[0].u_obj);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_init_obj, 1, pyb_rtc_init);
+
+STATIC mp_obj_t pyb_rtc_now (mp_obj_t self_in) {
timeutils_struct_time_t tm;
uint32_t seconds;
uint16_t mseconds;
- if (n_args == 1) {
+ // get the seconds and the milliseconds from the RTC
+ MAP_PRCMRTCGet(&seconds, &mseconds);
+ mseconds = RTC_CYCLES_U16MS(mseconds);
+ timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
+
+ mp_obj_t tuple[8] = {
+ mp_obj_new_int(tm.tm_year),
+ mp_obj_new_int(tm.tm_mon),
+ mp_obj_new_int(tm.tm_mday),
+ mp_obj_new_int(tm.tm_hour),
+ mp_obj_new_int(tm.tm_min),
+ mp_obj_new_int(tm.tm_sec),
+ mp_obj_new_int(mseconds * 1000),
+ mp_const_none
+ };
+ return mp_obj_new_tuple(8, tuple);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_rtc_now_obj, pyb_rtc_now);
+
+STATIC mp_obj_t pyb_rtc_deinit (mp_obj_t self_in) {
+ pyb_rtc_reset (self_in);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_rtc_deinit_obj, pyb_rtc_deinit);
+
+STATIC mp_obj_t pyb_rtc_alarm (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ STATIC const mp_arg_t allowed_args[] = {
+ { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
+ { MP_QSTR_time, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_repeat, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ };
+
+ // parse args
+ pyb_rtc_obj_t *self = pos_args[0];
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), allowed_args, args);
+
+ // check the alarm id
+ if (args[0].u_int != 0) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ }
+
+ uint32_t a_seconds;
+ uint16_t a_mseconds;
+ if (MP_OBJ_IS_TYPE(args[1].u_obj, &mp_type_tuple)) { // datetime tuple given
+ a_mseconds = pyb_rtc_datetime_s_us (args[1].u_obj, &a_seconds) / 1000;
+ } else { // then it must be an integer or MP_OBJ_NULL
+ uint32_t c_seconds;
+ uint16_t c_mseconds;
+ if (MP_OBJ_IS_INT(args[1].u_obj)) {
+ a_seconds = 0, a_mseconds = mp_obj_get_int(args[1].u_obj);
+ } else {
+ a_seconds = 1, a_mseconds = 0;
+ }
// get the seconds and the milliseconds from the RTC
- MAP_PRCMRTCGet(&seconds, &mseconds);
- mseconds = RTC_CYCLES_U16MS(mseconds);
- timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
-
- mp_obj_t tuple[8] = {
- mp_obj_new_int(tm.tm_year),
- mp_obj_new_int(tm.tm_mon),
- mp_obj_new_int(tm.tm_mday),
- mp_obj_new_int(tm.tm_wday),
- mp_obj_new_int(tm.tm_hour),
- mp_obj_new_int(tm.tm_min),
- mp_obj_new_int(tm.tm_sec),
- mp_obj_new_int(mseconds)
- };
- return mp_obj_new_tuple(8, tuple);
- } else {
- // set date and time
- mp_obj_t *items;
- mp_obj_get_array_fixed_n(args[1], 8, &items);
-
- tm.tm_year = mp_obj_get_int(items[0]);
- tm.tm_mon = mp_obj_get_int(items[1]);
- tm.tm_mday = mp_obj_get_int(items[2]);
- // skip the weekday
- tm.tm_hour = mp_obj_get_int(items[4]);
- tm.tm_min = mp_obj_get_int(items[5]);
- tm.tm_sec = mp_obj_get_int(items[6]);
- mseconds = mp_obj_get_int(items[7]);
-
- seconds = timeutils_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
- mseconds = RTC_U16MS_CYCLES(mseconds);
- MAP_PRCMRTCSet(seconds, mseconds);
-
- // set WLAN time and date, this is needed to verify certificates
- wlan_set_current_time(seconds);
- return mp_const_none;
+ MAP_PRCMRTCGet(&c_seconds, &c_mseconds);
+ a_mseconds += RTC_CYCLES_U16MS(c_mseconds);
+ // calculate the future time
+ a_seconds += c_seconds + (a_mseconds / 1000);
+ a_mseconds -= ((a_mseconds / 1000) * 1000);
+ }
+
+ // disable the interrupt before updating anything
+ pyb_rtc_callback_disable((mp_obj_t)self);
+
+ // set the match value
+ MAP_PRCMRTCMatchSet(a_seconds, a_mseconds);
+
+ // enabled it again (according to the power mode)
+ pyb_rtc_callback_enable((mp_obj_t)self);
+
+ // set the alarmset flag and store the repeat one
+ self->alarmset = true;
+ self->repeat = args[2].u_bool;
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_alarm_obj, 1, pyb_rtc_alarm);
+
+STATIC mp_obj_t pyb_rtc_alarm_left (mp_obj_t self_in) {
+ pyb_rtc_obj_t *self = self_in;
+ uint32_t a_seconds, c_seconds;
+ uint16_t a_mseconds, c_mseconds;
+ int32_t ms_left;
+
+ // get the alarm time
+ MAP_PRCMRTCMatchGet(&a_seconds, &a_mseconds);
+ a_mseconds = RTC_CYCLES_U16MS(a_mseconds);
+ // get the current time
+ MAP_PRCMRTCGet(&c_seconds, &c_mseconds);
+ c_mseconds = RTC_CYCLES_U16MS(c_mseconds);
+ // calculate the ms left
+ ms_left = ((a_seconds * 1000) + a_mseconds) - ((c_seconds * 1000) + c_mseconds);
+ if (!self->alarmset || ms_left < 0) {
+ ms_left = 0;
}
+ return mp_obj_new_int(ms_left);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_datetime);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_rtc_alarm_left_obj, pyb_rtc_alarm_left);
/// \method callback(handler, value, pwrmode)
/// Creates a callback object associated with the real time clock
/// min num of arguments is 1 (value). The value is the alarm time
/// in the future, in msec
+/// FIXME
STATIC mp_obj_t pyb_rtc_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);
+ pyb_rtc_obj_t *self = pos_args[0];
// check if any parameters were passed
mp_obj_t _callback = mpcallback_find((mp_obj_t)&pyb_rtc_obj);
@@ -228,14 +361,13 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp
mseconds += f_mseconds - ((f_mseconds / 1000) * 1000);
// disable the interrupt before updating anything
- // (the object is not relevant here, the function already knows it)
- pyb_rtc_callback_disable(NULL);
+ pyb_rtc_callback_disable((mp_obj_t)&pyb_rtc_obj);
// set the match value
MAP_PRCMRTCMatchSet(seconds, mseconds);
// save the power mode data for later
- pybrtc_data.prwmode = args[4].u_int;
+ self->prwmode = args[4].u_int;
// create the callback
_callback = mpcallback_new ((mp_obj_t)&pyb_rtc_obj, args[1].u_obj, &pybrtc_cb_methods, true);
@@ -246,8 +378,8 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp
// the interrupt priority is ignored since it's already set to to highest level by the sleep module
// to make sure that the wakeup callbacks are always called first when resuming from sleep
- // enable the interrupt (the object is not relevant here, the function already knows it)
- pyb_rtc_callback_enable(NULL);
+ // enable the interrupt
+ pyb_rtc_callback_enable((mp_obj_t)&pyb_rtc_obj);
} else if (!_callback) {
_callback = mpcallback_new ((mp_obj_t)&pyb_rtc_obj, mp_const_none, &pybrtc_cb_methods, false);
}
@@ -256,8 +388,12 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_callback_obj, 1, pyb_rtc_callback);
STATIC const mp_map_elem_t pyb_rtc_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_datetime), (mp_obj_t)&pyb_rtc_datetime_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_rtc_callback_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_rtc_init_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_rtc_deinit_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_now), (mp_obj_t)&pyb_rtc_now_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_alarm), (mp_obj_t)&pyb_rtc_alarm_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_left), (mp_obj_t)&pyb_rtc_alarm_left_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_rtc_callback_obj },
};
STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table);
diff --git a/cc3200/mods/pybrtc.h b/cc3200/mods/pybrtc.h
index 55d695a9a..06c4868db 100644
--- a/cc3200/mods/pybrtc.h
+++ b/cc3200/mods/pybrtc.h
@@ -33,8 +33,7 @@
extern const mp_obj_type_t pyb_rtc_type;
-extern void pybrtc_pre_init(void);
-extern void pyb_rtc_callback_disable (mp_obj_t self_in);
-extern uint32_t pybrtc_get_seconds (void);
+extern void pyb_rtc_pre_init(void);
+extern uint32_t pyb_rtc_get_seconds (void);
#endif // PYBRTC_H_
diff --git a/cc3200/mods/pybsd.c b/cc3200/mods/pybsd.c
index 052a6b51e..864db513b 100644
--- a/cc3200/mods/pybsd.c
+++ b/cc3200/mods/pybsd.c
@@ -37,69 +37,46 @@
#include "prcm.h"
#include "gpio.h"
#include "sdhost.h"
-#include "pybpin.h"
-#include "pybsd.h"
#include "ff.h"
#include "diskio.h"
#include "sd_diskio.h"
-#include "simplelink.h"
-#include "debug.h"
+#include "pybsd.h"
#include "mpexception.h"
#include "pybsleep.h"
+#include "pybpin.h"
+#include "pins.h"
-
-#if MICROPY_HW_HAS_SDCARD
-
+/******************************************************************************
+ DEFINE PRIVATE CONSTANTS
+ ******************************************************************************/
#define PYBSD_FREQUENCY_HZ 15000000 // 15MHz
-typedef struct {
- mp_obj_base_t base;
- FATFS *fatfs;
- pin_obj_t *pin_clk;
- bool pinsset;
- bool enabled;
- bool mounted;
-} pybsd_obj_t;
-
/******************************************************************************
- DECLARE PRIVATE DATA
+ DECLARE PUBLIC DATA
******************************************************************************/
-STATIC pybsd_obj_t pybsd_obj = {.pinsset = false, .enabled = false, .mounted = false};
+pybsd_obj_t pybsd_obj = {.pin_clk = MP_OBJ_NULL, .enabled = false};
/******************************************************************************
- DECLARE PRIVATE FUNCTIONS
+ DECLARE PRIVATE DATA
******************************************************************************/
-STATIC void pybsd_hw_init (pybsd_obj_t *self);
-STATIC mp_obj_t pybsd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
-STATIC mp_obj_t pybsd_init (uint n_args, const mp_obj_t *args);
-STATIC mp_obj_t pybsd_deinit (mp_obj_t self_in);
-STATIC mp_obj_t pybsd_mount (mp_obj_t self_in);
-STATIC mp_obj_t pybsd_unmount (mp_obj_t self_in);
+STATIC const mp_obj_t pyb_sd_def_pin[3] = {&pin_GP10, &pin_GP11, &pin_GP15};
/******************************************************************************
- DEFINE PUBLIC FUNCTIONS
+ DECLARE PRIVATE FUNCTIONS
******************************************************************************/
-__attribute__ ((section (".boot")))
-void pybsd_pre_init (void) {
- // allocate memory for the sd file system
- ASSERT ((pybsd_obj.fatfs = mem_Malloc(sizeof(FATFS))) != NULL);
-}
-
-void pybsd_disable (void) {
- pybsd_deinit ((mp_obj_t)&pybsd_obj);
-}
-
-bool pybsd_is_mounted (void) {
- return pybsd_obj.mounted;
-}
+STATIC void pyb_sd_hw_init (pybsd_obj_t *self);
+STATIC mp_obj_t pyb_sd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
+STATIC mp_obj_t pyb_sd_deinit (mp_obj_t self_in);
/******************************************************************************
DEFINE PRIVATE FUNCTIONS
******************************************************************************/
/// Initalizes the sd card hardware driver
-STATIC void pybsd_hw_init (pybsd_obj_t *self) {
- // Configure the clock pin as output only
- MAP_PinDirModeSet(self->pin_clk->pin_num, PIN_DIR_MODE_OUT);
+STATIC void pyb_sd_hw_init (pybsd_obj_t *self) {
+ if (self->pin_clk) {
+ // Configure the clock pin as output only
+ MAP_PinDirModeSet(((pin_obj_t *)(self->pin_clk))->pin_num, PIN_DIR_MODE_OUT);
+ }
// Enable SD peripheral clock
MAP_PRCMPeripheralClkEnable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
// Reset MMCHS
@@ -110,38 +87,36 @@ STATIC void pybsd_hw_init (pybsd_obj_t *self) {
MAP_SDHostSetExpClk(SDHOST_BASE, MAP_PRCMPeripheralClockGet(PRCM_SDHOST), PYBSD_FREQUENCY_HZ);
// Set card rd/wr block len
MAP_SDHostBlockSizeSet(SDHOST_BASE, SD_SECTOR_SIZE);
+ self->enabled = true;
}
-STATIC mp_obj_t pybsd_init_helper (pybsd_obj_t *self, uint n_args, const mp_obj_t *args) {
- if (n_args > 0) {
- if (mp_obj_get_type(args[0]) == &mp_type_tuple) {
- mp_obj_t *items;
- mp_obj_get_array_fixed_n(args[0], 6, &items);
-
- // save the clock pin for later use
- self->pin_clk = (pin_obj_t *)pin_find(items[2]);
-
- // configure the data pin with pull-up enabled
- pin_config ((pin_obj_t *)pin_find(items[0]), mp_obj_get_int(items[1]), 0, PIN_TYPE_STD_PU, -1, PIN_STRENGTH_4MA);
- // configure the clock pin
- pin_config (self->pin_clk, mp_obj_get_int(items[3]), 0, PIN_TYPE_STD, -1, PIN_STRENGTH_4MA);
- // configure the command pin with pull-up enabled
- pin_config ((pin_obj_t *)pin_find(items[4]), mp_obj_get_int(items[5]), 0, PIN_TYPE_STD_PU, -1, PIN_STRENGTH_4MA);
- self->pinsset = true;
+STATIC mp_obj_t pyb_sd_init_helper (pybsd_obj_t *self, const mp_arg_val_t *args) {
+ // assign the pins
+ mp_obj_t pins_o = args[0].u_obj;
+ if (pins_o != mp_const_none) {
+ mp_obj_t *pins;
+ mp_uint_t n_pins = MP_ARRAY_SIZE(pyb_sd_def_pin);
+ if (pins_o == MP_OBJ_NULL) {
+ // use the default pins
+ pins = (mp_obj_t *)pyb_sd_def_pin;
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
+ mp_obj_get_array(pins_o, &n_pins, &pins);
+ if (n_pins != MP_ARRAY_SIZE(pyb_sd_def_pin)) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ }
}
+ pin_assign_pins_af (pins, n_pins, PIN_TYPE_STD_PU, PIN_FN_SD, 0);
+ // save the pins clock
+ self->pin_clk = pin_find(pins[0]);
}
- if (!self->enabled) {
- if (!self->pinsset) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
- }
- pybsd_hw_init (self);
- // mark as enabled and register it with the sleep module
- self->enabled = true;
- pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pybsd_hw_init);
+ pyb_sd_hw_init (self);
+ if (sd_disk_init() != 0) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
}
+
+ // register it with the sleep module
+ pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pyb_sd_hw_init);
return mp_const_none;
}
@@ -149,107 +124,60 @@ STATIC mp_obj_t pybsd_init_helper (pybsd_obj_t *self, uint n_args, const mp_obj_
// Micro Python bindings
//
-/// \classmethod \constructor()
-/// Creates an SD card object.
-/// Accepts a tuple of pins an alternate functions to configure the SD card interface.
-/// When called with no arguments it returns the previoulsy created SD card object.
-///
-/// Usage:
-/// sd = pyb.SD()
-/// Or:
-/// sd = pyb.SD((d0_pin, d0_af, clk_pin, clk_af, cmd_pin, cmd_af))
-///
-STATIC mp_obj_t pybsd_make_new (mp_obj_t type_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, 1, false);
+STATIC const mp_arg_t pyb_sd_init_args[] = {
+ { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
+ { MP_QSTR_pins, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+};
+STATIC mp_obj_t pyb_sd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+ // parse args
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
+ mp_arg_val_t args[MP_ARRAY_SIZE(pyb_sd_init_args)];
+ mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_sd_init_args, args);
+
+ // check the peripheral id
+ if (args[0].u_int != 0) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ }
+
+ // setup and initialize the object
mp_obj_t self = &pybsd_obj;
pybsd_obj.base.type = &pyb_sd_type;
-
- if (n_args > 0) {
- pybsd_init_helper (self, n_args, args);
- }
+ pyb_sd_init_helper (self, &args[1]);
return self;
}
-/// \method init()
-/// Enables the sd card
-STATIC mp_obj_t pybsd_init (uint n_args, const mp_obj_t *args) {
- return pybsd_init_helper(args[0], n_args - 1, args + 1);
+STATIC mp_obj_t pyb_sd_init (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ // parse args
+ mp_arg_val_t args[MP_ARRAY_SIZE(pyb_sd_init_args) - 1];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_sd_init_args[1], args);
+ return pyb_sd_init_helper(pos_args[0], args);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pybsd_init_obj, 1, 2, pybsd_init);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_sd_init_obj, 1, pyb_sd_init);
-/// \method deinit()
-/// Disables the sd card
-STATIC mp_obj_t pybsd_deinit (mp_obj_t self_in) {
+STATIC mp_obj_t pyb_sd_deinit (mp_obj_t self_in) {
pybsd_obj_t *self = self_in;
- if (self->enabled) {
- // unmounted in case not done yet
- pybsd_unmount (self);
- self->enabled = false;
- // disable the peripheral
- MAP_PRCMPeripheralClkDisable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
- // de-initialze the sd card at diskio level
- sd_disk_deinit();
- // unregister it with the sleep module
- pybsleep_remove (self);
- }
+ // disable the peripheral
+ self->enabled = false;
+ MAP_PRCMPeripheralClkDisable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
+ // de-initialze the sd card at diskio level
+ sd_disk_deinit();
+ // unregister it from the sleep module
+ pybsleep_remove (self);
return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_deinit_obj, pybsd_deinit);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sd_deinit_obj, pyb_sd_deinit);
-/// \method mount()
-/// Mount the sd card on /sd
-STATIC mp_obj_t pybsd_mount (mp_obj_t self_in) {
- pybsd_obj_t *self = self_in;
- if (!self->mounted) {
- if (!self->enabled) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
- }
- // try to mount the sd card on /sd
- if (FR_OK != f_mount(self->fatfs, "/sd", 1)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
- }
- mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
- mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
- self->mounted = true;
- }
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_mount_obj, pybsd_mount);
-
-/// \method unmount()
-/// Unmount the sd card
-STATIC mp_obj_t pybsd_unmount (mp_obj_t self_in) {
- pybsd_obj_t *self = self_in;
- if (self->mounted) {
- if (!self->enabled) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
- }
- // unmount the sd card
- f_mount (NULL, "/sd", 1);
- // remove sd paths from mp_sys_path
- mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
- mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
- self->mounted = false;
- // change the drive in case it was /sd
- f_chdrive("/flash");
- }
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_unmount_obj, pybsd_unmount);
-
-STATIC const mp_map_elem_t pybsd_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pybsd_init_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pybsd_deinit_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&pybsd_mount_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_unmount), (mp_obj_t)&pybsd_unmount_obj },
+STATIC const mp_map_elem_t pyb_sd_locals_dict_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_sd_init_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_sd_deinit_obj },
};
-STATIC MP_DEFINE_CONST_DICT(pybsd_locals_dict, pybsd_locals_dict_table);
+
+STATIC MP_DEFINE_CONST_DICT(pyb_sd_locals_dict, pyb_sd_locals_dict_table);
const mp_obj_type_t pyb_sd_type = {
{ &mp_type_type },
.name = MP_QSTR_SD,
- .make_new = pybsd_make_new,
- .locals_dict = (mp_obj_t)&pybsd_locals_dict,
+ .make_new = pyb_sd_make_new,
+ .locals_dict = (mp_obj_t)&pyb_sd_locals_dict,
};
-
-#endif // MICROPY_HW_HAS_SDCARD
diff --git a/cc3200/mods/pybsd.h b/cc3200/mods/pybsd.h
index 145c7dc41..a06df6d8d 100644
--- a/cc3200/mods/pybsd.h
+++ b/cc3200/mods/pybsd.h
@@ -26,12 +26,19 @@
#ifndef PYBSD_H_
#define PYBSD_H_
-#if MICROPY_HW_HAS_SDCARD
-extern const mp_obj_type_t pyb_sd_type;
+/******************************************************************************
+ DEFINE PUBLIC TYPES
+ ******************************************************************************/
+typedef struct {
+ mp_obj_base_t base;
+ mp_obj_t pin_clk;
+ bool enabled;
+} pybsd_obj_t;
-void pybsd_pre_init (void);
-void pybsd_disable (void);
-bool pybsd_is_mounted (void);
-#endif
+/******************************************************************************
+ DECLARE EXPORTED DATA
+ ******************************************************************************/
+extern pybsd_obj_t pybsd_obj;
+extern const mp_obj_type_t pyb_sd_type;
#endif // PYBSD_H_
diff --git a/cc3200/mods/pybspi.c b/cc3200/mods/pybspi.c
index 20ba04cb4..94387bcfb 100644
--- a/cc3200/mods/pybspi.c
+++ b/cc3200/mods/pybspi.c
@@ -156,7 +156,7 @@ STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki
}
}
-STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, mp_arg_val_t *args) {
+STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, const mp_arg_val_t *args) {
// verify that mode is master
if (args[0].u_int != SPI_MODE_MASTER) {
goto invalid_args;
diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c
index b1d74785b..73cf661bc 100644
--- a/cc3200/mods/pybuart.c
+++ b/cc3200/mods/pybuart.c
@@ -352,7 +352,7 @@ STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
}
}
-STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_arg_val_t *args) {
+STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, const mp_arg_val_t *args) {
// get the baudrate
if (args[0].u_int <= 0) {
goto error;
diff --git a/cc3200/mods/pybwdt.c b/cc3200/mods/pybwdt.c
index b1f9086ce..7619404d0 100644
--- a/cc3200/mods/pybwdt.c
+++ b/cc3200/mods/pybwdt.c
@@ -53,17 +53,17 @@
DECLARE TYPES
******************************************************************************/
typedef struct {
+ mp_obj_base_t base;
bool servers;
bool servers_sleeping;
bool simplelink;
bool running;
-} pybwdt_data_t;
+} pyb_wdt_obj_t;
/******************************************************************************
DECLARE PRIVATE DATA
******************************************************************************/
-STATIC pybwdt_data_t pybwdt_data = {.servers = false, .servers_sleeping = false, .simplelink = false, .running = false};
-STATIC const mp_obj_base_t pyb_wdt_obj = {&pyb_wdt_type};
+STATIC pyb_wdt_obj_t pyb_wdt_obj = {.servers = false, .servers_sleeping = false, .simplelink = false, .running = false};
/******************************************************************************
DEFINE PUBLIC FUNCTIONS
@@ -74,15 +74,15 @@ void pybwdt_init0 (void) {
}
void pybwdt_srv_alive (void) {
- pybwdt_data.servers = true;
+ pyb_wdt_obj.servers = true;
}
void pybwdt_srv_sleeping (bool state) {
- pybwdt_data.servers_sleeping = state;
+ pyb_wdt_obj.servers_sleeping = state;
}
void pybwdt_sl_alive (void) {
- pybwdt_data.simplelink = true;
+ pyb_wdt_obj.simplelink = true;
}
/******************************************************************************/
@@ -106,7 +106,7 @@ STATIC mp_obj_t pyb_wdt_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t
if (timeout_ms < PYBWDT_MIN_TIMEOUT_MS) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
}
- if (pybwdt_data.running) {
+ if (pyb_wdt_obj.running) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
}
@@ -128,15 +128,17 @@ STATIC mp_obj_t pyb_wdt_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t
// start the timer. Once it's started, it cannot be disabled.
MAP_WatchdogEnable(WDT_BASE);
- pybwdt_data.running = true;
+ pyb_wdt_obj.base.type = &pyb_wdt_type;
+ pyb_wdt_obj.running = true;
return (mp_obj_t)&pyb_wdt_obj;
}
-STATIC mp_obj_t pyb_wdt_feed(mp_obj_t self) {
- if ((pybwdt_data.servers || pybwdt_data.servers_sleeping) && pybwdt_data.simplelink && pybwdt_data.running) {
- pybwdt_data.servers = false;
- pybwdt_data.simplelink = false;
+STATIC mp_obj_t pyb_wdt_feed(mp_obj_t self_in) {
+ pyb_wdt_obj_t *self = self_in;
+ if ((self->servers || self->servers_sleeping) && self->simplelink && self->running) {
+ self->servers = false;
+ self->simplelink = false;
MAP_WatchdogIntClear(WDT_BASE);
}
return mp_const_none;