summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDaniel Campora <daniel@wipy.io>2015-09-16 14:09:51 +0200
committerDaniel Campora <daniel@wipy.io>2015-09-21 22:30:32 +0200
commitdffa9f6da65cd03e834b2ed3914f40428f72e49f (patch)
tree1f2e51f17c511f884db77e47d481c0f9c1b6bed2
parent660f8613fd8e38863998a9758d97eada0eebc47d (diff)
downloadmicropython-dffa9f6da65cd03e834b2ed3914f40428f72e49f.tar.gz
micropython-dffa9f6da65cd03e834b2ed3914f40428f72e49f.zip
cc3200: New SD and RTC API plus os and time modules' extensions.
-rw-r--r--cc3200/boards/LAUNCHXL/mpconfigboard.h3
-rw-r--r--cc3200/boards/WIPY/mpconfigboard.h3
-rw-r--r--cc3200/fatfs/src/diskio.c184
-rw-r--r--cc3200/fatfs/src/diskio.h2
-rw-r--r--cc3200/fatfs/src/drivers/sd_diskio.c129
-rw-r--r--cc3200/fatfs/src/drivers/sd_diskio.h1
-rw-r--r--cc3200/fatfs/src/ffconf.c38
-rw-r--r--cc3200/ftp/ftp.c140
-rw-r--r--cc3200/misc/mpsystick.c2
-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
-rw-r--r--cc3200/mpconfigport.h1
-rw-r--r--cc3200/mptask.c19
-rw-r--r--cc3200/qstrdefsport.h56
-rw-r--r--cc3200/tools/smoke.py10
-rw-r--r--cc3200/util/random.c21
-rw-r--r--cc3200/util/random.h4
-rw-r--r--docs/wipy/quickref.rst7
-rw-r--r--tests/wipy/i2c.py8
-rw-r--r--tests/wipy/os.py155
-rw-r--r--tests/wipy/os.py.exp30
-rw-r--r--tests/wipy/rtc.py100
-rw-r--r--tests/wipy/rtc.py.exp34
-rw-r--r--tests/wipy/sd.py46
-rw-r--r--tests/wipy/sd.py.exp6
-rw-r--r--tests/wipy/time.py78
-rw-r--r--tests/wipy/time.py.exp65
-rw-r--r--tests/wipy/uart.py3
-rw-r--r--tests/wipy/wdt.py7
41 files changed, 1565 insertions, 887 deletions
diff --git a/cc3200/boards/LAUNCHXL/mpconfigboard.h b/cc3200/boards/LAUNCHXL/mpconfigboard.h
index d0ece9b8db..ac7b41f5dd 100644
--- a/cc3200/boards/LAUNCHXL/mpconfigboard.h
+++ b/cc3200/boards/LAUNCHXL/mpconfigboard.h
@@ -30,9 +30,6 @@
#define MICROPY_HW_BOARD_NAME "LaunchPad"
#define MICROPY_HW_MCU_NAME "CC3200"
-#define MICROPY_HW_HAS_SDCARD (0)
-#define MICROPY_HW_ENABLE_RNG (1)
-#define MICROPY_HW_ENABLE_RTC (1)
#define MICROPY_HW_ANTENNA_DIVERSITY (0)
#define MICROPY_STDIO_UART 0
diff --git a/cc3200/boards/WIPY/mpconfigboard.h b/cc3200/boards/WIPY/mpconfigboard.h
index 237df197c1..57fdc9a609 100644
--- a/cc3200/boards/WIPY/mpconfigboard.h
+++ b/cc3200/boards/WIPY/mpconfigboard.h
@@ -30,9 +30,6 @@
#define MICROPY_HW_BOARD_NAME "WiPy"
#define MICROPY_HW_MCU_NAME "CC3200"
-#define MICROPY_HW_HAS_SDCARD (1)
-#define MICROPY_HW_ENABLE_RNG (1)
-#define MICROPY_HW_ENABLE_RTC (1)
#define MICROPY_HW_ANTENNA_DIVERSITY (1)
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA3
diff --git a/cc3200/fatfs/src/diskio.c b/cc3200/fatfs/src/diskio.c
index cd1d2e5be5..f8a84a30c5 100644
--- a/cc3200/fatfs/src/diskio.c
+++ b/cc3200/fatfs/src/diskio.c
@@ -10,12 +10,11 @@
#include <stdbool.h>
#include "py/mpconfig.h"
+#include "py/runtime.h"
#include "py/obj.h"
-#include "diskio.h" /* FatFs lower layer API */
+#include "diskio.h" /* FatFs lower layer API */
#include "sflash_diskio.h" /* Serial flash disk IO API */
-#if MICROPY_HW_HAS_SDCARD
-#include "sd_diskio.h" /* SDCARD disk IO API */
-#endif
+#include "sd_diskio.h" /* SDCARD disk IO API */
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
@@ -23,10 +22,9 @@
#include "prcm.h"
#include "pybrtc.h"
#include "timeutils.h"
-
-/* Definitions of physical drive number for each drive */
-#define SFLASH 0 /* Map SFLASH drive to drive number 0 */
-#define SDCARD 1 /* Map SD card to drive number 1 */
+#include "ff.h"
+#include "pybsd.h"
+#include "moduos.h"
/*-----------------------------------------------------------------------*/
@@ -37,21 +35,20 @@ DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
- switch (pdrv) {
- case SFLASH :
- return sflash_disk_status();
-#if MICROPY_HW_HAS_SDCARD
- case SDCARD :
- return sd_disk_status();
-#endif
- default:
- break;
- }
- return STA_NODISK;
+ if (pdrv == FLASH) {
+ return sflash_disk_status();
+ } else {
+ os_fs_mount_t *mount_obj;
+ if ((mount_obj = osmount_find_by_volume(pdrv))) {
+ if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
+ return STA_PROTECT;
+ }
+ return 0;
+ }
+ }
+ return STA_NODISK;
}
-
-
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
@@ -60,29 +57,22 @@ DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
- DSTATUS stat = 0;
-
- switch (pdrv) {
- case SFLASH :
- if (RES_OK != sflash_disk_init()) {
- stat = STA_NOINIT;
- }
- return stat;
-#if MICROPY_HW_HAS_SDCARD
- case SDCARD :
- if (RES_OK != sd_disk_init()) {
- stat = STA_NOINIT;
+ if (pdrv == FLASH) {
+ if (RES_OK != sflash_disk_init()) {
+ return STA_NOINIT;
}
- return stat;
-#endif
- default:
- break;
- }
- return STA_NOINIT;
+ } else {
+ os_fs_mount_t *mount_obj;
+ if ((mount_obj = osmount_find_by_volume(pdrv))) {
+ if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
+ return STA_PROTECT;
+ }
+ return 0;
+ }
+ }
+ return STA_NODISK;
}
-
-
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
@@ -94,22 +84,25 @@ DRESULT disk_read (
UINT count /* Number of sectors to read */
)
{
- switch (pdrv) {
- case SFLASH :
- return sflash_disk_read(buff, sector, count);
-#if MICROPY_HW_HAS_SDCARD
- case SDCARD :
- return sd_disk_read(buff, sector, count);
-#endif
- default:
- break;
- }
-
- return RES_PARERR;
+ if (pdrv == FLASH) {
+ return sflash_disk_read(buff, sector, count);
+ } else {
+ os_fs_mount_t *mount_obj;
+ if ((mount_obj = osmount_find_by_volume(pdrv))) {
+ // optimization for the built-in sd card device
+ if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
+ return sd_disk_read(buff, sector, count);
+ }
+ mount_obj->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
+ mount_obj->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
+ return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->readblocks));
+ }
+ // nothing mounted
+ return RES_ERROR;
+ }
+ return RES_PARERR;
}
-
-
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
@@ -122,18 +115,23 @@ DRESULT disk_write (
UINT count /* Number of sectors to write */
)
{
- switch (pdrv) {
- case SFLASH :
- return sflash_disk_write(buff, sector, count);
-#if MICROPY_HW_HAS_SDCARD
- case SDCARD :
- return sd_disk_write(buff, sector, count);
-#endif
- default:
- break;
- }
-
- return RES_PARERR;
+ if (pdrv == FLASH) {
+ return sflash_disk_write(buff, sector, count);
+ } else {
+ os_fs_mount_t *mount_obj;
+ if ((mount_obj = osmount_find_by_volume(pdrv))) {
+ // optimization for the built-in sd card device
+ if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
+ return sd_disk_write(buff, sector, count);
+ }
+ mount_obj->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
+ mount_obj->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void *)buff);
+ return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->writeblocks));
+ }
+ // nothing mounted
+ return RES_ERROR;
+ }
+ return RES_PARERR;
}
#endif
@@ -149,41 +147,47 @@ DRESULT disk_ioctl (
void *buff /* Buffer to send/receive control data */
)
{
- switch (pdrv) {
- case SFLASH:
+ if (pdrv == FLASH) {
switch (cmd) {
case CTRL_SYNC:
return sflash_disk_flush();
case GET_SECTOR_COUNT:
*((DWORD*)buff) = SFLASH_SECTOR_COUNT;
return RES_OK;
- break;
case GET_SECTOR_SIZE:
- *((WORD*)buff) = SFLASH_SECTOR_SIZE;
+ *((DWORD*)buff) = SFLASH_SECTOR_SIZE;
return RES_OK;
- break;
case GET_BLOCK_SIZE:
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
return RES_OK;
}
- break;
-#if MICROPY_HW_HAS_SDCARD
- case SDCARD:
- switch (cmd) {
- case CTRL_SYNC:
- return RES_OK;
- case GET_SECTOR_COUNT:
- *(WORD*)buff = sd_disk_info.ulNofBlock;
- break;
- case GET_SECTOR_SIZE :
- *(WORD*)buff = SD_SECTOR_SIZE;
- break;
- case GET_BLOCK_SIZE:
- *((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
- return RES_OK;
+ } else {
+ os_fs_mount_t *mount_obj;
+ if ((mount_obj = osmount_find_by_volume(pdrv))) {
+ switch (cmd) {
+ case CTRL_SYNC:
+ if (mount_obj->sync[0] != MP_OBJ_NULL) {
+ mp_call_method_n_kw(0, 0, mount_obj->sync);
+ }
+ return RES_OK;
+ case GET_SECTOR_COUNT:
+ // optimization for the built-in sd card device
+ if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
+ *((DWORD*)buff) = sd_disk_info.ulNofBlock * (sd_disk_info.ulBlockSize / 512);
+ } else {
+ *((DWORD*)buff) = mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count));
+ }
+ return RES_OK;
+ case GET_SECTOR_SIZE:
+ *((DWORD*)buff) = SD_SECTOR_SIZE; // Sector size is fixed to 512 bytes, as with SD cards
+ return RES_OK;
+ case GET_BLOCK_SIZE:
+ *((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
+ return RES_OK;
+ }
}
- break;
-#endif
+ // nothing mounted
+ return RES_ERROR;
}
return RES_PARERR;
}
@@ -195,7 +199,7 @@ DWORD get_fattime (
)
{
timeutils_struct_time_t tm;
- timeutils_seconds_since_2000_to_struct_time(pybrtc_get_seconds(), &tm);
+ timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
diff --git a/cc3200/fatfs/src/diskio.h b/cc3200/fatfs/src/diskio.h
index 6e4a056f06..15d732b6d1 100644
--- a/cc3200/fatfs/src/diskio.h
+++ b/cc3200/fatfs/src/diskio.h
@@ -38,6 +38,8 @@ DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
+/* Definitions of physical drive number for each drive */
+#define FLASH 0 /* Map FLASH drive to drive number 0 */
/* Disk Status Bits (DSTATUS) */
diff --git a/cc3200/fatfs/src/drivers/sd_diskio.c b/cc3200/fatfs/src/drivers/sd_diskio.c
index 3b17aa6b89..358f33fbbd 100644
--- a/cc3200/fatfs/src/drivers/sd_diskio.c
+++ b/cc3200/fatfs/src/drivers/sd_diskio.c
@@ -302,19 +302,6 @@ void sd_disk_deinit (void) {
//*****************************************************************************
//
-//! Gets the disk status.
-//!
-//! This function gets the current status of the drive.
-//!
-//! \return Returns the current status of the specified drive
-//
-//*****************************************************************************
-DSTATUS sd_disk_status (void) {
- return sd_disk_info.bStatus;
-}
-
-//*****************************************************************************
-//
//! Reads sector(s) from the disk drive.
//!
//!
@@ -365,6 +352,7 @@ DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT SectorCount) {
pBuffer += 4;
}
CardSendCmd(CMD_STOP_TRANS, 0);
+ while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
Res = RES_OK;
}
}
@@ -384,61 +372,62 @@ DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT SectorCount) {
//
//*****************************************************************************
DRESULT sd_disk_write (const BYTE* pBuffer, DWORD ulSectorNumber, UINT SectorCount) {
- DRESULT Res = RES_ERROR;
- unsigned long ulSize;
-
- if (SectorCount > 0) {
- // Return if disk not initialized
- if (sd_disk_info.bStatus & STA_NOINIT) {
- return RES_NOTRDY;
- }
-
- // SDSC uses linear address, SDHC uses block address
- if (sd_disk_info.ulCapClass == CARD_CAP_CLASS_SDSC) {
- ulSectorNumber = ulSectorNumber * SD_SECTOR_SIZE;
- }
-
- // Set the block count
- MAP_SDHostBlockCountSet(SDHOST_BASE, SectorCount);
-
- // Compute the number of words
- ulSize = (SD_SECTOR_SIZE * SectorCount) / 4;
-
- // Check if 1 block or multi block transfer
- if (SectorCount == 1) {
- // Send single block write command
- if (CardSendCmd(CMD_WRITE_SINGLE_BLK, ulSectorNumber) == 0) {
- // Write the data
- while (ulSize--) {
- MAP_SDHostDataWrite (SDHOST_BASE, (*(unsigned long *)pBuffer));
- pBuffer += 4;
- }
- // Wait for data transfer complete
- while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
- Res = RES_OK;
- }
- }
- else {
- // Set the card write block count
- if (sd_disk_info.ucCardType == CARD_TYPE_SDCARD) {
- CardSendCmd(CMD_APP_CMD,sd_disk_info.usRCA << 16);
- CardSendCmd(CMD_SET_BLK_CNT, SectorCount);
- }
-
- // Send multi block write command
- if (CardSendCmd(CMD_WRITE_MULTI_BLK, ulSectorNumber) == 0) {
- // Write the data buffer
- while (ulSize--) {
- MAP_SDHostDataWrite(SDHOST_BASE, (*(unsigned long *)pBuffer));
- pBuffer += 4;
- }
- // Wait for transfer complete
- while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
- CardSendCmd(CMD_STOP_TRANS, 0);
- Res = RES_OK;
- }
- }
- }
-
- return Res;
+ DRESULT Res = RES_ERROR;
+ unsigned long ulSize;
+
+ if (SectorCount > 0) {
+ // Return if disk not initialized
+ if (sd_disk_info.bStatus & STA_NOINIT) {
+ return RES_NOTRDY;
+ }
+
+ // SDSC uses linear address, SDHC uses block address
+ if (sd_disk_info.ulCapClass == CARD_CAP_CLASS_SDSC) {
+ ulSectorNumber = ulSectorNumber * SD_SECTOR_SIZE;
+ }
+
+ // Set the block count
+ MAP_SDHostBlockCountSet(SDHOST_BASE, SectorCount);
+
+ // Compute the number of words
+ ulSize = (SD_SECTOR_SIZE * SectorCount) / 4;
+
+ // Check if 1 block or multi block transfer
+ if (SectorCount == 1) {
+ // Send single block write command
+ if (CardSendCmd(CMD_WRITE_SINGLE_BLK, ulSectorNumber) == 0) {
+ // Write the data
+ while (ulSize--) {
+ MAP_SDHostDataWrite (SDHOST_BASE, (*(unsigned long *)pBuffer));
+ pBuffer += 4;
+ }
+ // Wait for data transfer complete
+ while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
+ Res = RES_OK;
+ }
+ }
+ else {
+ // Set the card write block count
+ if (sd_disk_info.ucCardType == CARD_TYPE_SDCARD) {
+ CardSendCmd(CMD_APP_CMD,sd_disk_info.usRCA << 16);
+ CardSendCmd(CMD_SET_BLK_CNT, SectorCount);
+ }
+
+ // Send multi block write command
+ if (CardSendCmd(CMD_WRITE_MULTI_BLK, ulSectorNumber) == 0) {
+ // Write the data buffer
+ while (ulSize--) {
+ MAP_SDHostDataWrite(SDHOST_BASE, (*(unsigned long *)pBuffer));
+ pBuffer += 4;
+ }
+ // Wait for transfer complete
+ while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
+ CardSendCmd(CMD_STOP_TRANS, 0);
+ while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
+ Res = RES_OK;
+ }
+ }
+ }
+
+ return Res;
}
diff --git a/cc3200/fatfs/src/drivers/sd_diskio.h b/cc3200/fatfs/src/drivers/sd_diskio.h
index f1cb2a0bfe..b5a1944ec4 100644
--- a/cc3200/fatfs/src/drivers/sd_diskio.h
+++ b/cc3200/fatfs/src/drivers/sd_diskio.h
@@ -21,7 +21,6 @@ extern DiskInfo_t sd_disk_info;
DSTATUS sd_disk_init (void);
void sd_disk_deinit (void);
-DSTATUS sd_disk_status (void);
DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT bSectorCount);
DRESULT sd_disk_write (const BYTE* pBuffer, DWORD ulSectorNumber, UINT bSectorCount);
diff --git a/cc3200/fatfs/src/ffconf.c b/cc3200/fatfs/src/ffconf.c
index e3c425e332..5726db1bc5 100644
--- a/cc3200/fatfs/src/ffconf.c
+++ b/cc3200/fatfs/src/ffconf.c
@@ -26,11 +26,11 @@
#include <string.h>
-#include "py/mpconfig.h"
-#include "py/misc.h"
+#include "py/mpstate.h"
#include "ff.h"
#include "ffconf.h"
#include "diskio.h"
+#include "moduos.h"
#if _FS_RPATH
extern BYTE ff_CurrVol;
@@ -65,31 +65,29 @@ int ff_get_ldnumber (const TCHAR **path) {
}
if (check_path(path, "/flash", 6)) {
- return 0;
+ return FLASH;
}
-#if MICROPY_HW_HAS_SDCARD
- else if (check_path(path, "/sd", 3)) {
- return 1;
- }
-#endif
else {
- return -1;
+ 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 (check_path(path, mount_obj->path, mount_obj->pathlen)) {
+ return mount_obj->vol;
+ }
+ }
}
+
+ return -1;
}
void ff_get_volname(BYTE vol, TCHAR **dest) {
-#if MICROPY_HW_HAS_SDCARD
- if (vol == 0)
-#endif
- {
+ if (vol == FLASH) {
memcpy(*dest, "/flash", 6);
*dest += 6;
+ } else {
+ os_fs_mount_t *mount_obj;
+ if ((mount_obj = osmount_find_by_volume(vol))) {
+ memcpy(*dest, mount_obj->path, mount_obj->pathlen);
+ *dest += mount_obj->pathlen;
+ }
}
-#if MICROPY_HW_HAS_SDCARD
- else
- {
- memcpy(*dest, "/sd", 3);
- *dest += 3;
- }
-#endif
}
diff --git a/cc3200/ftp/ftp.c b/cc3200/ftp/ftp.c
index f61ee6d481..221fede058 100644
--- a/cc3200/ftp/ftp.c
+++ b/cc3200/ftp/ftp.c
@@ -28,7 +28,7 @@
#include <ctype.h>
#include "std.h"
-#include "py/mpconfig.h"
+#include "py/mpstate.h"
#include MICROPY_HAL_H
#include "py/obj.h"
#include "inc/hw_types.h"
@@ -47,9 +47,9 @@
#include "ff.h"
#include "fifo.h"
#include "socketfifo.h"
-#include "pybsd.h"
#include "updater.h"
#include "timeutils.h"
+#include "moduos.h"
/******************************************************************************
DEFINE PRIVATE CONSTANTS
@@ -93,16 +93,12 @@ typedef enum {
E_FTP_STE_SUB_DISCONNECTED = 0,
E_FTP_STE_SUB_LISTEN_FOR_DATA,
E_FTP_STE_SUB_DATA_CONNECTED
-} ftp_data_substate_t;
-
-typedef union {
- ftp_data_substate_t data;
} ftp_substate_t;
typedef struct {
bool uservalid : 1;
bool passvalid : 1;
-}ftp_loggin_t;
+} ftp_loggin_t;
typedef enum {
E_FTP_NOTHING_OPEN = 0,
@@ -128,8 +124,9 @@ typedef struct {
int16_t c_sd;
int16_t d_sd;
int16_t dtimeout;
- ftp_state_t state;
- ftp_substate_t substate;
+ uint16_t volcount;
+ uint8_t state;
+ uint8_t substate;
uint8_t txRetries;
uint8_t logginRetries;
ftp_loggin_t loggin;
@@ -137,6 +134,7 @@ typedef struct {
bool closechild;
bool enabled;
bool special_file;
+ bool listroot;
} ftp_data_t;
typedef struct {
@@ -217,7 +215,7 @@ static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name);
static bool ftp_open_file (const char *path, int mode);
static ftp_result_t ftp_read_file (char *filebuf, uint32_t desiredsize, uint32_t *actualsize);
static ftp_result_t ftp_write_file (char *filebuf, uint32_t size);
-static ftp_result_t ftp_open_dir_for_listing (const char *path, char *list, uint32_t maxlistsize, uint32_t *listsize);
+static ftp_result_t ftp_open_dir_for_listing (const char *path);
static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *listsize);
static void ftp_open_child (char *pwd, char *dir);
static void ftp_close_child (char *pwd);
@@ -239,8 +237,9 @@ void ftp_init (void) {
ftp_data.ld_sd = -1;
ftp_data.e_open = E_FTP_NOTHING_OPEN;
ftp_data.state = E_FTP_STE_DISABLED;
- ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
+ ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
ftp_data.special_file = false;
+ ftp_data.volcount = 0;
}
void ftp_run (void) {
@@ -254,7 +253,7 @@ void ftp_run (void) {
}
break;
case E_FTP_STE_READY:
- if (ftp_data.c_sd < 0 && ftp_data.substate.data == E_FTP_STE_SUB_DISCONNECTED) {
+ if (ftp_data.c_sd < 0 && ftp_data.substate == E_FTP_STE_SUB_DISCONNECTED) {
if (E_FTP_RESULT_OK == ftp_wait_for_connection(ftp_data.lc_sd, &ftp_data.c_sd)) {
ftp_data.txRetries = 0;
ftp_data.logginRetries = 0;
@@ -267,7 +266,7 @@ void ftp_run (void) {
}
}
if (SOCKETFIFO_IsEmpty()) {
- if (ftp_data.c_sd > 0 && ftp_data.substate.data != E_FTP_STE_SUB_LISTEN_FOR_DATA) {
+ if (ftp_data.c_sd > 0 && ftp_data.substate != E_FTP_STE_SUB_LISTEN_FOR_DATA) {
ftp_process_cmd();
if (ftp_data.state != E_FTP_STE_READY) {
break;
@@ -284,8 +283,7 @@ void ftp_run (void) {
ftp_list_dir((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, &listsize);
if (listsize > 0) {
ftp_send_data(listsize);
- }
- else {
+ } else {
ftp_send_reply(226, NULL);
ftp_data.state = E_FTP_STE_END_TRANSFER;
}
@@ -356,19 +354,19 @@ void ftp_run (void) {
break;
}
- switch (ftp_data.substate.data) {
+ switch (ftp_data.substate) {
case E_FTP_STE_SUB_DISCONNECTED:
break;
case E_FTP_STE_SUB_LISTEN_FOR_DATA:
if (E_FTP_RESULT_OK == ftp_wait_for_connection(ftp_data.ld_sd, &ftp_data.d_sd)) {
ftp_data.dtimeout = 0;
- ftp_data.substate.data = E_FTP_STE_SUB_DATA_CONNECTED;
+ ftp_data.substate = E_FTP_STE_SUB_DATA_CONNECTED;
}
else if (ftp_data.dtimeout++ > FTP_DATA_TIMEOUT_MS / FTP_CYCLE_TIME_MS) {
ftp_data.dtimeout = 0;
// close the listening socket
servers_close_socket(&ftp_data.ld_sd);
- ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
+ ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
}
break;
case E_FTP_STE_SUB_DATA_CONNECTED:
@@ -377,7 +375,7 @@ void ftp_run (void) {
servers_close_socket(&ftp_data.ld_sd);
servers_close_socket(&ftp_data.d_sd);
ftp_close_filesystem_on_error ();
- ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
+ ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
}
break;
default:
@@ -389,7 +387,7 @@ void ftp_run (void) {
// check the state of the data sockets
if (ftp_data.d_sd < 0 && (ftp_data.state > E_FTP_STE_READY)) {
- ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
+ ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
ftp_data.state = E_FTP_STE_READY;
}
}
@@ -410,7 +408,8 @@ void ftp_reset (void) {
servers_close_socket(&ftp_data.ld_sd);
ftp_close_cmd_data();
ftp_data.state = E_FTP_STE_START;
- ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
+ ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
+ ftp_data.volcount = 0;
SOCKETFIFO_Flush();
}
@@ -554,7 +553,7 @@ static void ftp_send_from_fifo (void) {
servers_close_socket(&ftp_data.ld_sd);
// this one is the command socket
servers_close_socket(fifoelement.sd);
- ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
+ ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
}
ftp_close_filesystem_on_error();
}
@@ -604,7 +603,6 @@ static void ftp_process_cmd (void) {
_i32 len;
char *bufptr = (char *)ftp_cmd_buffer;
ftp_result_t result;
- uint32_t listsize;
FRESULT fres;
FILINFO fno;
#if _USE_LFN
@@ -706,7 +704,7 @@ static void ftp_process_cmd (void) {
{
// some servers (e.g. google chrome) send PASV several times very quickly
servers_close_socket(&ftp_data.d_sd);
- ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
+ ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
bool socketcreated = true;
if (ftp_data.ld_sd < 0) {
socketcreated = ftp_create_listening_socket(&ftp_data.ld_sd, FTP_PASIVE_DATA_PORT, FTP_DATA_CLIENTS_MAX);
@@ -718,7 +716,7 @@ static void ftp_process_cmd (void) {
wlan_get_ip(&ip);
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "(%u,%u,%u,%u,%u,%u)",
pip[3], pip[2], pip[1], pip[0], (FTP_PASIVE_DATA_PORT >> 8), (FTP_PASIVE_DATA_PORT & 0xFF));
- ftp_data.substate.data = E_FTP_STE_SUB_LISTEN_FOR_DATA;
+ ftp_data.substate = E_FTP_STE_SUB_LISTEN_FOR_DATA;
ftp_send_reply(227, (char *)ftp_data.dBuffer);
}
else {
@@ -727,13 +725,7 @@ static void ftp_process_cmd (void) {
}
break;
case E_FTP_CMD_LIST:
- if ((result = ftp_open_dir_for_listing(ftp_path, (char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, &listsize)) == E_FTP_RESULT_OK) {
- ftp_data.state = E_FTP_STE_END_TRANSFER;
- ftp_send_reply(150, NULL);
- ftp_send_data(listsize);
- ftp_send_reply(226, NULL);
- }
- else if (result == E_FTP_RESULT_CONTINUE) {
+ if (ftp_open_dir_for_listing(ftp_path) == E_FTP_RESULT_CONTINUE) {
ftp_data.state = E_FTP_STE_CONTINUE_LISTING;
ftp_send_reply(150, NULL);
}
@@ -903,7 +895,7 @@ static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno) {
(fno->ftime >> 11) & 0x1f,
(fno->ftime >> 5) & 0x3f,
2 * (fno->ftime & 0x1f));
- tseconds = pybrtc_get_seconds();
+ tseconds = pyb_rtc_get_seconds();
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - fseconds) {
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
@@ -931,7 +923,7 @@ static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
timeutils_seconds_since_2000_to_struct_time((FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101), &tm);
- tseconds = pybrtc_get_seconds();
+ tseconds = pyb_rtc_get_seconds();
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - (FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101)) {
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
type, 0, ftp_month[(tm.tm_mon - 1)].month, tm.tm_mday, tm.tm_year, name);
@@ -979,32 +971,25 @@ static ftp_result_t ftp_write_file (char *filebuf, uint32_t size) {
return result;
}
-static ftp_result_t ftp_open_dir_for_listing (const char *path, char *list, uint32_t maxlistsize, uint32_t *listsize) {
- uint next = 0;
- // "hack" to list root directory
+static ftp_result_t ftp_open_dir_for_listing (const char *path) {
+ // "hack" to detect the root directory
if (path[0] == '/' && path[1] == '\0') {
- next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
-#if MICROPY_HW_HAS_SDCARD
- if (pybsd_is_mounted()) {
- next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "sd");
+ ftp_data.listroot = true;
+ } else {
+ FRESULT res;
+ res = f_opendir(&ftp_data.dp, path); /* Open the directory */
+ if (res != FR_OK) {
+ return E_FTP_RESULT_FAILED;
}
-#endif
- *listsize = next;
- return E_FTP_RESULT_OK;
+ ftp_data.e_open = E_FTP_DIR_OPEN;
+ ftp_data.listroot = false;
}
-
- FRESULT res;
- res = f_opendir(&ftp_data.dp, path); /* Open the directory */
- if (res != FR_OK) {
- return E_FTP_RESULT_FAILED;
- }
- ftp_data.e_open = E_FTP_DIR_OPEN;
return E_FTP_RESULT_CONTINUE;
}
static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *listsize) {
uint next = 0;
- uint count = 0;
+ uint listcount = 0;
FRESULT res;
ftp_result_t result = E_FTP_RESULT_CONTINUE;
FILINFO fno;
@@ -1013,22 +998,40 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
fno.lfsize = _MAX_LFN;
// read up to 2 directory items
- while (count < 2) {
+ while (listcount < 2) {
#else
// read up to 4 directory items
- while (count < 4) {
+ while (listcount < 4) {
#endif
- res = f_readdir(&ftp_data.dp, &fno); /* Read a directory item */
- if (res != FR_OK || fno.fname[0] == 0) {
- result = E_FTP_RESULT_OK;
- break; /* Break on error or end of dp */
- }
- 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 (ftp_data.listroot) {
+ // root directory "hack"
+ if (0 == ftp_data.volcount) {
+ next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
+ } else if (ftp_data.volcount <= MP_STATE_PORT(mount_obj_list).len) {
+ os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[(ftp_data.volcount - 1)]));
+ next += ftp_print_eplf_drive((list + next), (maxlistsize - next), (char *)&mount_obj->path[1]);
+ } else {
+ if (!next) {
+ // no volume found this time, we are done
+ ftp_data.volcount = 0;
+ }
+ break;
+ }
+ ftp_data.volcount++;
+ } else {
+ // a "normal" directory
+ res = f_readdir(&ftp_data.dp, &fno); /* Read a directory item */
+ if (res != FR_OK || fno.fname[0] == 0) {
+ result = E_FTP_RESULT_OK;
+ break; /* Break on error or end of dp */
+ }
+ 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 */
- // add the entry to the list
- next += ftp_print_eplf_item((list + next), (maxlistsize - next), &fno);
- count++;
+ // add the entry to the list
+ next += ftp_print_eplf_item((list + next), (maxlistsize - next), &fno);
+ }
+ listcount++;
}
if (result == E_FTP_RESULT_OK) {
ftp_close_files();
@@ -1043,8 +1046,7 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
static void ftp_open_child (char *pwd, char *dir) {
if (dir[0] == '/') {
strcpy (pwd, dir);
- }
- else {
+ } else {
if (strlen(pwd) > 1) {
strcat (pwd, "/");
}
@@ -1064,8 +1066,7 @@ static void ftp_close_child (char *pwd) {
}
if (len == 0) {
strcpy (pwd, "/");
- }
- else {
+ } else {
pwd[len] = '\0';
}
}
@@ -1078,8 +1079,7 @@ static void ftp_return_to_previous_path (char *pwd, char *dir) {
else {
if (newlen == 0) {
strcpy (pwd, "/");
- }
- else {
+ } else {
pwd[newlen] = '\0';
}
}
diff --git a/cc3200/misc/mpsystick.c b/cc3200/misc/mpsystick.c
index 7e1cff6ff7..21c147449d 100644
--- a/cc3200/misc/mpsystick.c
+++ b/cc3200/misc/mpsystick.c
@@ -68,7 +68,7 @@ uint32_t sys_tick_get_microseconds(void) {
enable_irq(irq_state);
// It's still possible for the countflag bit to get set if the counter was
- // reloaded between reading VAL and reading CTRL. With interrupts disabled
+ // reloaded between reading VAL and reading CTRL. With interrupts disabled
// it definitely takes less than 50 HCLK cycles between reading VAL and
// reading CTRL, so the test (counter > 50) is to cover the case where VAL
// is +ve and very close to zero, and the COUNTFLAG bit is also set.
diff --git a/cc3200/mods/modpyb.c b/cc3200/mods/modpyb.c
index 3e71d658c3..c32ea6c90b 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 0d62a96e85..8dc7716b56 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 7e01148d71..99172b7061 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 70116c5b7b..e6271e3916 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 2282b876bd..1899565999 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 010cf88d4d..1c3e63710e 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 8692a2f585..5369aa97ef 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 14a610a673..cc2e26f3a3 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 55d695a9a0..06c4868db7 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 052a6b51e6..864db513bc 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 145c7dc411..a06df6d8d1 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 20ba04cb49..94387bcfbb 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 b1d74785b5..73cf661bcc 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 b1f9086cee..7619404d03 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;
diff --git a/cc3200/mpconfigport.h b/cc3200/mpconfigport.h
index f81bd1af52..aed07bdcae 100644
--- a/cc3200/mpconfigport.h
+++ b/cc3200/mpconfigport.h
@@ -162,6 +162,7 @@ extern const struct _mp_obj_module_t mp_module_ussl;
mp_obj_list_t pybsleep_obj_list; \
mp_obj_list_t mpcallback_obj_list; \
mp_obj_list_t pyb_timer_channel_obj_list; \
+ mp_obj_list_t mount_obj_list; \
struct _pyb_uart_obj_t *pyb_uart_objs[2]; \
diff --git a/cc3200/mptask.c b/cc3200/mptask.c
index dd3a762244..ec342e2d09 100644
--- a/cc3200/mptask.c
+++ b/cc3200/mptask.c
@@ -61,13 +61,13 @@
#include "mpexception.h"
#include "random.h"
#include "pybi2c.h"
-#include "pybsd.h"
#include "pins.h"
#include "pybsleep.h"
#include "pybtimer.h"
#include "mpcallback.h"
#include "cryptohash.h"
#include "updater.h"
+#include "moduos.h"
/******************************************************************************
DECLARE PRIVATE CONSTANTS
@@ -134,9 +134,8 @@ soft_reset:
timer_init0();
readline_init0();
mod_network_init0();
-#if MICROPY_HW_ENABLE_RNG
+ moduos_init0();
rng_init0();
-#endif
#ifdef LAUNCHXL
// instantiate the stdio uart on the default pins
@@ -243,10 +242,6 @@ soft_reset_exit:
// clean-up the user socket space
modusocket_close_all_user_sockets();
-#if MICROPY_HW_HAS_SDCARD
- pybsd_disable();
-#endif
-
// wait for pending transactions to complete
HAL_Delay(20);
@@ -258,9 +253,8 @@ soft_reset_exit:
******************************************************************************/
__attribute__ ((section (".boot")))
STATIC void mptask_pre_init (void) {
-#if MICROPY_HW_ENABLE_RTC
- pybrtc_pre_init();
-#endif
+ // this one only makes sense after a poweron reset
+ pyb_rtc_pre_init();
// Create the simple link spawn task
ASSERT (OSI_OK == VStartSimpleLinkSpawnTask(SIMPLELINK_SPAWN_TASK_PRIORITY));
@@ -280,11 +274,6 @@ STATIC void mptask_pre_init (void) {
// this one allocates memory for the socket semaphore
modusocket_pre_init();
-#if MICROPY_HW_HAS_SDCARD
- // this one allocates memory for the SD file system
- pybsd_pre_init();
-#endif
-
CRYPTOHASH_Init();
#ifdef DEBUG
diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h
index c5fc53032b..9ccdf829fd 100644
--- a/cc3200/qstrdefsport.h
+++ b/cc3200/qstrdefsport.h
@@ -35,40 +35,18 @@ Q(main)
Q(sync)
Q(gc)
Q(rng)
-Q(delay)
-Q(time)
-Q(open)
-Q(on)
-Q(off)
Q(toggle)
Q(write)
-Q(read)
-Q(readall)
-Q(readline)
Q(input)
-Q(os)
Q(freq)
Q(unique_id)
-Q(repl_info)
Q(disable_irq)
Q(enable_irq)
-Q(millis)
-Q(micros)
-Q(elapsed_millis)
-Q(elapsed_micros)
-Q(udelay)
Q(flush)
-Q(FileIO)
-Q(enable)
-Q(disable)
Q(repl_uart)
-// Entries for sys.path
+// entries for sys.path
Q(/flash)
Q(/flash/lib)
-#if MICROPY_HW_HAS_SDCARD
-Q(/sd)
-Q(/sd/lib)
-#endif
// for module weak links
Q(struct)
@@ -79,8 +57,8 @@ Q(heapq)
Q(hashlib)
// for os module
-Q(uos)
Q(os)
+Q(uos)
Q(sysname)
Q(nodename)
Q(release)
@@ -89,9 +67,6 @@ Q(machine)
Q(uname)
Q(/)
Q(flash)
-#if MICROPY_HW_HAS_SDCARD
-Q(sd)
-#endif
Q(chdir)
Q(getcwd)
Q(listdir)
@@ -104,6 +79,13 @@ Q(sep)
Q(stat)
Q(urandom)
Q(mkfs)
+Q(mount)
+Q(unmount)
+Q(readonly)
+Q(readblocks)
+Q(writeblocks)
+Q(sync)
+Q(count)
// for file class
Q(seek)
@@ -185,25 +167,35 @@ Q(channel)
Q(id)
Q(pin)
-#if MICROPY_HW_HAS_SDCARD
// for SD class
Q(SD)
Q(init)
Q(deinit)
-Q(mount)
-Q(unmount)
-#endif
+Q(id)
+Q(pins)
// for RTC class
Q(RTC)
+Q(init)
+Q(alarm)
+Q(alarm_left)
+Q(now)
+Q(deinit)
Q(datetime)
+Q(repeat)
// for time class
+Q(time)
Q(utime)
Q(localtime)
Q(mktime)
Q(sleep)
-Q(time)
+Q(sleep_ms)
+Q(sleep_us)
+Q(ticks_ms)
+Q(ticks_us)
+Q(ticks_cpu)
+Q(ticks_diff)
// for select class
Q(select)
diff --git a/cc3200/tools/smoke.py b/cc3200/tools/smoke.py
index 8b0fb5fc8e..45187b6976 100644
--- a/cc3200/tools/smoke.py
+++ b/cc3200/tools/smoke.py
@@ -63,12 +63,12 @@ print(ls)
# test the real time clock
rtc = pyb.RTC()
-while rtc.datetime()[7] > 800:
+while rtc.now()[6] > 800:
pass
-time1 = rtc.datetime()
+time1 = rtc.now()
pyb.delay(1000)
-time2 = rtc.datetime()
-print(time2[6] - time1[6] == 1)
-print(time2[7] - time1[7] < 50)
+time2 = rtc.now()
+print(time2[5] - time1[5] == 1)
+print(time2[6] - time1[6] < 5000) # microseconds
diff --git a/cc3200/util/random.c b/cc3200/util/random.c
index e9a6abcea2..470d95d3a8 100644
--- a/cc3200/util/random.c
+++ b/cc3200/util/random.c
@@ -43,11 +43,11 @@
/******************************************************************************
* LOCAL TYPES
******************************************************************************/
-typedef union Id_t {
+typedef union _rng_id_t {
uint32_t id32;
uint16_t id16[3];
uint8_t id8[6];
-} Id_t;
+} rng_id_t;
/******************************************************************************
* LOCAL VARIABLES
@@ -64,29 +64,19 @@ static uint32_t lfsr (uint32_t input);
******************************************************************************/
static uint32_t lfsr (uint32_t input) {
assert( input != 0 );
-
- /*lint -save -e501*/
return (input >> 1) ^ (-(input & 0x01) & 0x00E10000);
- /*lint -restore*/
}
-#if MICROPY_HW_ENABLE_RNG
-/// \moduleref rng
-
-/// \function rng()
-/// Return a 24-bit hardware generated random number.
STATIC mp_obj_t pyb_rng_get(void) {
return mp_obj_new_int(rng_get());
}
-
MP_DEFINE_CONST_FUN_OBJ_0(pyb_rng_get_obj, pyb_rng_get);
-#endif
/******************************************************************************
* PUBLIC FUNCTIONS
******************************************************************************/
void rng_init0 (void) {
- Id_t juggler;
+ rng_id_t juggler;
uint32_t seconds;
uint16_t mseconds;
@@ -95,7 +85,7 @@ void rng_init0 (void) {
wlan_get_mac (juggler.id8);
- // Flatten the 48-bit board identification to 24 bits
+ // flatten the 48-bit board identification to 24 bits
juggler.id16[0] ^= juggler.id16[2];
juggler.id8[0] ^= juggler.id8[3];
@@ -104,7 +94,8 @@ void rng_init0 (void) {
s_seed = juggler.id32 & 0x00FFFFFF;
s_seed += (seconds & 0x000FFFFF) + mseconds;
- // The seed must not be zero
+
+ // the seed must not be zero
if (s_seed == 0) {
s_seed = 1;
}
diff --git a/cc3200/util/random.h b/cc3200/util/random.h
index 78ca578936..eae15f2d25 100644
--- a/cc3200/util/random.h
+++ b/cc3200/util/random.h
@@ -30,8 +30,6 @@
void rng_init0 (void);
uint32_t rng_get (void);
-#if MICROPY_HW_ENABLE_RNG
- MP_DECLARE_CONST_FUN_OBJ(pyb_rng_get_obj);
-#endif
+MP_DECLARE_CONST_FUN_OBJ(pyb_rng_get_obj);
#endif // __RANDOM_H
diff --git a/docs/wipy/quickref.rst b/docs/wipy/quickref.rst
index 8376e5b404..eb8a12e8be 100644
--- a/docs/wipy/quickref.rst
+++ b/docs/wipy/quickref.rst
@@ -158,11 +158,12 @@ SD card
See :ref:`pyb.SD <pyb.SD>`. ::
from pyb import SD
+ import os
# SD card pins need special configuration so we pass them to the constructor
- # data pin, data af, clock pin, clock af, cmd pin, cmd af
- sd = pyb.SD(('GP15', 8, 'GP10', 6, 'GP11', 6))
- sd.mount()
+ # clock pin, cmd pin, data0 pin
+ sd = SD(pins=('GP10', 'GP11', 'GP15'))
+ os.mount(sd, '/sd')
WLAN (WiFi)
-----------
diff --git a/tests/wipy/i2c.py b/tests/wipy/i2c.py
index 24afc5a082..b5f2a610d7 100644
--- a/tests/wipy/i2c.py
+++ b/tests/wipy/i2c.py
@@ -5,7 +5,7 @@ A MPU-9150 sensor must be connected to the I2C bus.
from pyb import I2C
import os
-import pyb
+import time
machine = os.uname().machine
if 'LaunchPad' in machine:
@@ -39,7 +39,7 @@ reg2_r = bytearray(2)
# reset the sensor
reg[0] |= 0x80
print(1 == i2c.writeto_mem(addr, 107, reg))
-pyb.delay(100) # wait for the sensor to reset...
+time.sleep_ms(100) # wait for the sensor to reset...
print(1 == i2c.readfrom_mem_into(addr, 107, reg)) # read the power management register 1
print(0x40 == reg[0])
@@ -79,7 +79,7 @@ print(0x40 == reg[0])
# reset the sensor
reg[0] |= 0x80
print(1 == i2c.writeto_mem(addr, 107, reg))
-pyb.delay(100) # wait for the sensor to reset...
+time.sleep_ms(100) # wait for the sensor to reset...
# now read and write two register at a time
print(2 == i2c.readfrom_mem_into(addr, 107, reg2))
@@ -97,7 +97,7 @@ print(reg2 == reg2_r)
# reset the sensor
reg[0] = 0x80
print(1 == i2c.writeto_mem(addr, 107, reg))
-pyb.delay(100) # wait for the sensor to reset...
+time.sleep_ms(100) # wait for the sensor to reset...
# try some raw read and writes
reg[0] = 117 # register address
diff --git a/tests/wipy/os.py b/tests/wipy/os.py
new file mode 100644
index 0000000000..796d4699ef
--- /dev/null
+++ b/tests/wipy/os.py
@@ -0,0 +1,155 @@
+'''
+os module test for the CC3200 based boards
+'''
+
+from pyb import SD
+import pyb
+import os
+
+machine = os.uname().machine
+if 'LaunchPad' in machine:
+ sd_pins = ('GP16', 'GP17', 'GP15')
+elif 'WiPy' in machine:
+ sd_pins = ('GP10', 'GP11', 'GP15')
+else:
+ raise Exception('Board not supported!')
+
+sd = SD(pins=sd_pins)
+
+os.mount(sd, '/sd')
+os.mkfs('/sd')
+os.chdir('/flash')
+print(os.listdir())
+
+os.chdir('/sd')
+print(os.listdir())
+
+# create a test directory in flash
+os.mkdir('/flash/test')
+os.chdir('/flash/test')
+print(os.getcwd())
+os.chdir('..')
+print(os.getcwd())
+os.chdir('test')
+print(os.getcwd())
+# create a new file
+f = open('test.txt', 'w')
+test_bytes = os.urandom(1024)
+n_w = f.write(test_bytes)
+print(n_w == len(test_bytes))
+f.close()
+f = open('test.txt', 'r')
+r = bytes(f.readall(), 'ascii')
+# check that we can write and read it correctly
+print(r == test_bytes)
+f.close()
+os.rename('test.txt', 'newtest.txt')
+print(os.listdir())
+os.rename('/flash/test', '/flash/newtest')
+print(os.listdir('/flash'))
+os.remove('newtest.txt')
+os.chdir('..')
+os.rmdir('newtest')
+
+# create a test directory in the sd card
+os.mkdir('/sd/test')
+os.chdir('/sd/test')
+print(os.getcwd())
+os.chdir('..')
+print(os.getcwd())
+os.chdir('test')
+print(os.getcwd())
+# create a new file
+f = open('test.txt', 'w')
+test_bytes = os.urandom(1024)
+n_w = f.write(test_bytes)
+print(n_w == len(test_bytes))
+f.close()
+f = open('test.txt', 'r')
+r = bytes(f.readall(), 'ascii')
+# check that we can write and read it correctly
+print(r == test_bytes)
+f.close()
+
+print('CC3200' in os.uname().machine)
+print('WiPy' == os.uname().sysname)
+
+os.sync()
+os.stat('/flash')
+os.stat('/flash/sys')
+os.stat('/flash/boot.py')
+os.stat('/sd')
+os.stat('/')
+os.chdir('/sd/test')
+os.remove('test.txt')
+os.chdir('/sd')
+os.rmdir('test')
+os.listdir('/sd')
+print(os.listdir('/'))
+os.unmount('/sd')
+print(os.listdir('/'))
+os.mkfs(sd)
+os.mount(sd, '/sd')
+print(os.listdir('/'))
+os.chdir('/flash')
+
+# next ones must raise
+sd.deinit()
+try:
+ os.listdir('/sd')
+except:
+ print('Exception')
+
+#re-initialization must work
+sd.init()
+print(os.listdir('/sd'))
+
+try:
+ os.mount(sd, '/sd')
+except:
+ print('Exception')
+
+try:
+ os.mount(sd, '/sd2')
+except:
+ print('Exception')
+
+os.unmount('/sd')
+try:
+ os.listdir('/sd')
+except:
+ print('Exception')
+
+try:
+ os.unmount('/flash')
+except:
+ print('Exception')
+
+try:
+ os.mkfs('flash') # incorrect path format
+except:
+ print('Exception')
+
+try:
+ os.remove('/flash/nofile.txt')
+except:
+ print('Exception')
+
+try:
+ os.rename('/flash/nofile.txt', '/flash/nofile2.txt')
+except:
+ print('Exception')
+
+try:
+ os.chdir('/flash/nodir')
+except:
+ print('Exception')
+
+try:
+ os.listdir('/flash/nodir')
+except:
+ print('Exception')
+
+os.mount(sd, '/sd')
+print(os.listdir('/'))
+os.unmount('/sd')
diff --git a/tests/wipy/os.py.exp b/tests/wipy/os.py.exp
new file mode 100644
index 0000000000..55a0879aad
--- /dev/null
+++ b/tests/wipy/os.py.exp
@@ -0,0 +1,30 @@
+['main.py', 'sys', 'lib', 'cert', 'boot.py']
+[]
+/flash/test
+/flash
+/flash/test
+True
+True
+['newtest.txt']
+['main.py', 'sys', 'lib', 'cert', 'boot.py', 'newtest']
+/sd/test
+/sd
+/sd/test
+True
+True
+True
+True
+['flash', 'sd']
+['flash']
+['flash', 'sd']
+[]
+Exception
+Exception
+Exception
+Exception
+Exception
+Exception
+Exception
+Exception
+Exception
+['flash', 'sd']
diff --git a/tests/wipy/rtc.py b/tests/wipy/rtc.py
new file mode 100644
index 0000000000..4114796db1
--- /dev/null
+++ b/tests/wipy/rtc.py
@@ -0,0 +1,100 @@
+'''
+RTC test for the CC3200 based boards.
+'''
+
+from pyb import RTC
+import os
+import time
+
+machine = os.uname().machine
+if not 'LaunchPad' in machine and not 'WiPy' in machine:
+ raise Exception('Board not supported!')
+
+rtc = RTC()
+print(rtc)
+print(rtc.now()[:6])
+
+rtc = RTC(datetime=(2015, 8, 29, 9, 0, 0, 0, None))
+print(rtc.now()[:6])
+
+rtc.deinit()
+print(rtc.now()[:6])
+
+rtc.init((2015, 8, 29, 9, 0, 0, 0, None))
+print(rtc.now()[:6])
+seconds = rtc.now()[5]
+time.sleep_ms(1000)
+print(rtc.now()[5] - seconds == 1)
+seconds = rtc.now()[5]
+time.sleep_ms(2000)
+print(rtc.now()[5] - seconds == 2)
+
+# initialization with shorter tuples
+rtc.init((2015, 9, 19, 8, 0, 0, 0))
+print(rtc.now()[5])
+rtc.init((2015, 9, 19, 8, 0, 0))
+print(rtc.now()[5])
+rtc.init((2015, 9, 19, 8, 0))
+print(rtc.now()[5])
+rtc.init((2015, 9, 19, 8))
+print(rtc.now()[4])
+rtc.init((2015, 9, 19))
+print(rtc.now()[3])
+
+def set_and_print(datetime):
+ rtc.init(datetime)
+ print(rtc.now()[:6])
+
+# make sure that setting works correctly
+set_and_print((2000, 1, 1, 0, 0, 0, 0, None))
+set_and_print((2000, 1, 31, 0, 0, 0, 0, None))
+set_and_print((2000, 12, 31, 0, 0, 0, 0, None))
+set_and_print((2016, 12, 31, 0, 0, 0, 0, None))
+set_and_print((2016, 12, 31, 0, 0, 0, 0, None))
+set_and_print((2016, 12, 31, 1, 0, 0, 0, None))
+set_and_print((2016, 12, 31, 12, 0, 0, 0, None))
+set_and_print((2016, 12, 31, 13, 0, 0, 0, None))
+set_and_print((2016, 12, 31, 23, 0, 0, 0, None))
+set_and_print((2016, 12, 31, 23, 1, 0, 0, None))
+set_and_print((2016, 12, 31, 23, 59, 0, 50, None))
+set_and_print((2016, 12, 31, 23, 59, 1, 900, None))
+set_and_print((2016, 12, 31, 23, 59, 59, 100, None))
+set_and_print((2048, 12, 31, 23, 59, 59, 99999, None))
+
+rtc.init((2015, 8, 29, 9, 0, 0, 0, None))
+rtc.alarm(0, 5000)
+rtc.alarm(time=2000)
+time.sleep_ms(1000)
+left = rtc.alarm_left()
+print(abs(left-1000) < 20)
+time.sleep_ms(1000)
+print(rtc.alarm_left() == 0)
+time.sleep_ms(100)
+print(rtc.alarm_left() == 0)
+
+rtc.init((2015, 8, 29, 9, 0, 0, 0, None))
+rtc.alarm(time=(2015, 8, 29, 9, 0, 45))
+time.sleep_ms(1000)
+left = rtc.alarm_left()
+print(abs(left-44000) < 100)
+
+# next ones must raise
+try:
+ rtc.alarm(5000)
+except:
+ print('Exception')
+
+try:
+ rtc.alarm(5000)
+except:
+ print('Exception')
+
+try:
+ rtc = RTC(200000000)
+except:
+ print('Exception')
+
+try:
+ rtc = RTC((2015, 8, 29, 9, 0, 0, 0, None))
+except:
+ print('Exception')
diff --git a/tests/wipy/rtc.py.exp b/tests/wipy/rtc.py.exp
new file mode 100644
index 0000000000..8225f4602f
--- /dev/null
+++ b/tests/wipy/rtc.py.exp
@@ -0,0 +1,34 @@
+<RTC>
+(2015, 1, 1, 0, 0, 0)
+(2015, 8, 29, 9, 0, 0)
+(2015, 1, 1, 0, 0, 0)
+(2015, 8, 29, 9, 0, 0)
+True
+True
+0
+0
+0
+0
+0
+(2000, 1, 1, 0, 0, 0)
+(2000, 1, 31, 0, 0, 0)
+(2000, 12, 31, 0, 0, 0)
+(2016, 12, 31, 0, 0, 0)
+(2016, 12, 31, 0, 0, 0)
+(2016, 12, 31, 1, 0, 0)
+(2016, 12, 31, 12, 0, 0)
+(2016, 12, 31, 13, 0, 0)
+(2016, 12, 31, 23, 0, 0)
+(2016, 12, 31, 23, 1, 0)
+(2016, 12, 31, 23, 59, 0)
+(2016, 12, 31, 23, 59, 1)
+(2016, 12, 31, 23, 59, 59)
+(2048, 12, 31, 23, 59, 59)
+True
+True
+True
+True
+Exception
+Exception
+Exception
+Exception
diff --git a/tests/wipy/sd.py b/tests/wipy/sd.py
new file mode 100644
index 0000000000..2b66af78bb
--- /dev/null
+++ b/tests/wipy/sd.py
@@ -0,0 +1,46 @@
+'''
+SD card test for the CC3200 based boards.
+'''
+
+from pyb import SD
+import os
+
+machine = os.uname().machine
+if 'LaunchPad' in machine:
+ sd_pins = ('GP16', 'GP17', 'GP15')
+elif 'WiPy' in machine:
+ sd_pins = ('GP10', 'GP11', 'GP15')
+else:
+ raise Exception('Board not supported!')
+
+sd = SD(pins=sd_pins)
+print(sd)
+sd.deinit()
+print(sd)
+sd.init(sd_pins)
+print(sd)
+
+sd = SD(0, pins=sd_pins)
+sd = SD(id=0, pins=sd_pins)
+sd = SD(0, sd_pins)
+
+# check for memory leaks
+for i in range(0, 1000):
+ sd = sd = SD(0, pins=sd_pins)
+
+# next ones should raise
+try:
+ sd = SD(pins=())
+except Exception:
+ print("Exception")
+
+try:
+ sd = SD(pins=('GP10', 'GP11', 'GP8'))
+except Exception:
+ print("Exception")
+
+try:
+ sd = SD(pins=('GP10', 'GP11'))
+except Exception:
+ print("Exception")
+
diff --git a/tests/wipy/sd.py.exp b/tests/wipy/sd.py.exp
new file mode 100644
index 0000000000..eaa5f08efb
--- /dev/null
+++ b/tests/wipy/sd.py.exp
@@ -0,0 +1,6 @@
+<SD>
+<SD>
+<SD>
+Exception
+Exception
+Exception
diff --git a/tests/wipy/time.py b/tests/wipy/time.py
new file mode 100644
index 0000000000..d6b4f245d6
--- /dev/null
+++ b/tests/wipy/time.py
@@ -0,0 +1,78 @@
+import time
+
+DAYS_PER_MONTH = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+
+def is_leap(year):
+ return (year % 4) == 0
+
+def test():
+ seconds = 0
+ wday = 5 # Jan 1, 2000 was a Saturday
+ for year in range(2000, 2049):
+ print("Testing %d" % year)
+ yday = 1
+ for month in range(1, 13):
+ if month == 2 and is_leap(year):
+ DAYS_PER_MONTH[2] = 29
+ else:
+ DAYS_PER_MONTH[2] = 28
+ for day in range(1, DAYS_PER_MONTH[month] + 1):
+ secs = time.mktime((year, month, day, 0, 0, 0, 0, 0))
+ if secs != seconds:
+ print("mktime failed for %d-%02d-%02d got %d expected %d" % (year, month, day, secs, seconds))
+ tuple = time.localtime(seconds)
+ secs = time.mktime(tuple)
+ if secs != seconds:
+ print("localtime failed for %d-%02d-%02d got %d expected %d" % (year, month, day, secs, seconds))
+ return
+ seconds += 86400
+ if yday != tuple[7]:
+ print("locatime for %d-%02d-%02d got yday %d, expecting %d" % (year, month, day, tuple[7], yday))
+ return
+ if wday != tuple[6]:
+ print("locatime for %d-%02d-%02d got wday %d, expecting %d" % (year, month, day, tuple[6], wday))
+ return
+ yday += 1
+ wday = (wday + 1) % 7
+
+def spot_test(seconds, expected_time):
+ actual_time = time.localtime(seconds)
+ for i in range(len(actual_time)):
+ if actual_time[i] != expected_time[i]:
+ print("time.localtime(", seconds, ") returned", actual_time, "expecting", expected_time)
+ return
+ print("time.localtime(", seconds, ") returned", actual_time, "(pass)")
+
+
+test()
+spot_test( 0, (2000, 1, 1, 0, 0, 0, 5, 1))
+spot_test( 1, (2000, 1, 1, 0, 0, 1, 5, 1))
+spot_test( 59, (2000, 1, 1, 0, 0, 59, 5, 1))
+spot_test( 60, (2000, 1, 1, 0, 1, 0, 5, 1))
+spot_test( 3599, (2000, 1, 1, 0, 59, 59, 5, 1))
+spot_test( 3600, (2000, 1, 1, 1, 0, 0, 5, 1))
+spot_test( -1, (1999, 12, 31, 23, 59, 59, 4, 365))
+spot_test( 447549467, (2014, 3, 7, 23, 17, 47, 4, 66))
+spot_test( -940984933, (1970, 3, 7, 23, 17, 47, 5, 66))
+spot_test(-1072915199, (1966, 1, 1, 0, 0, 1, 5, 1))
+spot_test(-1072915200, (1966, 1, 1, 0, 0, 0, 5, 1))
+spot_test(-1072915201, (1965, 12, 31, 23, 59, 59, 4, 365))
+
+t1 = time.time()
+time.sleep(2)
+t2 = time.time()
+print(time.ticks_diff(t1, t2) == 2)
+
+t1 = time.ticks_ms()
+time.sleep_ms(50)
+t2 = time.ticks_ms()
+print(time.ticks_diff(t1, t2) == 50)
+
+t1 = time.ticks_us()
+time.sleep_us(1000)
+t2 = time.ticks_us()
+print(time.ticks_diff(t1, t2) < 2000)
+
+t1 = time.ticks_cpu()
+t2 = time.ticks_cpu()
+print(time.ticks_diff(t1, t2) < 16384)
diff --git a/tests/wipy/time.py.exp b/tests/wipy/time.py.exp
new file mode 100644
index 0000000000..24d798f929
--- /dev/null
+++ b/tests/wipy/time.py.exp
@@ -0,0 +1,65 @@
+Testing 2000
+Testing 2001
+Testing 2002
+Testing 2003
+Testing 2004
+Testing 2005
+Testing 2006
+Testing 2007
+Testing 2008
+Testing 2009
+Testing 2010
+Testing 2011
+Testing 2012
+Testing 2013
+Testing 2014
+Testing 2015
+Testing 2016
+Testing 2017
+Testing 2018
+Testing 2019
+Testing 2020
+Testing 2021
+Testing 2022
+Testing 2023
+Testing 2024
+Testing 2025
+Testing 2026
+Testing 2027
+Testing 2028
+Testing 2029
+Testing 2030
+Testing 2031
+Testing 2032
+Testing 2033
+Testing 2034
+Testing 2035
+Testing 2036
+Testing 2037
+Testing 2038
+Testing 2039
+Testing 2040
+Testing 2041
+Testing 2042
+Testing 2043
+Testing 2044
+Testing 2045
+Testing 2046
+Testing 2047
+Testing 2048
+time.localtime( 0 ) returned (2000, 1, 1, 0, 0, 0, 5, 1) (pass)
+time.localtime( 1 ) returned (2000, 1, 1, 0, 0, 1, 5, 1) (pass)
+time.localtime( 59 ) returned (2000, 1, 1, 0, 0, 59, 5, 1) (pass)
+time.localtime( 60 ) returned (2000, 1, 1, 0, 1, 0, 5, 1) (pass)
+time.localtime( 3599 ) returned (2000, 1, 1, 0, 59, 59, 5, 1) (pass)
+time.localtime( 3600 ) returned (2000, 1, 1, 1, 0, 0, 5, 1) (pass)
+time.localtime( -1 ) returned (1999, 12, 31, 23, 59, 59, 4, 365) (pass)
+time.localtime( 447549467 ) returned (2014, 3, 7, 23, 17, 47, 4, 66) (pass)
+time.localtime( -940984933 ) returned (1970, 3, 7, 23, 17, 47, 5, 66) (pass)
+time.localtime( -1072915199 ) returned (1966, 1, 1, 0, 0, 1, 5, 1) (pass)
+time.localtime( -1072915200 ) returned (1966, 1, 1, 0, 0, 0, 5, 1) (pass)
+time.localtime( -1072915201 ) returned (1965, 12, 31, 23, 59, 59, 4, 365) (pass)
+True
+True
+True
+True
diff --git a/tests/wipy/uart.py b/tests/wipy/uart.py
index aa2f18b985..d700c29d08 100644
--- a/tests/wipy/uart.py
+++ b/tests/wipy/uart.py
@@ -7,6 +7,7 @@ from pyb import UART
from pyb import Pin
import os
import pyb
+import time
machine = os.uname().machine
if 'LaunchPad' in machine:
@@ -66,7 +67,7 @@ print(buf)
# try initializing without the id
uart0 = UART(baudrate=1000000, pins=uart_pins[0][0])
uart0.write(b'1234567890')
-pyb.delay(2) # because of the fifo interrupt levels
+time.sleep_ms(2) # because of the fifo interrupt levels
print(uart1.any() == 10)
print(uart1.readline() == b'1234567890')
print(uart1.any() == 0)
diff --git a/tests/wipy/wdt.py b/tests/wipy/wdt.py
index 9be6293b08..8e07fd8314 100644
--- a/tests/wipy/wdt.py
+++ b/tests/wipy/wdt.py
@@ -3,6 +3,7 @@ WDT test for the CC3200 based boards
'''
from pyb import WDT
+import time
# test the invalid cases first
try:
@@ -28,10 +29,10 @@ try:
except Exception:
print("Exception")
-pyb.delay(500)
+time.sleep_ms(500)
wdt.feed()
print(wdt)
-pyb.delay(900)
+time.sleep_ms(900)
wdt.feed()
print(wdt)
-pyb.delay(950)
+time.sleep_ms(950)